1.1 --- a/src/share/vm/opto/parseHelper.cpp Thu Jul 08 14:29:44 2010 -0700 1.2 +++ b/src/share/vm/opto/parseHelper.cpp Mon Jul 12 10:58:25 2010 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -197,6 +197,43 @@ 1.11 } 1.12 1.13 1.14 +void Parse::emit_guard_for_new(ciInstanceKlass* klass) { 1.15 + // Emit guarded new 1.16 + // if (klass->_init_thread != current_thread || 1.17 + // klass->_init_state != being_initialized) 1.18 + // uncommon_trap 1.19 + Node* cur_thread = _gvn.transform( new (C, 1) ThreadLocalNode() ); 1.20 + Node* merge = new (C, 3) RegionNode(3); 1.21 + _gvn.set_type(merge, Type::CONTROL); 1.22 + Node* kls = makecon(TypeKlassPtr::make(klass)); 1.23 + 1.24 + Node* init_thread_offset = _gvn.MakeConX(instanceKlass::init_thread_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()); 1.25 + Node* adr_node = basic_plus_adr(kls, kls, init_thread_offset); 1.26 + Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS); 1.27 + Node *tst = Bool( CmpP( init_thread, cur_thread), BoolTest::eq); 1.28 + IfNode* iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN); 1.29 + set_control(IfTrue(iff)); 1.30 + merge->set_req(1, IfFalse(iff)); 1.31 + 1.32 + Node* init_state_offset = _gvn.MakeConX(instanceKlass::init_state_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()); 1.33 + adr_node = basic_plus_adr(kls, kls, init_state_offset); 1.34 + Node* init_state = make_load(NULL, adr_node, TypeInt::INT, T_INT); 1.35 + Node* being_init = _gvn.intcon(instanceKlass::being_initialized); 1.36 + tst = Bool( CmpI( init_state, being_init), BoolTest::eq); 1.37 + iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN); 1.38 + set_control(IfTrue(iff)); 1.39 + merge->set_req(2, IfFalse(iff)); 1.40 + 1.41 + PreserveJVMState pjvms(this); 1.42 + record_for_igvn(merge); 1.43 + set_control(merge); 1.44 + 1.45 + uncommon_trap(Deoptimization::Reason_uninitialized, 1.46 + Deoptimization::Action_reinterpret, 1.47 + klass); 1.48 +} 1.49 + 1.50 + 1.51 //------------------------------do_new----------------------------------------- 1.52 void Parse::do_new() { 1.53 kill_dead_locals(); 1.54 @@ -206,7 +243,7 @@ 1.55 assert(will_link, "_new: typeflow responsibility"); 1.56 1.57 // Should initialize, or throw an InstantiationError? 1.58 - if (!klass->is_initialized() || 1.59 + if (!klass->is_initialized() && !klass->is_being_initialized() || 1.60 klass->is_abstract() || klass->is_interface() || 1.61 klass->name() == ciSymbol::java_lang_Class() || 1.62 iter().is_unresolved_klass()) { 1.63 @@ -215,6 +252,9 @@ 1.64 klass); 1.65 return; 1.66 } 1.67 + if (klass->is_being_initialized()) { 1.68 + emit_guard_for_new(klass); 1.69 + } 1.70 1.71 Node* kls = makecon(TypeKlassPtr::make(klass)); 1.72 Node* obj = new_instance(kls);