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