< prev index next >

src/hotspot/share/opto/parse1.cpp

Print this page

        

@@ -582,10 +582,15 @@
       decrement_age();
     }
   }
 
   if (depth() == 1 && !failing()) {
+    if (C->clinit_barrier_on_entry()) {
+      // Add check to deoptimize the nmethod once the holder class is fully initialized
+      clinit_deopt();
+    }
+
     // Add check to deoptimize the nmethod if RTM state was changed
     rtm_deopt();
   }
 
   // Check for bailouts during method entry or RTM state check setup.

@@ -2100,15 +2105,41 @@
   }
 
   set_control( _gvn.transform(result_rgn) );
 }
 
+// Add check to deoptimize once holder klass is fully initialized.
+void Parse::clinit_deopt() {
+  assert(C->has_method(), "only for normal compilations");
+  assert(depth() == 1, "only for main compiled method");
+  assert(is_normal_parse(), "no barrier needed on osr entry");
+  assert(method()->needs_clinit_barrier(), "barrier not needed");
+  assert(method()->holder()->is_being_initialized(), "barrier not needed");
+
+  set_parse_bci(0);
+
+  Node* holder = makecon(TypeKlassPtr::make(method()->holder()));
+  int init_state_off = in_bytes(InstanceKlass::init_state_offset());
+  const Type* t = TypeKlassPtr::make(method()->holder(), init_state_off);
+  Node* adr = basic_plus_adr(top(), holder, init_state_off);
+  Node* init_state = make_load(control(), adr, TypeInt::BYTE, T_BYTE, MemNode::unordered);
+
+  Node* fully_initialized_state = makecon(TypeInt::make(InstanceKlass::fully_initialized));
+
+  Node* chk = gvn().transform(new CmpINode(init_state, fully_initialized_state));
+  Node* tst = gvn().transform(new BoolNode(chk, BoolTest::ne));
+
+  { BuildCutout unless(this, tst, PROB_MAX);
+    uncommon_trap(Deoptimization::Reason_initialized, Deoptimization::Action_reinterpret);
+  }
+}
+
 // Add check to deoptimize if RTM state is not ProfileRTM
 void Parse::rtm_deopt() {
 #if INCLUDE_RTM_OPT
   if (C->profile_rtm()) {
-    assert(C->method() != NULL, "only for normal compilations");
+    assert(C->has_method(), "only for normal compilations");
     assert(!C->method()->method_data()->is_empty(), "MDO is needed to record RTM state");
     assert(depth() == 1, "generate check only for main compiled method");
 
     // Set starting bci for uncommon trap.
     set_parse_bci(is_osr_parse() ? osr_bci() : 0);
< prev index next >