Mercurial > hg > truffle
comparison src/share/vm/opto/parseHelper.cpp @ 1645:3941674cc7fa
6958668: repeated uncommon trapping for new of klass which is being initialized
Reviewed-by: kvn, jrose
author | never |
---|---|
date | Mon, 12 Jul 2010 10:58:25 -0700 |
parents | c18cbe5936b8 |
children | 4b29a725c43c |
comparison
equal
deleted
inserted
replaced
1644:2a47bd84841f | 1645:3941674cc7fa |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
195 // Result is ignored, we just need the CFG effects. | 195 // Result is ignored, we just need the CFG effects. |
196 gen_checkcast( obj, a_e_klass ); | 196 gen_checkcast( obj, a_e_klass ); |
197 } | 197 } |
198 | 198 |
199 | 199 |
200 void Parse::emit_guard_for_new(ciInstanceKlass* klass) { | |
201 // Emit guarded new | |
202 // if (klass->_init_thread != current_thread || | |
203 // klass->_init_state != being_initialized) | |
204 // uncommon_trap | |
205 Node* cur_thread = _gvn.transform( new (C, 1) ThreadLocalNode() ); | |
206 Node* merge = new (C, 3) RegionNode(3); | |
207 _gvn.set_type(merge, Type::CONTROL); | |
208 Node* kls = makecon(TypeKlassPtr::make(klass)); | |
209 | |
210 Node* init_thread_offset = _gvn.MakeConX(instanceKlass::init_thread_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()); | |
211 Node* adr_node = basic_plus_adr(kls, kls, init_thread_offset); | |
212 Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS); | |
213 Node *tst = Bool( CmpP( init_thread, cur_thread), BoolTest::eq); | |
214 IfNode* iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN); | |
215 set_control(IfTrue(iff)); | |
216 merge->set_req(1, IfFalse(iff)); | |
217 | |
218 Node* init_state_offset = _gvn.MakeConX(instanceKlass::init_state_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()); | |
219 adr_node = basic_plus_adr(kls, kls, init_state_offset); | |
220 Node* init_state = make_load(NULL, adr_node, TypeInt::INT, T_INT); | |
221 Node* being_init = _gvn.intcon(instanceKlass::being_initialized); | |
222 tst = Bool( CmpI( init_state, being_init), BoolTest::eq); | |
223 iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN); | |
224 set_control(IfTrue(iff)); | |
225 merge->set_req(2, IfFalse(iff)); | |
226 | |
227 PreserveJVMState pjvms(this); | |
228 record_for_igvn(merge); | |
229 set_control(merge); | |
230 | |
231 uncommon_trap(Deoptimization::Reason_uninitialized, | |
232 Deoptimization::Action_reinterpret, | |
233 klass); | |
234 } | |
235 | |
236 | |
200 //------------------------------do_new----------------------------------------- | 237 //------------------------------do_new----------------------------------------- |
201 void Parse::do_new() { | 238 void Parse::do_new() { |
202 kill_dead_locals(); | 239 kill_dead_locals(); |
203 | 240 |
204 bool will_link; | 241 bool will_link; |
205 ciInstanceKlass* klass = iter().get_klass(will_link)->as_instance_klass(); | 242 ciInstanceKlass* klass = iter().get_klass(will_link)->as_instance_klass(); |
206 assert(will_link, "_new: typeflow responsibility"); | 243 assert(will_link, "_new: typeflow responsibility"); |
207 | 244 |
208 // Should initialize, or throw an InstantiationError? | 245 // Should initialize, or throw an InstantiationError? |
209 if (!klass->is_initialized() || | 246 if (!klass->is_initialized() && !klass->is_being_initialized() || |
210 klass->is_abstract() || klass->is_interface() || | 247 klass->is_abstract() || klass->is_interface() || |
211 klass->name() == ciSymbol::java_lang_Class() || | 248 klass->name() == ciSymbol::java_lang_Class() || |
212 iter().is_unresolved_klass()) { | 249 iter().is_unresolved_klass()) { |
213 uncommon_trap(Deoptimization::Reason_uninitialized, | 250 uncommon_trap(Deoptimization::Reason_uninitialized, |
214 Deoptimization::Action_reinterpret, | 251 Deoptimization::Action_reinterpret, |
215 klass); | 252 klass); |
216 return; | 253 return; |
254 } | |
255 if (klass->is_being_initialized()) { | |
256 emit_guard_for_new(klass); | |
217 } | 257 } |
218 | 258 |
219 Node* kls = makecon(TypeKlassPtr::make(klass)); | 259 Node* kls = makecon(TypeKlassPtr::make(klass)); |
220 Node* obj = new_instance(kls); | 260 Node* obj = new_instance(kls); |
221 | 261 |