src/share/vm/oops/methodOop.cpp

Print this page
rev 1083 : code cache unloading for webrev 091214

@@ -610,10 +610,20 @@
   assert(comp_level == CompLevel_highest_tier, "unexpected compilation level");
   invocation_counter()->set_state(InvocationCounter::wait_for_nothing);
   backedge_counter()->set_state(InvocationCounter::wait_for_nothing);
 }
 
+// Clear the code ptr during emergency code cache sweeping
+// It will be restored if it is actually called
+void methodOopDesc::clear_code_hedge() {
+  // should guarantee at safepoint
+  nmethod* tmp = code();
+  clear_code();
+  _saved_code = tmp;
+  assert( ! _saved_code->is_osr_method(), "should not get here for osr" );  
+}
+
 // Revert to using the interpreter and clear out the nmethod
 void methodOopDesc::clear_code() {
 
   // this may be NULL if c2i adapters have not been made yet
   // Only should happen at allocate time.

@@ -624,10 +634,11 @@
   }
   OrderAccess::storestore();
   _from_interpreted_entry = _i2i_entry;
   OrderAccess::storestore();
   _code = NULL;
+  _saved_code = NULL;
 }
 
 // Called by class data sharing to remove any entry points (which are not shared)
 void methodOopDesc::unlink_method() {
   _code = NULL;

@@ -703,10 +714,19 @@
 // This function is called after potential safepoints so that nmethod
 // or adapter that it points to is still live and valid.
 // This function must not hit a safepoint!
 address methodOopDesc::verified_code_entry() {
   debug_only(No_Safepoint_Verifier nsv;)
+  nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code);
+  nmethod *saved_code = (nmethod *)OrderAccess::load_ptr_acquire(&_saved_code);
+  if (( code == NULL) && (saved_code != NULL) && (saved_code->is_in_use())) {
+    methodHandle method(this);
+    assert(UseCodeCacheFlushing, "UseCodeCacheFlushing should be on");
+    assert( ! saved_code->is_osr_method(), "should not get here for osr" );
+    set_code( method, saved_code );
+  }
+  
   assert(_from_compiled_entry != NULL, "must be set");
   return _from_compiled_entry;
 }
 
 // Check that if an nmethod ref exists, it has a backlink to this or no backlink at all

@@ -723,10 +743,12 @@
   assert( code, "use clear_code to remove code" );
   assert( mh->check_code(), "" );
 
   guarantee(mh->adapter() != NULL, "Adapter blob must already exist!");
 
+  mh->set_saved_code(NULL);
+
   // These writes must happen in this order, because the interpreter will
   // directly jump to from_interpreted_entry which jumps to an i2c adapter
   // which jumps to _from_compiled_entry.
   mh->_code = code;             // Assign before allowing compiled code to exec