< prev index next >

src/hotspot/share/code/codeCache.cpp

Print this page
@@ -34,10 +34,11 @@
  #include "code/nmethod.hpp"
  #include "code/pcDesc.hpp"
  #include "compiler/compilationPolicy.hpp"
  #include "compiler/compileBroker.hpp"
  #include "compiler/oopMap.hpp"
+ #include "gc/shared/barrierSetNMethod.hpp"
  #include "gc/shared/collectedHeap.hpp"
  #include "jfr/jfrEvents.hpp"
  #include "logging/log.hpp"
  #include "logging/logStream.hpp"
  #include "memory/allocation.inline.hpp"

@@ -651,10 +652,27 @@
      }
    }
    return NULL;
  }
  
+ CodeBlob* CodeCache::patch_nop(NativePostCallNop* nop, void* pc, int& slot) {
+   CodeBlob* cb = CodeCache::find_blob(pc);
+   int oopmap_slot = cb->oop_maps()->find_slot_for_offset((intptr_t) pc - (intptr_t) cb->code_begin());
+   intptr_t cbaddr = (intptr_t) cb;
+   intptr_t offset = ((intptr_t) pc) - cbaddr;
+ 
+   if (((oopmap_slot & 0xff) == oopmap_slot) && ((offset & 0xffffff) == offset)) {
+     jint value = (oopmap_slot << 24) | (jint) offset;
+     nop->patch(value);
+     slot = oopmap_slot;
+   } else {
+     slot = -1;
+     log_debug(codecache)("failed to encode %d %d", oopmap_slot, (int) offset);
+   }
+   return cb;
+ }
+ 
  nmethod* CodeCache::find_nmethod(void* start) {
    CodeBlob* cb = find_blob(start);
    assert(cb->is_nmethod(), "did not find an nmethod");
    return (nmethod*)cb;
  }

@@ -774,20 +792,27 @@
    }
    _exception_cache_purge_list = NULL;
  }
  
  uint8_t CodeCache::_unloading_cycle = 1;
+ uint64_t CodeCache::_marking_cycle = 0;
  
  void CodeCache::increment_unloading_cycle() {
    // 2-bit value (see IsUnloadingState in nmethod.cpp for details)
    // 0 is reserved for new methods.
    _unloading_cycle = (_unloading_cycle + 1) % 4;
    if (_unloading_cycle == 0) {
      _unloading_cycle = 1;
    }
  }
  
+ void CodeCache::increment_marking_cycle() {
+   ++_marking_cycle;
+   BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
+   bs_nm->arm_all_nmethods();
+ }
+ 
  CodeCache::UnloadingScope::UnloadingScope(BoolObjectClosure* is_alive)
    : _is_unloading_behaviour(is_alive)
  {
    _saved_behaviour = IsUnloadingBehaviour::current();
    IsUnloadingBehaviour::set_current(&_is_unloading_behaviour);

@@ -1107,11 +1132,13 @@
    assert(SafepointSynchronize::is_at_safepoint(), "Can only do this at a safepoint!");
    CompiledMethodIterator iter(CompiledMethodIterator::only_alive_and_not_unloading);
    while(iter.next()) {
      CompiledMethod* nm = iter.method();
      if (!nm->method()->is_method_handle_intrinsic()) {
-       nm->mark_for_deoptimization();
+       if (nm->can_be_deoptimized()) {
+         nm->mark_for_deoptimization();
+       }
        if (nm->has_evol_metadata()) {
          add_to_old_table(nm);
        }
      }
    }

@@ -1159,17 +1186,31 @@
    }
  
    return number_of_marked_CodeBlobs;
  }
  
- void CodeCache::make_marked_nmethods_not_entrant() {
+ void CodeCache::make_marked_nmethods_not_entrant(GrowableArray<CompiledMethod*>* marked) {
    assert_locked_or_safepoint(CodeCache_lock);
    CompiledMethodIterator iter(CompiledMethodIterator::only_alive_and_not_unloading);
    while(iter.next()) {
      CompiledMethod* nm = iter.method();
      if (nm->is_marked_for_deoptimization()) {
-       nm->make_not_entrant();
+       if (!nm->make_not_entrant()) {
+         // if the method is not entrant already then it is needed run barrier
+         // to don't allow method become zombie before deoptimization even without safepoint
+         nm->run_nmethod_entry_barrier();
+       }
+       marked->append(nm);
+     }
+   }
+ }
+ 
+ void CodeCache::make_marked_nmethods_deoptimized(GrowableArray<CompiledMethod*>* marked) {
+   for (int i = 0; i < marked->length(); i++) {
+     CompiledMethod* nm = marked->at(i);
+     if (nm->is_marked_for_deoptimization() && nm->can_be_deoptimized()) {
+       nm->make_deoptimized();
      }
    }
  }
  
  // Flushes compiled methods dependent on dependee.
< prev index next >