hotspot/src/share/vm/opto/parseHelper.cpp
changeset 5925 a30fef61d0b7
parent 5547 f4b087cbb361
child 6416 d49b65c9425a
equal deleted inserted replaced
5924:dc9d04930c82 5925:a30fef61d0b7
     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