8151956: Support non-continuous CodeBlobs in HotSpot
authorrbackman
Tue, 26 Apr 2016 10:28:51 +0200
changeset 38133 78b95467b9f1
parent 38132 ba888a4f352a
child 38134 7435f311b441
8151956: Support non-continuous CodeBlobs in HotSpot Reviewed-by: iveresov, thartmann, simonis
hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp
hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp
hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp
hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.cpp
hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp
hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp
hotspot/src/cpu/sparc/vm/frame_sparc.cpp
hotspot/src/cpu/x86/vm/frame_x86.cpp
hotspot/src/cpu/x86/vm/frame_x86.hpp
hotspot/src/cpu/x86/vm/frame_x86.inline.hpp
hotspot/src/cpu/zero/vm/frame_zero.inline.hpp
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/AdapterBlob.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/BufferBlob.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CompiledMethod.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/RuntimeBlob.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/RuntimeStub.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/SingletonBlob.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java
hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp
hotspot/src/os/bsd/dtrace/libjvm_db.c
hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp
hotspot/src/os/solaris/dtrace/libjvm_db.c
hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp
hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp
hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp
hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
hotspot/src/share/vm/asm/codeBuffer.cpp
hotspot/src/share/vm/asm/codeBuffer.hpp
hotspot/src/share/vm/ci/ciEnv.cpp
hotspot/src/share/vm/ci/ciMethod.cpp
hotspot/src/share/vm/ci/ciReplay.cpp
hotspot/src/share/vm/classfile/classLoader.cpp
hotspot/src/share/vm/classfile/javaClasses.cpp
hotspot/src/share/vm/classfile/metadataOnStackMark.cpp
hotspot/src/share/vm/code/codeBlob.cpp
hotspot/src/share/vm/code/codeBlob.hpp
hotspot/src/share/vm/code/codeCache.cpp
hotspot/src/share/vm/code/codeCache.hpp
hotspot/src/share/vm/code/compiledIC.cpp
hotspot/src/share/vm/code/compiledIC.hpp
hotspot/src/share/vm/code/compiledMethod.cpp
hotspot/src/share/vm/code/compiledMethod.hpp
hotspot/src/share/vm/code/debugInfo.hpp
hotspot/src/share/vm/code/exceptionHandlerTable.cpp
hotspot/src/share/vm/code/exceptionHandlerTable.hpp
hotspot/src/share/vm/code/icBuffer.cpp
hotspot/src/share/vm/code/nmethod.cpp
hotspot/src/share/vm/code/nmethod.hpp
hotspot/src/share/vm/code/pcDesc.cpp
hotspot/src/share/vm/code/pcDesc.hpp
hotspot/src/share/vm/code/relocInfo.cpp
hotspot/src/share/vm/code/relocInfo.hpp
hotspot/src/share/vm/code/scopeDesc.cpp
hotspot/src/share/vm/code/scopeDesc.hpp
hotspot/src/share/vm/compiler/compileBroker.cpp
hotspot/src/share/vm/compiler/compileTask.cpp
hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp
hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp
hotspot/src/share/vm/jvmci/jvmciEnv.cpp
hotspot/src/share/vm/jvmci/jvmciRuntime.cpp
hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp
hotspot/src/share/vm/oops/method.cpp
hotspot/src/share/vm/oops/method.hpp
hotspot/src/share/vm/opto/compile.cpp
hotspot/src/share/vm/opto/runtime.cpp
hotspot/src/share/vm/prims/whitebox.cpp
hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp
hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp
hotspot/src/share/vm/runtime/compilationPolicy.cpp
hotspot/src/share/vm/runtime/compilationPolicy.hpp
hotspot/src/share/vm/runtime/deoptimization.cpp
hotspot/src/share/vm/runtime/fprofiler.cpp
hotspot/src/share/vm/runtime/frame.cpp
hotspot/src/share/vm/runtime/rframe.cpp
hotspot/src/share/vm/runtime/safepoint.cpp
hotspot/src/share/vm/runtime/sharedRuntime.cpp
hotspot/src/share/vm/runtime/sharedRuntime.hpp
hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp
hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp
hotspot/src/share/vm/runtime/stubRoutines.hpp
hotspot/src/share/vm/runtime/sweeper.cpp
hotspot/src/share/vm/runtime/sweeper.hpp
hotspot/src/share/vm/runtime/thread.cpp
hotspot/src/share/vm/runtime/thread.hpp
hotspot/src/share/vm/runtime/vframe.cpp
hotspot/src/share/vm/runtime/vframe.hpp
hotspot/src/share/vm/runtime/vframeArray.cpp
hotspot/src/share/vm/runtime/vframe_hp.cpp
hotspot/src/share/vm/runtime/vframe_hp.hpp
hotspot/src/share/vm/runtime/vmStructs.cpp
hotspot/src/share/vm/utilities/globalDefinitions.hpp
hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java
hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java
hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -221,21 +221,19 @@
       return jcw_safe;
     }
 
-    if (sender_blob->is_nmethod()) {
-        nmethod* nm = sender_blob->as_nmethod_or_null();
-        if (nm != NULL) {
-            if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc) ||
-                nm->method()->is_method_handle_intrinsic()) {
-                return false;
-            }
-        }
+    CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
+    if (nm != NULL) {
+      if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc) ||
+          nm->method()->is_method_handle_intrinsic()) {
+        return false;
+      }
     }
 
     // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
     // because the return address counts against the callee's frame.
 
     if (sender_blob->frame_size() <= 0) {
-      assert(!sender_blob->is_nmethod(), "should count return address at least");
+      assert(!sender_blob->is_compiled(), "should count return address at least");
       return false;
     }
 
@@ -244,7 +242,7 @@
     // should not be anything but the call stub (already covered), the interpreter (already covered)
     // or an nmethod.
 
-    if (!sender_blob->is_nmethod()) {
+    if (!sender_blob->is_compiled()) {
         return false;
     }
 
@@ -286,7 +284,7 @@
   assert(_pc == *pc_addr || pc == *pc_addr, "must be");
   *pc_addr = pc;
   _cb = CodeCache::find_blob(pc);
-  address original_pc = nmethod::get_deopt_original_pc(this);
+  address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     assert(original_pc == _pc, "expected original PC to be stored before patching");
     _deopt_state = is_deoptimized;
@@ -371,7 +369,7 @@
 // Verifies the calculated original PC of a deoptimization PC for the
 // given unextended SP.
 #ifdef ASSERT
-void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp) {
+void frame::verify_deopt_original_pc(CompiledMethod* nm, intptr_t* unextended_sp) {
   frame fr;
 
   // This is ugly but it's better than to change {get,set}_original_pc
@@ -391,12 +389,14 @@
   // as any other call site. Therefore, no special action is needed when we are
   // returning to any of these call sites.
 
-  nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null();
-  if (sender_nm != NULL) {
-    // If the sender PC is a deoptimization point, get the original PC.
-    if (sender_nm->is_deopt_entry(_pc) ||
-        sender_nm->is_deopt_mh_entry(_pc)) {
-      DEBUG_ONLY(verify_deopt_original_pc(sender_nm, _unextended_sp));
+  if (_cb != NULL) {
+    CompiledMethod* sender_cm = _cb->as_compiled_method_or_null();
+    if (sender_cm != NULL) {
+      // If the sender PC is a deoptimization point, get the original PC.
+      if (sender_cm->is_deopt_entry(_pc) ||
+          sender_cm->is_deopt_mh_entry(_pc)) {
+        DEBUG_ONLY(verify_deopt_original_pc(sender_cm, _unextended_sp));
+      }
     }
   }
 }
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -124,7 +124,7 @@
 
 #ifdef ASSERT
   // Used in frame::sender_for_{interpreter,compiled}_frame
-  static void verify_deopt_original_pc(   nmethod* nm, intptr_t* unextended_sp);
+  static void verify_deopt_original_pc(   CompiledMethod* nm, intptr_t* unextended_sp);
 #endif
 
  public:
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -55,7 +55,7 @@
   _cb = CodeCache::find_blob(pc);
   adjust_unextended_sp();
 
-  address original_pc = nmethod::get_deopt_original_pc(this);
+  address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
     _deopt_state = is_deoptimized;
@@ -79,10 +79,10 @@
   _cb = CodeCache::find_blob(pc);
   adjust_unextended_sp();
 
-  address original_pc = nmethod::get_deopt_original_pc(this);
+  address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
-    assert(((nmethod*)_cb)->insts_contains(_pc), "original PC must be in nmethod");
+    assert(((CompiledMethod*)_cb)->insts_contains(_pc), "original PC must be in CompiledMethod");
     _deopt_state = is_deoptimized;
   } else {
     _deopt_state = not_deoptimized;
@@ -111,7 +111,7 @@
   _cb = CodeCache::find_blob(_pc);
   adjust_unextended_sp();
 
-  address original_pc = nmethod::get_deopt_original_pc(this);
+  address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
     _deopt_state = is_deoptimized;
--- a/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -99,7 +99,7 @@
 
   address bl_destination
     = MacroAssembler::pd_call_destination(call_addr);
-  if (code->content_contains(bl_destination) &&
+  if (code->contains(bl_destination) &&
       is_NativeCallTrampolineStub_at(bl_destination))
     return bl_destination;
 
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -40,7 +40,7 @@
 
   _fp = (intptr_t*)own_abi()->callers_sp;
 
-  address original_pc = nmethod::get_deopt_original_pc(this);
+  address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
     _deopt_state = is_deoptimized;
--- a/hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -137,7 +137,7 @@
     return NULL;
 
   address bl_destination = Assembler::bxx_destination(call_addr);
-  if (code->content_contains(bl_destination) &&
+  if (code->contains(bl_destination) &&
       is_NativeCallTrampolineStub_at(bl_destination))
     return bl_destination;
 
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -212,7 +212,7 @@
     // ok. adapter blobs never have a frame complete and are never ok.
 
     if (!_cb->is_frame_complete_at(_pc)) {
-      if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
+      if (_cb->is_compiled() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
         return false;
       }
     }
@@ -304,7 +304,7 @@
     // because you must allocate window space
 
     if (sender_blob->frame_size() <= 0) {
-      assert(!sender_blob->is_nmethod(), "should count return address at least");
+      assert(!sender_blob->is_compiled(), "should count return address at least");
       return false;
     }
 
@@ -315,7 +315,7 @@
     // the stack unwalkable. pd_get_top_frame_for_signal_handler tries to recover from this by unwinding
     // that initial frame and retrying.
 
-    if (!sender_blob->is_nmethod()) {
+    if (!sender_blob->is_compiled()) {
       return false;
     }
 
@@ -358,9 +358,9 @@
   }
   _deopt_state = unknown;
 #ifdef ASSERT
-  if ( _cb != NULL && _cb->is_nmethod()) {
+  if ( _cb != NULL && _cb->is_compiled()) {
     // Without a valid unextended_sp() we can't convert the pc to "original"
-    assert(!((nmethod*)_cb)->is_deopt_pc(_pc), "invariant broken");
+    assert(!((CompiledMethod*)_cb)->is_deopt_pc(_pc), "invariant broken");
   }
 #endif // ASSERT
 }
@@ -393,7 +393,7 @@
 
   // Check for MethodHandle call sites.
   if (_cb != NULL) {
-    nmethod* nm = _cb->as_nmethod_or_null();
+    CompiledMethod* nm = _cb->as_compiled_method_or_null();
     if (nm != NULL) {
       if (nm->is_deopt_mh_entry(_pc) || nm->is_method_handle_return(_pc)) {
         _sp_adjustment_by_callee = (intptr_t*) ((intptr_t) sp[L7_mh_SP_save->sp_offset_in_saved_window()] + STACK_BIAS) - sp;
@@ -413,7 +413,7 @@
   // this lookup as get_deopt_original_pc() needs a correct value for
   // unextended_sp() which uses _sp_adjustment_by_callee.
   if (_pc != NULL) {
-    address original_pc = nmethod::get_deopt_original_pc(this);
+    address original_pc = CompiledMethod::get_deopt_original_pc(this);
     if (original_pc != NULL) {
       _pc = original_pc;
       _deopt_state = is_deoptimized;
@@ -547,7 +547,7 @@
   _cb = CodeCache::find_blob(pc);
   *O7_addr() = pc - pc_return_offset;
   _cb = CodeCache::find_blob(_pc);
-  address original_pc = nmethod::get_deopt_original_pc(this);
+  address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     assert(original_pc == _pc, "expected original to be stored before patching");
     _deopt_state = is_deoptimized;
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -95,7 +95,7 @@
     // ok. adapter blobs never have a frame complete and are never ok.
 
     if (!_cb->is_frame_complete_at(_pc)) {
-      if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
+      if (_cb->is_compiled() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
         return false;
       }
     }
@@ -220,13 +220,11 @@
       return jcw_safe;
     }
 
-    if (sender_blob->is_nmethod()) {
-        nmethod* nm = sender_blob->as_nmethod_or_null();
-        if (nm != NULL) {
-            if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc) ||
-                nm->method()->is_method_handle_intrinsic()) {
-                return false;
-            }
+    CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
+    if (nm != NULL) {
+        if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc) ||
+            nm->method()->is_method_handle_intrinsic()) {
+            return false;
         }
     }
 
@@ -234,7 +232,7 @@
     // because the return address counts against the callee's frame.
 
     if (sender_blob->frame_size() <= 0) {
-      assert(!sender_blob->is_nmethod(), "should count return address at least");
+      assert(!sender_blob->is_compiled(), "should count return address at least");
       return false;
     }
 
@@ -243,7 +241,7 @@
     // should not be anything but the call stub (already covered), the interpreter (already covered)
     // or an nmethod.
 
-    if (!sender_blob->is_nmethod()) {
+    if (!sender_blob->is_compiled()) {
         return false;
     }
 
@@ -286,7 +284,7 @@
   assert(_pc == *pc_addr || pc == *pc_addr, "must be");
   *pc_addr = pc;
   _cb = CodeCache::find_blob(pc);
-  address original_pc = nmethod::get_deopt_original_pc(this);
+  address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     assert(original_pc == _pc, "expected original PC to be stored before patching");
     _deopt_state = is_deoptimized;
@@ -372,7 +370,7 @@
 // Verifies the calculated original PC of a deoptimization PC for the
 // given unextended SP.
 #ifdef ASSERT
-void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp) {
+void frame::verify_deopt_original_pc(CompiledMethod* nm, intptr_t* unextended_sp) {
   frame fr;
 
   // This is ugly but it's better than to change {get,set}_original_pc
@@ -381,7 +379,7 @@
   fr._unextended_sp = unextended_sp;
 
   address original_pc = nm->get_original_pc(&fr);
-  assert(nm->insts_contains(original_pc), "original PC must be in nmethod");
+  assert(nm->insts_contains(original_pc), "original PC must be in CompiledMethod");
 }
 #endif
 
@@ -392,12 +390,14 @@
   // as any other call site. Therefore, no special action is needed when we are
   // returning to any of these call sites.
 
-  nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null();
-  if (sender_nm != NULL) {
-    // If the sender PC is a deoptimization point, get the original PC.
-    if (sender_nm->is_deopt_entry(_pc) ||
-        sender_nm->is_deopt_mh_entry(_pc)) {
-      DEBUG_ONLY(verify_deopt_original_pc(sender_nm, _unextended_sp));
+  if (_cb != NULL) {
+    CompiledMethod* sender_cm = _cb->as_compiled_method_or_null();
+    if (sender_cm != NULL) {
+      // If the sender PC is a deoptimization point, get the original PC.
+      if (sender_cm->is_deopt_entry(_pc) ||
+          sender_cm->is_deopt_mh_entry(_pc)) {
+        DEBUG_ONLY(verify_deopt_original_pc(sender_cm, _unextended_sp));
+      }
     }
   }
 }
--- a/hotspot/src/cpu/x86/vm/frame_x86.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/cpu/x86/vm/frame_x86.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -124,7 +124,7 @@
 
 #ifdef ASSERT
   // Used in frame::sender_for_{interpreter,compiled}_frame
-  static void verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp);
+  static void verify_deopt_original_pc(CompiledMethod* nm, intptr_t* unextended_sp);
 #endif
 
  public:
--- a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,7 +50,7 @@
   _cb = CodeCache::find_blob(pc);
   adjust_unextended_sp();
 
-  address original_pc = nmethod::get_deopt_original_pc(this);
+  address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
     _deopt_state = is_deoptimized;
@@ -72,10 +72,10 @@
   _cb = CodeCache::find_blob(pc);
   adjust_unextended_sp();
 
-  address original_pc = nmethod::get_deopt_original_pc(this);
+  address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
-    assert(((nmethod*)_cb)->insts_contains(_pc), "original PC must be in nmethod");
+    assert(((CompiledMethod*)_cb)->insts_contains(_pc), "original PC must be in CompiledMethod");
     _deopt_state = is_deoptimized;
   } else {
     if (_cb->is_deoptimization_stub()) {
@@ -106,7 +106,7 @@
   _cb = CodeCache::find_blob(_pc);
   adjust_unextended_sp();
 
-  address original_pc = nmethod::get_deopt_original_pc(this);
+  address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
     _deopt_state = is_deoptimized;
--- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -59,7 +59,7 @@
   case ZeroFrame::SHARK_FRAME: {
     _pc = zero_sharkframe()->pc();
     _cb = CodeCache::find_blob_unsafe(pc());
-    address original_pc = nmethod::get_deopt_original_pc(this);
+    address original_pc = CompiledMethod::get_deopt_original_pc(this);
     if (original_pc != NULL) {
       _pc = original_pc;
       _deopt_state = is_deoptimized;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/AdapterBlob.java	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/AdapterBlob.java	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.types.*;
 
-public class AdapterBlob extends CodeBlob {
+public class AdapterBlob extends RuntimeBlob {
   static {
     VM.registerVMInitializedObserver(new Observer() {
         public void update(Observable o, Object data) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/BufferBlob.java	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/BufferBlob.java	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.types.*;
 
-public class BufferBlob extends CodeBlob {
+public class BufferBlob extends RuntimeBlob {
   static {
     VM.registerVMInitializedObserver(new Observer() {
         public void update(Observable o, Object data) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -19,46 +19,42 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
-
 package sun.jvm.hotspot.code;
 
-import java.io.*;
-import java.util.*;
+import sun.jvm.hotspot.compiler.ImmutableOopMap;
+import sun.jvm.hotspot.compiler.ImmutableOopMapSet;
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.types.AddressField;
+import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+import sun.jvm.hotspot.utilities.Assert;
 
-import sun.jvm.hotspot.compiler.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.utilities.*;
+import java.io.PrintStream;
+import java.util.Observable;
+import java.util.Observer;
 
 public class CodeBlob extends VMObject {
-  private static AddressField  nameField;
+  private static AddressField nameField;
   private static CIntegerField sizeField;
   private static CIntegerField headerSizeField;
-  private static CIntegerField relocationSizeField;
-  private static CIntegerField contentOffsetField;
-  private static CIntegerField codeOffsetField;
+  private static AddressField  contentBeginField;
+  private static AddressField  codeBeginField;
+  private static AddressField  codeEndField;
+  private static AddressField  dataEndField;
   private static CIntegerField frameCompleteOffsetField;
   private static CIntegerField dataOffsetField;
   private static CIntegerField frameSizeField;
   private static AddressField  oopMapsField;
 
-  // Only used by server compiler on x86; computed over in SA rather
-  // than relying on computation in target VM
-  private static final int     NOT_YET_COMPUTED = -2;
-  private static final int     UNDEFINED        = -1;
-  private              int     linkOffset       = NOT_YET_COMPUTED;
-  private static       int     matcherInterpreterFramePointerReg;
+  public CodeBlob(Address addr) {
+    super(addr);
+  }
 
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
+  protected static       int     matcherInterpreterFramePointerReg;
 
   private static void initialize(TypeDataBase db) {
     Type type = db.lookupType("CodeBlob");
@@ -66,37 +62,99 @@
     nameField                = type.getAddressField("_name");
     sizeField                = type.getCIntegerField("_size");
     headerSizeField          = type.getCIntegerField("_header_size");
-    relocationSizeField      = type.getCIntegerField("_relocation_size");
     frameCompleteOffsetField = type.getCIntegerField("_frame_complete_offset");
-    contentOffsetField       = type.getCIntegerField("_content_offset");
-    codeOffsetField          = type.getCIntegerField("_code_offset");
+    contentBeginField        = type.getAddressField("_content_begin");
+    codeBeginField           = type.getAddressField("_code_begin");
+    codeEndField             = type.getAddressField("_code_end");
+    dataEndField             = type.getAddressField("_data_end");
     dataOffsetField          = type.getCIntegerField("_data_offset");
     frameSizeField           = type.getCIntegerField("_frame_size");
     oopMapsField             = type.getAddressField("_oop_maps");
 
     if (VM.getVM().isServerCompiler()) {
       matcherInterpreterFramePointerReg =
-        db.lookupIntConstant("Matcher::interpreter_frame_pointer_reg").intValue();
+          db.lookupIntConstant("Matcher::interpreter_frame_pointer_reg").intValue();
     }
   }
 
-  public CodeBlob(Address addr) {
-    super(addr);
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+      public void update(Observable o, Object data) {
+        initialize(VM.getVM().getTypeDataBase());
+      }
+    });
   }
 
+  public Address headerBegin() { return getAddress(); }
+
+  public Address headerEnd() { return getAddress().addOffsetTo(getHeaderSize()); }
+
+  public Address contentBegin() { return contentBeginField.getValue(addr); }
+
+  public Address contentEnd() { return headerBegin().addOffsetTo(getDataOffset()); }
+
+  public Address codeBegin() { return codeBeginField.getValue(addr); }
+
+  public Address codeEnd() { return codeEndField.getValue(addr); }
+
+  public Address dataBegin() { return headerBegin().addOffsetTo(getDataOffset()); }
+
+  public Address dataEnd() { return dataEndField.getValue(addr); }
+
+  public long getFrameCompleteOffset() { return frameCompleteOffsetField.getValue(addr); }
+
+  public int getDataOffset()       { return (int) dataOffsetField.getValue(addr); }
+
+  // Sizes
+  public int getSize()             { return (int) sizeField.getValue(addr); }
+
+  public int getHeaderSize()       { return (int) headerSizeField.getValue(addr); }
+
+  public long getFrameSizeWords() {
+    return (int) frameSizeField.getValue(addr);
+  }
+
+  public String getName() {
+    return getName();
+  }
+
+  /** OopMap for frame; can return null if none available */
+
+  public ImmutableOopMapSet getOopMaps() {
+    Address value = oopMapsField.getValue(addr);
+    if (value == null) {
+      return null;
+    }
+    return new ImmutableOopMapSet(value);
+  }
+
+
   // Typing
   public boolean isBufferBlob()         { return false; }
+
+  public boolean isAOT()                { return false; }
+
+  public boolean isCompiled()           { return false; }
+
   public boolean isNMethod()            { return false; }
+
   public boolean isRuntimeStub()        { return false; }
+
   public boolean isDeoptimizationStub() { return false; }
+
   public boolean isUncommonTrapStub()   { return false; }
+
   public boolean isExceptionStub()      { return false; }
+
   public boolean isSafepointStub()      { return false; }
+
   public boolean isAdapterBlob()        { return false; }
 
   // Fine grain nmethod support: isNmethod() == isJavaMethod() || isNativeMethod() || isOSRMethod()
   public boolean isJavaMethod()         { return false; }
+
   public boolean isNativeMethod()       { return false; }
+
   /** On-Stack Replacement method */
   public boolean isOSRMethod()          { return false; }
 
@@ -105,82 +163,33 @@
     return null;
   }
 
-  // Boundaries
-  public Address headerBegin() {
-    return addr;
-  }
-
-  public Address headerEnd() {
-    return addr.addOffsetTo(headerSizeField.getValue(addr));
-  }
-
-  // FIXME: add RelocInfo
-  //  public RelocInfo relocationBegin();
-  //  public RelocInfo relocationEnd();
-
-  public Address contentBegin() {
-    return headerBegin().addOffsetTo(contentOffsetField.getValue(addr));
-  }
-
-  public Address contentEnd() {
-    return headerBegin().addOffsetTo(dataOffsetField.getValue(addr));
-  }
-
-  public Address codeBegin() {
-    return headerBegin().addOffsetTo(contentOffsetField.getValue(addr));
-  }
-
-  public Address codeEnd() {
-    return headerBegin().addOffsetTo(dataOffsetField.getValue(addr));
-  }
-
-  public Address dataBegin() {
-    return headerBegin().addOffsetTo(dataOffsetField.getValue(addr));
-  }
-
-  public Address dataEnd() {
-    return headerBegin().addOffsetTo(sizeField.getValue(addr));
-  }
-
-  // Offsets
-  public int getRelocationOffset() { return (int) headerSizeField   .getValue(addr); }
-  public int getContentOffset()    { return (int) contentOffsetField.getValue(addr); }
-  public int getCodeOffset()       { return (int) codeOffsetField   .getValue(addr); }
-  public int getDataOffset()       { return (int) dataOffsetField   .getValue(addr); }
-
-  // Sizes
-  public int getSize()             { return (int) sizeField      .getValue(addr);     }
-  public int getHeaderSize()       { return (int) headerSizeField.getValue(addr);     }
   // FIXME: add getRelocationSize()
   public int getContentSize()      { return (int) contentEnd().minus(contentBegin()); }
+
   public int getCodeSize()         { return (int) codeEnd()   .minus(codeBegin());    }
+
   public int getDataSize()         { return (int) dataEnd()   .minus(dataBegin());    }
 
   // Containment
   public boolean blobContains(Address addr)    { return headerBegin() .lessThanOrEqual(addr) && dataEnd()   .greaterThan(addr); }
+
   // FIXME: add relocationContains
   public boolean contentContains(Address addr) { return contentBegin().lessThanOrEqual(addr) && contentEnd().greaterThan(addr); }
+
   public boolean codeContains(Address addr)    { return codeBegin()   .lessThanOrEqual(addr) && codeEnd()   .greaterThan(addr); }
+
   public boolean dataContains(Address addr)    { return dataBegin()   .lessThanOrEqual(addr) && dataEnd()   .greaterThan(addr); }
+
   public boolean contains(Address addr)        { return contentContains(addr);                                                  }
-  public boolean isFrameCompleteAt(Address a)  { return codeContains(a) && a.minus(codeBegin()) >= frameCompleteOffsetField.getValue(addr); }
+
+  public boolean isFrameCompleteAt(Address a)  { return codeContains(a) && a.minus(codeBegin()) >= getFrameCompleteOffset(); }
 
   // Reclamation support (really only used by the nmethods, but in order to get asserts to work
   // in the CodeCache they are defined virtual here)
   public boolean isZombie()             { return false; }
+
   public boolean isLockedByVM()         { return false; }
 
-  /** OopMap for frame; can return null if none available */
-  public ImmutableOopMapSet getOopMaps() {
-    Address oopMapsAddr = oopMapsField.getValue(addr);
-    if (oopMapsAddr == null) {
-      return null;
-    }
-    return new ImmutableOopMapSet(oopMapsAddr);
-  }
-  // FIXME: not yet implementable
-  //  void set_oop_maps(ImmutableOopMapSet* p);
-
   public ImmutableOopMap getOopMapForReturnAddress(Address returnAddress, boolean debugging) {
     Address pc = returnAddress;
     if (Assert.ASSERTS_ENABLED) {
@@ -189,25 +198,14 @@
     return getOopMaps().findMapAtOffset(pc.minus(codeBegin()), debugging);
   }
 
-  //  virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, void f(oop*)) { ShouldNotReachHere(); }
-  //  FIXME;
-
   /** NOTE: this returns a size in BYTES in this system! */
   public long getFrameSize() {
-    return VM.getVM().getAddressSize() * frameSizeField.getValue(addr);
+    return VM.getVM().getAddressSize() * getFrameSizeWords();
   }
 
   // Returns true, if the next frame is responsible for GC'ing oops passed as arguments
   public boolean callerMustGCArguments() { return false; }
 
-  public String getName() {
-    return CStringUtilities.getString(nameField.getValue(addr));
-  }
-
-  // FIXME: NOT FINISHED
-
-  // FIXME: add more accessors
-
   public void print() {
     printOn(System.out);
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CompiledMethod.java	Tue Apr 26 10:28:51 2016 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.jvm.hotspot.code;
+
+import java.util.*;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+public abstract class CompiledMethod extends CodeBlob {
+  private static AddressField  methodField;
+  private static AddressField  deoptHandlerBeginField;
+  private static AddressField  deoptMhHandlerBeginField;
+  private static AddressField  scopesDataBeginField;
+
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static void initialize(TypeDataBase db) {
+    Type type = db.lookupType("CompiledMethod");
+
+    methodField                 = type.getAddressField("_method");
+    deoptHandlerBeginField      = type.getAddressField("_deopt_handler_begin");
+    deoptMhHandlerBeginField    = type.getAddressField("_deopt_mh_handler_begin");
+    scopesDataBeginField        = type.getAddressField("_scopes_data_begin");
+  }
+
+  public CompiledMethod(Address addr) {
+    super(addr);
+  }
+
+  public Method getMethod() {
+    return (Method)Metadata.instantiateWrapperFor(methodField.getValue(addr));
+  }
+
+  public Address deoptHandlerBegin()    { return deoptHandlerBeginField.getValue(addr);              }
+  public Address deoptMhHandlerBegin()  { return deoptMhHandlerBeginField.getValue(addr);            }
+  public Address scopesDataBegin()      { return scopesDataBeginField.getValue(addr);                }
+
+  public static int getMethodOffset()                { return (int) methodField.getOffset();                }
+
+  @Override
+  public boolean isCompiled() {
+    return true;
+  }
+}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,15 +27,13 @@
 import java.io.*;
 import java.util.*;
 import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.memory.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.utilities.*;
 
-public class NMethod extends CodeBlob {
+public class NMethod extends CompiledMethod {
   private static long          pcDescSize;
-  private static AddressField  methodField;
   /** != InvocationEntryBci if this nmethod is an on-stack replacement method */
   private static CIntegerField entryBCIField;
   /** To support simple linked-list chaining of nmethods */
@@ -45,13 +43,10 @@
 
   /** Offsets for different nmethod parts */
   private static CIntegerField exceptionOffsetField;
-  private static CIntegerField deoptOffsetField;
-  private static CIntegerField deoptMhOffsetField;
   private static CIntegerField origPCOffsetField;
   private static CIntegerField stubOffsetField;
   private static CIntegerField oopsOffsetField;
   private static CIntegerField metadataOffsetField;
-  private static CIntegerField scopesDataOffsetField;
   private static CIntegerField scopesPCsOffsetField;
   private static CIntegerField dependenciesOffsetField;
   private static CIntegerField handlerTableOffsetField;
@@ -91,20 +86,16 @@
   private static void initialize(TypeDataBase db) {
     Type type = db.lookupType("nmethod");
 
-    methodField                 = type.getAddressField("_method");
     entryBCIField               = type.getCIntegerField("_entry_bci");
     osrLinkField                = type.getAddressField("_osr_link");
     scavengeRootLinkField       = type.getAddressField("_scavenge_root_link");
     scavengeRootStateField      = type.getJByteField("_scavenge_root_state");
 
     exceptionOffsetField        = type.getCIntegerField("_exception_offset");
-    deoptOffsetField            = type.getCIntegerField("_deoptimize_offset");
-    deoptMhOffsetField          = type.getCIntegerField("_deoptimize_mh_offset");
     origPCOffsetField           = type.getCIntegerField("_orig_pc_offset");
     stubOffsetField             = type.getCIntegerField("_stub_offset");
     oopsOffsetField             = type.getCIntegerField("_oops_offset");
     metadataOffsetField         = type.getCIntegerField("_metadata_offset");
-    scopesDataOffsetField       = type.getCIntegerField("_scopes_data_offset");
     scopesPCsOffsetField        = type.getCIntegerField("_scopes_pcs_offset");
     dependenciesOffsetField     = type.getCIntegerField("_dependencies_offset");
     handlerTableOffsetField     = type.getCIntegerField("_handler_table_offset");
@@ -123,16 +114,11 @@
     super(addr);
   }
 
-
   // Accessors
   public Address getAddress() {
     return addr;
   }
 
-  public Method getMethod() {
-    return (Method)Metadata.instantiateWrapperFor(methodField.getValue(addr));
-  }
-
   // Type info
   public boolean isNMethod()      { return true;                    }
   public boolean isJavaMethod()   { return !getMethod().isNative(); }
@@ -145,15 +131,12 @@
   public Address instsBegin()           { return codeBegin();                                        }
   public Address instsEnd()             { return headerBegin().addOffsetTo(getStubOffset());         }
   public Address exceptionBegin()       { return headerBegin().addOffsetTo(getExceptionOffset());    }
-  public Address deoptHandlerBegin()    { return headerBegin().addOffsetTo(getDeoptOffset());        }
-  public Address deoptMhHandlerBegin()  { return headerBegin().addOffsetTo(getDeoptMhOffset());      }
   public Address stubBegin()            { return headerBegin().addOffsetTo(getStubOffset());         }
   public Address stubEnd()              { return headerBegin().addOffsetTo(getOopsOffset());         }
   public Address oopsBegin()            { return headerBegin().addOffsetTo(getOopsOffset());         }
   public Address oopsEnd()              { return headerBegin().addOffsetTo(getMetadataOffset());     }
   public Address metadataBegin()        { return headerBegin().addOffsetTo(getMetadataOffset());     }
-  public Address metadataEnd()          { return headerBegin().addOffsetTo(getScopesDataOffset());   }
-  public Address scopesDataBegin()      { return headerBegin().addOffsetTo(getScopesDataOffset());   }
+  public Address metadataEnd()          { return scopesDataBegin();                                  }
   public Address scopesDataEnd()        { return headerBegin().addOffsetTo(getScopesPCsOffset());    }
   public Address scopesPCsBegin()       { return headerBegin().addOffsetTo(getScopesPCsOffset());    }
   public Address scopesPCsEnd()         { return headerBegin().addOffsetTo(getDependenciesOffset()); }
@@ -462,8 +445,6 @@
   public static int getVerifiedEntryPointOffset()    { return (int) verifiedEntryPointField.getOffset();    }
   public static int getOSREntryPointOffset()         { return (int) osrEntryPointField.getOffset();         }
   public static int getEntryBCIOffset()              { return (int) entryBCIField.getOffset();              }
-  /** NOTE: renamed from "method_offset_in_bytes" */
-  public static int getMethodOffset()                { return (int) methodField.getOffset();                }
 
   public void print() {
     printOn(System.out);
@@ -541,12 +522,9 @@
 
   private int getEntryBCI()           { return (int) entryBCIField          .getValue(addr); }
   private int getExceptionOffset()    { return (int) exceptionOffsetField   .getValue(addr); }
-  private int getDeoptOffset()        { return (int) deoptOffsetField       .getValue(addr); }
-  private int getDeoptMhOffset()      { return (int) deoptMhOffsetField     .getValue(addr); }
   private int getStubOffset()         { return (int) stubOffsetField        .getValue(addr); }
   private int getOopsOffset()         { return (int) oopsOffsetField        .getValue(addr); }
   private int getMetadataOffset()     { return (int) metadataOffsetField    .getValue(addr); }
-  private int getScopesDataOffset()   { return (int) scopesDataOffsetField  .getValue(addr); }
   private int getScopesPCsOffset()    { return (int) scopesPCsOffsetField   .getValue(addr); }
   private int getDependenciesOffset() { return (int) dependenciesOffsetField.getValue(addr); }
   private int getHandlerTableOffset() { return (int) handlerTableOffsetField.getValue(addr); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/RuntimeBlob.java	Tue Apr 26 10:28:51 2016 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.code;
+
+import java.util.*;
+
+import sun.jvm.hotspot.compiler.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class RuntimeBlob extends CodeBlob {
+
+  // Only used by server compiler on x86; computed over in SA rather
+  // than relying on computation in target VM
+  private static final int     NOT_YET_COMPUTED = -2;
+  private static final int     UNDEFINED        = -1;
+  private              int     linkOffset       = NOT_YET_COMPUTED;
+
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static void initialize(TypeDataBase db) {
+    Type type = db.lookupType("RuntimeBlob");
+  }
+
+  public RuntimeBlob(Address addr) {
+    super(addr);
+  }
+}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/RuntimeStub.java	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/RuntimeStub.java	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.types.*;
 
-public class RuntimeStub extends CodeBlob {
+public class RuntimeStub extends RuntimeBlob {
   private static CIntegerField callerMustGCArgumentsField;
 
   static {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/SingletonBlob.java	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/SingletonBlob.java	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.types.*;
 
-public class SingletonBlob extends CodeBlob {
+public class SingletonBlob extends RuntimeBlob {
   static {
     VM.registerVMInitializedObserver(new Observer() {
         public void update(Observable o, Object data) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Tue Apr 26 10:28:51 2016 +0200
@@ -1230,7 +1230,7 @@
     @HotSpotVMField(name = "Method::_method_counters", type = "MethodCounters*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodCountersOffset;
     @HotSpotVMField(name = "Method::_method_data", type = "MethodData*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOffset;
     @HotSpotVMField(name = "Method::_from_compiled_entry", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable public int methodCompiledEntryOffset;
-    @HotSpotVMField(name = "Method::_code", type = "nmethod*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodCodeOffset;
+    @HotSpotVMField(name = "Method::_code", type = "CompiledMethod*", get = HotSpotVMField.Type.OFFSET) @Stable public int methodCodeOffset;
 
     @HotSpotVMConstant(name = "Method::_jfr_towrite") @Stable public int methodFlagsJfrTowrite;
     @HotSpotVMConstant(name = "Method::_caller_sensitive") @Stable public int methodFlagsCallerSensitive;
--- a/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os/bsd/dtrace/generateJvmOffsets.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -256,8 +256,9 @@
 
   GEN_OFFS(CodeBlob, _name);
   GEN_OFFS(CodeBlob, _header_size);
-  GEN_OFFS(CodeBlob, _content_offset);
-  GEN_OFFS(CodeBlob, _code_offset);
+  GEN_OFFS(CodeBlob, _content_begin);
+  GEN_OFFS(CodeBlob, _code_begin);
+  GEN_OFFS(CodeBlob, _code_end);
   GEN_OFFS(CodeBlob, _data_offset);
   GEN_OFFS(CodeBlob, _frame_size);
   printf("\n");
@@ -265,10 +266,10 @@
   GEN_OFFS(nmethod, _method);
   GEN_OFFS(nmethod, _dependencies_offset);
   GEN_OFFS(nmethod, _metadata_offset);
-  GEN_OFFS(nmethod, _scopes_data_offset);
+  GEN_OFFS(nmethod, _scopes_data_begin);
   GEN_OFFS(nmethod, _scopes_pcs_offset);
   GEN_OFFS(nmethod, _handler_table_offset);
-  GEN_OFFS(nmethod, _deoptimize_offset);
+  GEN_OFFS(nmethod, _deopt_handler_begin);
   GEN_OFFS(nmethod, _orig_pc_offset);
 
   GEN_OFFS(PcDesc, _pc_offset);
--- a/hotspot/src/os/bsd/dtrace/libjvm_db.c	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os/bsd/dtrace/libjvm_db.c	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -124,10 +124,10 @@
   uint64_t pc_desc;
 
   int32_t  orig_pc_offset;      /* _orig_pc_offset */
-  int32_t  instrs_beg;          /* _code_offset */
-  int32_t  instrs_end;
-  int32_t  deopt_beg;           /* _deoptimize_offset */
-  int32_t  scopes_data_beg;     /* _scopes_data_offset */
+  uint64_t  instrs_beg;          /* _code_offset */
+  uint64_t  instrs_end;
+  uint64_t  deopt_beg;           /* _deoptimize_offset */
+  uint64_t  scopes_data_beg;     /* _scopes_data_offset */
   int32_t  scopes_data_end;
   int32_t  metadata_beg;        /* _metadata_offset */
   int32_t  metadata_end;
@@ -617,11 +617,12 @@
       fprintf(stderr, "\t nmethod_info: BEGIN \n");
 
   /* Instructions */
-  err = ps_pread(J->P, nm + OFFSET_CodeBlob_code_offset, &N->instrs_beg, SZ32);
+  err = read_pointer(J, base + OFFSET_VMStructEntryaddress, &vmp->address);
+  err = read_pointer(J, nm + OFFSET_CodeBlob_code_begin, &N->instrs_beg);
   CHECK_FAIL(err);
-  err = ps_pread(J->P, nm + OFFSET_CodeBlob_data_offset, &N->instrs_end, SZ32);
+  err = read_pointer(J, nm + OFFSET_CodeBlob_code_end, &N->instrs_end);
   CHECK_FAIL(err);
-  err = ps_pread(J->P, nm + OFFSET_nmethod_deoptimize_offset, &N->deopt_beg, SZ32);
+  err = read_pointer(J, nm + OFFSET_nmethod_deopt_handler_begin, &N->deopt_beg);
   CHECK_FAIL(err);
   err = ps_pread(J->P, nm + OFFSET_nmethod_orig_pc_offset, &N->orig_pc_offset, SZ32);
   CHECK_FAIL(err);
@@ -639,7 +640,7 @@
   CHECK_FAIL(err);
 
   /* scopes_data */
-  err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->scopes_data_beg, SZ32);
+  err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_begin, &N->scopes_data_beg, POINTER_SIZE);
   CHECK_FAIL(err);
 
   if (debug > 2 ) {
@@ -868,7 +869,7 @@
   err = ps_pread(N->J->P, pc_desc + OFFSET_PcDesc_pc_offset, &pc_offset, SZ32);
   CHECK_FAIL(err);
 
-  *real_pc = N->nm + N->instrs_beg + pc_offset;
+  *real_pc = N->instrs_beg + pc_offset;
   if (debug > 2) {
       fprintf(stderr, "\t\t get_real_pc: pc_offset: %lx, real_pc: %llx\n",
                        pc_offset, *real_pc);
@@ -942,7 +943,7 @@
       fprintf(stderr, "\t\t scope_desc_at: BEGIN \n");
   }
 
-  buffer = N->nm + N->scopes_data_beg + decode_offset;
+  buffer = N->scopes_data_beg + decode_offset;
 
   err = raw_read_int(N->J, &buffer, &vf->sender_decode_offset);
   CHECK_FAIL(err);
@@ -1052,11 +1053,11 @@
   CHECK_FAIL(err);
   if (debug) {
       fprintf(stderr, "name_for_nmethod: pc: %#llx, deopt_pc:  %#llx\n",
-              pc, N->nm + N->deopt_beg);
+              pc, N->deopt_beg);
   }
 
   /* check for a deoptimized frame */
-  if ( pc == N->nm + N->deopt_beg) {
+  if ( pc == N->deopt_beg) {
     uint64_t base;
     if (debug) {
         fprintf(stderr, "name_for_nmethod: found deoptimized frame\n");
--- a/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -251,8 +251,9 @@
 
   GEN_OFFS(CodeBlob, _name);
   GEN_OFFS(CodeBlob, _header_size);
-  GEN_OFFS(CodeBlob, _content_offset);
-  GEN_OFFS(CodeBlob, _code_offset);
+  GEN_OFFS(CodeBlob, _content_begin);
+  GEN_OFFS(CodeBlob, _code_begin);
+  GEN_OFFS(CodeBlob, _code_end);
   GEN_OFFS(CodeBlob, _data_offset);
   GEN_OFFS(CodeBlob, _frame_size);
   printf("\n");
@@ -260,10 +261,10 @@
   GEN_OFFS(nmethod, _method);
   GEN_OFFS(nmethod, _dependencies_offset);
   GEN_OFFS(nmethod, _metadata_offset);
-  GEN_OFFS(nmethod, _scopes_data_offset);
+  GEN_OFFS(nmethod, _scopes_data_begin);
   GEN_OFFS(nmethod, _scopes_pcs_offset);
   GEN_OFFS(nmethod, _handler_table_offset);
-  GEN_OFFS(nmethod, _deoptimize_offset);
+  GEN_OFFS(nmethod, _deopt_handler_begin);
   GEN_OFFS(nmethod, _orig_pc_offset);
 
   GEN_OFFS(PcDesc, _pc_offset);
--- a/hotspot/src/os/solaris/dtrace/libjvm_db.c	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os/solaris/dtrace/libjvm_db.c	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -124,10 +124,10 @@
   uint64_t pc_desc;
 
   int32_t  orig_pc_offset;      /* _orig_pc_offset */
-  int32_t  instrs_beg;          /* _code_offset */
-  int32_t  instrs_end;
-  int32_t  deopt_beg;           /* _deoptimize_offset */
-  int32_t  scopes_data_beg;     /* _scopes_data_offset */
+  uint64_t  instrs_beg;          /* _code_offset */
+  uint64_t  instrs_end;
+  uint64_t  deopt_beg;           /* _deoptimize_offset */
+  uint64_t  scopes_data_beg;     /* _scopes_data_begin */
   int32_t  scopes_data_end;
   int32_t  metadata_beg;        /* _metadata_offset */
   int32_t  metadata_end;
@@ -617,11 +617,11 @@
       fprintf(stderr, "\t nmethod_info: BEGIN \n");
 
   /* Instructions */
-  err = ps_pread(J->P, nm + OFFSET_CodeBlob_code_offset, &N->instrs_beg, SZ32);
+  err = read_pointer(J, nm + OFFSET_CodeBlob_code_begin, &N->instrs_beg);
   CHECK_FAIL(err);
-  err = ps_pread(J->P, nm + OFFSET_CodeBlob_data_offset, &N->instrs_end, SZ32);
+  err = read_pointer(J, nm + OFFSET_CodeBlob_code_end, &N->instrs_end);
   CHECK_FAIL(err);
-  err = ps_pread(J->P, nm + OFFSET_nmethod_deoptimize_offset, &N->deopt_beg, SZ32);
+  err = read_pointer(J, nm + OFFSET_nmethod_deopt_handler_begin, &N->deopt_beg);
   CHECK_FAIL(err);
   err = ps_pread(J->P, nm + OFFSET_nmethod_orig_pc_offset, &N->orig_pc_offset, SZ32);
   CHECK_FAIL(err);
@@ -629,7 +629,7 @@
   /* Metadata */
   err = ps_pread(J->P, nm + OFFSET_nmethod_metadata_offset, &N->metadata_beg, SZ32);
   CHECK_FAIL(err);
-  err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->metadata_end, SZ32);
+  err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_begin, &N->metadata_end, SZ32);
   CHECK_FAIL(err);
 
   /* scopes_pcs */
@@ -639,7 +639,7 @@
   CHECK_FAIL(err);
 
   /* scopes_data */
-  err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->scopes_data_beg, SZ32);
+  err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_begin, &N->scopes_data_beg, POINTER_SIZE);
   CHECK_FAIL(err);
 
   if (debug > 2 ) {
@@ -868,7 +868,7 @@
   err = ps_pread(N->J->P, pc_desc + OFFSET_PcDesc_pc_offset, &pc_offset, SZ32);
   CHECK_FAIL(err);
 
-  *real_pc = N->nm + N->instrs_beg + pc_offset;
+  *real_pc = N->instrs_beg + pc_offset;
   if (debug > 2) {
       fprintf(stderr, "\t\t get_real_pc: pc_offset: %lx, real_pc: %llx\n",
                        pc_offset, *real_pc);
@@ -942,7 +942,7 @@
       fprintf(stderr, "\t\t scope_desc_at: BEGIN \n");
   }
 
-  buffer = N->nm + N->scopes_data_beg + decode_offset;
+  buffer = N->scopes_data_beg + decode_offset;
 
   err = raw_read_int(N->J, &buffer, &vf->sender_decode_offset);
   CHECK_FAIL(err);
@@ -1052,11 +1052,11 @@
   CHECK_FAIL(err);
   if (debug) {
       fprintf(stderr, "name_for_nmethod: pc: %#llx, deopt_pc:  %#llx\n",
-              pc, N->nm + N->deopt_beg);
+              pc, N->deopt_beg);
   }
 
   /* check for a deoptimized frame */
-  if ( pc == N->nm + N->deopt_beg) {
+  if ( pc == N->deopt_beg) {
     uint64_t base;
     if (debug) {
         fprintf(stderr, "name_for_nmethod: found deoptimized frame\n");
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -390,7 +390,7 @@
         // BugId 4454115: A read from a MappedByteBuffer can fault here if the
         // underlying file has been truncated. Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
-        nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
+        CompiledMethod* nm = cb->as_compiled_method_or_null();
         if (nm != NULL && nm->has_unsafe_access()) {
           // We don't really need a stub here! Just set the pending exeption and
           // continue at the next instruction after the faulting read. Returning
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -582,7 +582,7 @@
         // here if the underlying file has been truncated.
         // Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
-        nmethod* nm = (cb != NULL && cb->is_nmethod()) ? (nmethod*)cb : NULL;
+        CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
         if (nm != NULL && nm->has_unsafe_access()) {
           stub = StubRoutines::handler_for_unsafe_access();
         }
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -385,7 +385,7 @@
         // here if the underlying file has been truncated.
         // Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
-        nmethod* nm = (cb != NULL && cb->is_nmethod()) ? (nmethod*)cb : NULL;
+        CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
         if (nm != NULL && nm->has_unsafe_access()) {
           stub = handle_unsafe_access(thread, pc);
         }
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -315,7 +315,7 @@
                ((NativeInstruction*)pc)->is_safepoint_poll() &&
                CodeCache::contains((void*) pc) &&
                ((cb = CodeCache::find_blob(pc)) != NULL) &&
-               cb->is_nmethod()) {
+               cb->is_compiled()) {
         if (TraceTraps) {
           tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (SIGSEGV)", p2i(pc));
         }
@@ -364,7 +364,7 @@
         // BugId 4454115: A read from a MappedByteBuffer can fault here if the
         // underlying file has been truncated. Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
-        nmethod* nm = (cb != NULL && cb->is_nmethod()) ? (nmethod*)cb : NULL;
+        CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
         if (nm != NULL && nm->has_unsafe_access()) {
           // We don't really need a stub here! Just set the pending exeption and
           // continue at the next instruction after the faulting read. Returning
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -438,7 +438,7 @@
   // here if the underlying file has been truncated.
   // Do not crash the VM in such a case.
   CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
-  nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
+  CompiledMethod* nm = cb->as_compiled_method_or_null();
   if (nm != NULL && nm->has_unsafe_access()) {
     *stub = StubRoutines::handler_for_unsafe_access();
     return true;
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -418,7 +418,7 @@
         // here if the underlying file has been truncated.
         // Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
-        nmethod* nm = (cb != NULL && cb->is_nmethod()) ? (nmethod*)cb : NULL;
+        CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
         if (nm != NULL && nm->has_unsafe_access()) {
           stub = StubRoutines::handler_for_unsafe_access();
         }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -478,7 +478,7 @@
         // here if the underlying file has been truncated.
         // Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
-        nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
+        CompiledMethod* nm = cb->as_compiled_method_or_null();
         if (nm != NULL && nm->has_unsafe_access()) {
           stub = StubRoutines::handler_for_unsafe_access();
         }
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -518,7 +518,7 @@
         // Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         if (cb != NULL) {
-          nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
+          CompiledMethod* nm = cb->as_compiled_method_or_null();
           if (nm != NULL && nm->has_unsafe_access()) {
             stub = StubRoutines::handler_for_unsafe_access();
           }
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -604,7 +604,7 @@
 
 
 
-csize_t CodeBuffer::total_offset_of(CodeSection* cs) const {
+csize_t CodeBuffer::total_offset_of(const CodeSection* cs) const {
   csize_t size_so_far = 0;
   for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
     const CodeSection* cur_cs = code_section(n);
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -468,9 +468,11 @@
   // construction.
   void initialize(csize_t code_size, csize_t locs_size);
 
-  CodeSection* consts()            { return &_consts; }
-  CodeSection* insts()             { return &_insts; }
-  CodeSection* stubs()             { return &_stubs; }
+  CodeSection* consts() { return &_consts; }
+  CodeSection* insts() { return &_insts; }
+  CodeSection* stubs() { return &_stubs; }
+
+  const CodeSection* insts() const { return &_insts; }
 
   // present sections in order; return NULL at end; consts is #0, etc.
   CodeSection* code_section(int n) {
@@ -547,7 +549,7 @@
 
   // Combined offset (relative to start of first section) of given
   // section, as eventually found in the final CodeBlob.
-  csize_t total_offset_of(CodeSection* cs) const;
+  csize_t total_offset_of(const CodeSection* cs) const;
 
   // allocated size of all relocation data, including index, rounded up
   csize_t total_relocation_size() const;
--- a/hotspot/src/share/vm/ci/ciEnv.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1055,14 +1055,14 @@
       if (entry_bci == InvocationEntryBci) {
         if (TieredCompilation) {
           // If there is an old version we're done with it
-          nmethod* old = method->code();
+          CompiledMethod* old = method->code();
           if (TraceMethodReplacement && old != NULL) {
             ResourceMark rm;
             char *method_name = method->name_and_sig_as_C_string();
             tty->print_cr("Replacing method %s", method_name);
           }
           if (old != NULL) {
-            old->make_not_entrant();
+            old->make_not_used();
           }
         }
         if (TraceNMethodInstalls) {
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1115,7 +1115,7 @@
 int ciMethod::comp_level() {
   check_is_loaded();
   VM_ENTRY_MARK;
-  nmethod* nm = get_Method()->code();
+  CompiledMethod* nm = get_Method()->code();
   if (nm != NULL) return nm->comp_level();
   return 0;
 }
@@ -1150,7 +1150,7 @@
 int ciMethod::instructions_size() {
   if (_instructions_size == -1) {
     GUARDED_VM_ENTRY(
-                     nmethod* code = get_Method()->code();
+                     CompiledMethod* code = get_Method()->code();
                      if (code != NULL && (code->comp_level() == CompLevel_full_optimization)) {
                        _instructions_size = code->insts_end() - code->verified_entry_point();
                      } else {
@@ -1165,7 +1165,7 @@
 // ciMethod::log_nmethod_identity
 void ciMethod::log_nmethod_identity(xmlStream* log) {
   GUARDED_VM_ENTRY(
-    nmethod* code = get_Method()->code();
+    CompiledMethod* code = get_Method()->code();
     if (code != NULL) {
       code->log_identity(log);
     }
--- a/hotspot/src/share/vm/ci/ciReplay.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -546,7 +546,7 @@
       }
     }
     // Make sure the existence of a prior compile doesn't stop this one
-    nmethod* nm = (entry_bci != InvocationEntryBci) ? method->lookup_osr_nmethod_for(entry_bci, comp_level, true) : method->code();
+    CompiledMethod* nm = (entry_bci != InvocationEntryBci) ? method->lookup_osr_nmethod_for(entry_bci, comp_level, true) : method->code();
     if (nm != NULL) {
       nm->make_not_entrant();
     }
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1651,7 +1651,7 @@
               }
               if (TieredCompilation && TieredStopAtLevel >= CompLevel_full_optimization) {
                 // Clobber the first compile and force second tier compilation
-                nmethod* nm = m->code();
+                CompiledMethod* nm = m->code();
                 if (nm != NULL && !m->is_method_handle_intrinsic()) {
                   // Throw out the code so that the code cache doesn't fill up
                   nm->make_not_entrant();
@@ -1670,7 +1670,7 @@
               tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string());
             }
 
-            nmethod* nm = m->code();
+            CompiledMethod* nm = m->code();
             if (nm != NULL && !m->is_method_handle_intrinsic()) {
               // Throw out the code so that the code cache doesn't fill up
               nm->make_not_entrant();
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1798,7 +1798,7 @@
         // Neither sourcename nor linenumber
         sprintf(buf + (int)strlen(buf), "Unknown Source)");
       }
-      nmethod* nm = method->code();
+      CompiledMethod* nm = method->code();
       if (WizardMode && nm != NULL) {
         sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm);
       }
@@ -1920,7 +1920,7 @@
   int total_count = 0;
   RegisterMap map(thread, false);
   int decode_offset = 0;
-  nmethod* nm = NULL;
+  CompiledMethod* nm = NULL;
   bool skip_fillInStackTrace_check = false;
   bool skip_throwableInit_check = false;
   bool skip_hidden = !ShowHiddenFrames;
@@ -1948,10 +1948,10 @@
         // HMMM QQQ might be nice to have frame return nm as NULL if cb is non-NULL
         // but non nmethod
         fr = fr.sender(&map);
-        if (cb == NULL || !cb->is_nmethod()) {
+        if (cb == NULL || !cb->is_compiled()) {
           continue;
         }
-        nm = (nmethod*)cb;
+        nm = cb->as_compiled_method();
         if (nm->method()->is_native()) {
           method = nm->method();
           bci = 0;
--- a/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,7 +56,7 @@
 
   if (redefinition_walk) {
     Threads::metadata_do(Metadata::mark_on_stack);
-    CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
+    CodeCache::metadata_do(Metadata::mark_on_stack);
     CompileBroker::mark_on_stack();
     JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
     ThreadService::metadata_do(Metadata::mark_on_stack);
--- a/hotspot/src/share/vm/code/codeBlob.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/codeBlob.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -65,12 +65,67 @@
   return size;
 }
 
+CodeBlob::CodeBlob(const char* name, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments) :
+  _name(name),
+  _size(layout.size()),
+  _header_size(layout.header_size()),
+  _frame_complete_offset(frame_complete_offset),
+  _data_offset(layout.data_offset()),
+  _frame_size(frame_size),
+  _strings(CodeStrings()),
+  _oop_maps(oop_maps),
+  _caller_must_gc_arguments(caller_must_gc_arguments),
+  _code_begin(layout.code_begin()),
+  _code_end(layout.code_end()),
+  _data_end(layout.data_end()),
+  _relocation_begin(layout.relocation_begin()),
+  _relocation_end(layout.relocation_end()),
+  _content_begin(layout.content_begin())
+{
+  assert(layout.size()        == round_to(layout.size(),        oopSize), "unaligned size");
+  assert(layout.header_size() == round_to(layout.header_size(), oopSize), "unaligned size");
+  assert(layout.relocation_size() == round_to(layout.relocation_size(), oopSize), "unaligned size");
+  assert(layout.code_end() == layout.content_end(), "must be the same - see code_end()");
+#ifdef COMPILER1
+  // probably wrong for tiered
+  assert(_frame_size >= -1, "must use frame size or -1 for runtime stubs");
+#endif // COMPILER1
+}
+
+CodeBlob::CodeBlob(const char* name, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments) :
+  _name(name),
+  _size(layout.size()),
+  _header_size(layout.header_size()),
+  _frame_complete_offset(frame_complete_offset),
+  _data_offset(layout.data_offset()),
+  _frame_size(frame_size),
+  _strings(CodeStrings()),
+  _caller_must_gc_arguments(caller_must_gc_arguments),
+  _code_begin(layout.code_begin()),
+  _code_end(layout.code_end()),
+  _data_end(layout.data_end()),
+  _relocation_begin(layout.relocation_begin()),
+  _relocation_end(layout.relocation_end()),
+  _content_begin(layout.content_begin())
+{
+  assert(_size        == round_to(_size,        oopSize), "unaligned size");
+  assert(_header_size == round_to(_header_size, oopSize), "unaligned size");
+  assert(_data_offset <= _size, "codeBlob is too small");
+  assert(layout.code_end() == layout.content_end(), "must be the same - see code_end()");
+
+  set_oop_maps(oop_maps);
+#ifdef COMPILER1
+  // probably wrong for tiered
+  assert(_frame_size >= -1, "must use frame size or -1 for runtime stubs");
+#endif // COMPILER1
+}
+
 
 // Creates a simple CodeBlob. Sets up the size of the different regions.
-CodeBlob::CodeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size) {
-  assert(size        == round_to(size,        oopSize), "unaligned size");
+RuntimeBlob::RuntimeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size)
+  : CodeBlob(name, CodeBlobLayout((address) this, size, header_size, locs_size, size), frame_complete, 0, NULL, false /* caller_must_gc_arguments */)
+{
   assert(locs_size   == round_to(locs_size,   oopSize), "unaligned size");
-  assert(header_size == round_to(header_size, oopSize), "unaligned size");
   assert(!UseRelocIndex, "no space allocated for reloc index yet");
 
   // Note: If UseRelocIndex is enabled, there needs to be (at least) one
@@ -79,55 +134,31 @@
   //       mentation is not easily understandable and thus it is not clear
   //       what exactly the format is supposed to be. For now, we just turn
   //       off the use of this table (gri 7/6/2000).
-
-  _name                  = name;
-  _size                  = size;
-  _frame_complete_offset = frame_complete;
-  _header_size           = header_size;
-  _relocation_size       = locs_size;
-  _content_offset        = align_code_offset(header_size + _relocation_size);
-  _code_offset           = _content_offset;
-  _data_offset           = size;
-  _frame_size            =  0;
-  set_oop_maps(NULL);
-  _strings               = CodeStrings();
 }
 
 
-// Creates a CodeBlob from a CodeBuffer. Sets up the size of the different regions,
+// Creates a RuntimeBlob from a CodeBuffer
 // and copy code and relocation info.
-CodeBlob::CodeBlob(
+RuntimeBlob::RuntimeBlob(
   const char* name,
   CodeBuffer* cb,
   int         header_size,
   int         size,
   int         frame_complete,
   int         frame_size,
-  OopMapSet*  oop_maps
-) {
-  assert(size        == round_to(size,        oopSize), "unaligned size");
-  assert(header_size == round_to(header_size, oopSize), "unaligned size");
-
-  _name                  = name;
-  _size                  = size;
-  _frame_complete_offset = frame_complete;
-  _header_size           = header_size;
-  _relocation_size       = round_to(cb->total_relocation_size(), oopSize);
-  _content_offset        = align_code_offset(header_size + _relocation_size);
-  _code_offset           = _content_offset + cb->total_offset_of(cb->insts());
-  _data_offset           = _content_offset + round_to(cb->total_content_size(), oopSize);
-  assert(_data_offset <= size, "codeBlob is too small");
-  _strings               = CodeStrings();
-
+  OopMapSet*  oop_maps,
+  bool        caller_must_gc_arguments
+) : CodeBlob(name, CodeBlobLayout((address) this, size, header_size, cb), cb, frame_complete, frame_size, oop_maps, caller_must_gc_arguments) {
   cb->copy_code_and_locs_to(this);
-  set_oop_maps(oop_maps);
-  _frame_size = frame_size;
-#ifdef COMPILER1
-  // probably wrong for tiered
-  assert(_frame_size >= -1, "must use frame size or -1 for runtime stubs");
-#endif // COMPILER1
 }
 
+void CodeBlob::flush() {
+  if (_oop_maps) {
+    FREE_C_HEAP_ARRAY(unsigned char, _oop_maps);
+    _oop_maps = NULL;
+  }
+  _strings.free();
+}
 
 void CodeBlob::set_oop_maps(OopMapSet* p) {
   // Danger Will Robinson! This method allocates a big
@@ -140,7 +171,7 @@
 }
 
 
-void CodeBlob::trace_new_stub(CodeBlob* stub, const char* name1, const char* name2) {
+void RuntimeBlob::trace_new_stub(RuntimeBlob* stub, const char* name1, const char* name2) {
   // Do not hold the CodeCache lock during name formatting.
   assert(!CodeCache_lock->owned_by_self(), "release CodeCache before registering the stub");
 
@@ -167,19 +198,9 @@
   MemoryService::track_code_cache_memory_usage();
 }
 
-
-void CodeBlob::flush() {
-  if (_oop_maps) {
-    FREE_C_HEAP_ARRAY(unsigned char, _oop_maps);
-    _oop_maps = NULL;
-  }
-  _strings.free();
-}
-
-
 const ImmutableOopMap* CodeBlob::oop_map_for_return_address(address return_address) {
-  assert(oop_maps() != NULL, "nope");
-  return oop_maps()->find_map_at_offset((intptr_t) return_address - (intptr_t) code_begin());
+  assert(_oop_maps != NULL, "nope");
+  return _oop_maps->find_map_at_offset((intptr_t) return_address - (intptr_t) code_begin());
 }
 
 void CodeBlob::print_code() {
@@ -193,7 +214,7 @@
 
 
 BufferBlob::BufferBlob(const char* name, int size)
-: CodeBlob(name, sizeof(BufferBlob), size, CodeOffsets::frame_never_safe, /*locs_size:*/ 0)
+: RuntimeBlob(name, sizeof(BufferBlob), size, CodeOffsets::frame_never_safe, /*locs_size:*/ 0)
 {}
 
 BufferBlob* BufferBlob::create(const char* name, int buffer_size) {
@@ -203,7 +224,7 @@
   unsigned int size = sizeof(BufferBlob);
   CodeCacheExtensions::size_blob(name, &buffer_size);
   // align the size to CodeEntryAlignment
-  size = align_code_offset(size);
+  size = CodeBlob::align_code_offset(size);
   size += round_to(buffer_size, oopSize);
   assert(name != NULL, "must provide a name");
   {
@@ -218,14 +239,14 @@
 
 
 BufferBlob::BufferBlob(const char* name, int size, CodeBuffer* cb)
-  : CodeBlob(name, cb, sizeof(BufferBlob), size, CodeOffsets::frame_never_safe, 0, NULL)
+  : RuntimeBlob(name, cb, sizeof(BufferBlob), size, CodeOffsets::frame_never_safe, 0, NULL)
 {}
 
 BufferBlob* BufferBlob::create(const char* name, CodeBuffer* cb) {
   ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
 
   BufferBlob* blob = NULL;
-  unsigned int size = allocation_size(cb, sizeof(BufferBlob));
+  unsigned int size = CodeBlob::allocation_size(cb, sizeof(BufferBlob));
   assert(name != NULL, "must provide a name");
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
@@ -246,7 +267,7 @@
   blob->flush();
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    CodeCache::free((CodeBlob*)blob);
+    CodeCache::free((RuntimeBlob*)blob);
   }
   // Track memory usage statistic after releasing CodeCache_lock
   MemoryService::track_code_cache_memory_usage();
@@ -265,7 +286,7 @@
   ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
 
   AdapterBlob* blob = NULL;
-  unsigned int size = allocation_size(cb, sizeof(AdapterBlob));
+  unsigned int size = CodeBlob::allocation_size(cb, sizeof(AdapterBlob));
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     blob = new (size) AdapterBlob(size, cb);
@@ -287,7 +308,7 @@
   unsigned int size = sizeof(MethodHandlesAdapterBlob);
   CodeCacheExtensions::size_blob("MethodHandles adapters", &buffer_size);
   // align the size to CodeEntryAlignment
-  size = align_code_offset(size);
+  size = CodeBlob::align_code_offset(size);
   size += round_to(buffer_size, oopSize);
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
@@ -314,12 +335,10 @@
   OopMapSet*  oop_maps,
   bool        caller_must_gc_arguments
 )
-: CodeBlob(name, cb, sizeof(RuntimeStub), size, frame_complete, frame_size, oop_maps)
+: RuntimeBlob(name, cb, sizeof(RuntimeStub), size, frame_complete, frame_size, oop_maps, caller_must_gc_arguments)
 {
-  _caller_must_gc_arguments = caller_must_gc_arguments;
 }
 
-
 RuntimeStub* RuntimeStub::new_runtime_stub(const char* stub_name,
                                            CodeBuffer* cb,
                                            int frame_complete,
@@ -332,7 +351,7 @@
   if (!CodeCacheExtensions::skip_code_generation()) {
     // bypass useless code generation
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    unsigned int size = allocation_size(cb, sizeof(RuntimeStub));
+    unsigned int size = CodeBlob::allocation_size(cb, sizeof(RuntimeStub));
     stub = new (size) RuntimeStub(stub_name, cb, size, frame_complete, frame_size, oop_maps, caller_must_gc_arguments);
   }
   stub = (RuntimeStub*) CodeCacheExtensions::handle_generated_blob(stub, stub_name);
@@ -392,7 +411,7 @@
   ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    unsigned int size = allocation_size(cb, sizeof(DeoptimizationBlob));
+    unsigned int size = CodeBlob::allocation_size(cb, sizeof(DeoptimizationBlob));
     blob = new (size) DeoptimizationBlob(cb,
                                          size,
                                          oop_maps,
@@ -431,7 +450,7 @@
   ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    unsigned int size = allocation_size(cb, sizeof(UncommonTrapBlob));
+    unsigned int size = CodeBlob::allocation_size(cb, sizeof(UncommonTrapBlob));
     blob = new (size) UncommonTrapBlob(cb, size, oop_maps, frame_size);
   }
 
@@ -467,7 +486,7 @@
   ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    unsigned int size = allocation_size(cb, sizeof(ExceptionBlob));
+    unsigned int size = CodeBlob::allocation_size(cb, sizeof(ExceptionBlob));
     blob = new (size) ExceptionBlob(cb, size, oop_maps, frame_size);
   }
 
@@ -502,7 +521,7 @@
   ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    unsigned int size = allocation_size(cb, sizeof(SafepointBlob));
+    unsigned int size = CodeBlob::allocation_size(cb, sizeof(SafepointBlob));
     blob = new (size) SafepointBlob(cb, size, oop_maps, frame_size);
   }
 
@@ -515,10 +534,6 @@
 //----------------------------------------------------------------------------------------------------
 // Verification and printing
 
-void CodeBlob::verify() {
-  ShouldNotReachHere();
-}
-
 void CodeBlob::print_on(outputStream* st) const {
   st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this));
   st->print_cr("Framesize: %d", _frame_size);
@@ -528,12 +543,16 @@
   st->print_cr("[CodeBlob]");
 }
 
+void RuntimeBlob::verify() {
+  ShouldNotReachHere();
+}
+
 void BufferBlob::verify() {
   // unimplemented
 }
 
 void BufferBlob::print_on(outputStream* st) const {
-  CodeBlob::print_on(st);
+  RuntimeBlob::print_on(st);
   print_value_on(st);
 }
 
@@ -547,10 +566,10 @@
 
 void RuntimeStub::print_on(outputStream* st) const {
   ttyLocker ttyl;
-  CodeBlob::print_on(st);
+  RuntimeBlob::print_on(st);
   st->print("Runtime Stub (" INTPTR_FORMAT "): ", p2i(this));
   st->print_cr("%s", name());
-  Disassembler::decode((CodeBlob*)this, st);
+  Disassembler::decode((RuntimeBlob*)this, st);
 }
 
 void RuntimeStub::print_value_on(outputStream* st) const {
@@ -563,9 +582,9 @@
 
 void SingletonBlob::print_on(outputStream* st) const {
   ttyLocker ttyl;
-  CodeBlob::print_on(st);
+  RuntimeBlob::print_on(st);
   st->print_cr("%s", name());
-  Disassembler::decode((CodeBlob*)this, st);
+  Disassembler::decode((RuntimeBlob*)this, st);
 }
 
 void SingletonBlob::print_value_on(outputStream* st) const {
--- a/hotspot/src/share/vm/code/codeBlob.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/codeBlob.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,12 +45,14 @@
 
 // CodeBlob - superclass for all entries in the CodeCache.
 //
-// Suptypes are:
-//   nmethod            : Compiled Java methods (include method that calls to native code)
-//   RuntimeStub        : Call to VM runtime methods
-//   DeoptimizationBlob : Used for deoptimizatation
-//   ExceptionBlob      : Used for stack unrolling
-//   SafepointBlob      : Used to handle illegal instruction exceptions
+// Subtypes are:
+//   CompiledMethod       : Compiled Java methods (include method that calls to native code)
+//     nmethod            : JIT Compiled Java methods
+//   RuntimeBlob          : Non-compiled method code; generated glue code
+//     RuntimeStub        : Call to VM runtime methods
+//     DeoptimizationBlob : Used for deoptimization
+//     ExceptionBlob      : Used for stack unrolling
+//     SafepointBlob      : Used to handle illegal instruction exceptions
 //
 //
 // Layout:
@@ -59,90 +61,79 @@
 //   - content space
 //     - instruction space
 //   - data space
-class DeoptimizationBlob;
+
+
+class CodeBlobLayout;
 
 class CodeBlob VALUE_OBJ_CLASS_SPEC {
-
   friend class VMStructs;
   friend class JVMCIVMStructs;
   friend class CodeCacheDumper;
 
- private:
+protected:
   const char* _name;
   int        _size;                              // total size of CodeBlob in bytes
   int        _header_size;                       // size of header (depends on subclass)
-  int        _relocation_size;                   // size of relocation
-  int        _content_offset;                    // offset to where content region begins (this includes consts, insts, stubs)
-  int        _code_offset;                       // offset to where instructions region begins (this includes insts, stubs)
   int        _frame_complete_offset;             // instruction offsets in [0.._frame_complete_offset) have
                                                  // not finished setting up their frame. Beware of pc's in
                                                  // that range. There is a similar range(s) on returns
                                                  // which we don't detect.
   int        _data_offset;                       // offset to where data region begins
   int        _frame_size;                        // size of stack frame
+
+  address    _code_begin;
+  address    _code_end;
+  address    _content_begin;                     // address to where content region begins (this includes consts, insts, stubs)
+                                                 // address    _content_end - not required, for all CodeBlobs _code_end == _content_end for now
+  address    _data_end;
+  address    _relocation_begin;
+  address    _relocation_end;
+
   ImmutableOopMapSet* _oop_maps;                 // OopMap for this CodeBlob
-  CodeStrings _strings;
+  bool                _caller_must_gc_arguments;
+  CodeStrings         _strings;
 
- public:
+  CodeBlob(const char* name, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);
+  CodeBlob(const char* name, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments);
+public:
   // Returns the space needed for CodeBlob
   static unsigned int allocation_size(CodeBuffer* cb, int header_size);
   static unsigned int align_code_offset(int offset);
 
-  // Creation
-  // a) simple CodeBlob
-  // frame_complete is the offset from the beginning of the instructions
-  // to where the frame setup (from stackwalk viewpoint) is complete.
-  CodeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size);
-
-  // b) full CodeBlob
-  CodeBlob(
-    const char* name,
-    CodeBuffer* cb,
-    int         header_size,
-    int         size,
-    int         frame_complete,
-    int         frame_size,
-    OopMapSet*  oop_maps
-  );
-
   // Deletion
-  void flush();
+  virtual void flush();
 
   // Typing
-  virtual bool is_buffer_blob() const            { return false; }
-  virtual bool is_nmethod() const                { return false; }
-  virtual bool is_runtime_stub() const           { return false; }
-  virtual bool is_deoptimization_stub() const    { return false; }
-  virtual bool is_uncommon_trap_stub() const     { return false; }
-  virtual bool is_exception_stub() const         { return false; }
+  virtual bool is_buffer_blob() const                 { return false; }
+  virtual bool is_nmethod() const                     { return false; }
+  virtual bool is_runtime_stub() const                { return false; }
+  virtual bool is_deoptimization_stub() const         { return false; }
+  virtual bool is_uncommon_trap_stub() const          { return false; }
+  virtual bool is_exception_stub() const              { return false; }
   virtual bool is_safepoint_stub() const              { return false; }
   virtual bool is_adapter_blob() const                { return false; }
   virtual bool is_method_handles_adapter_blob() const { return false; }
+  virtual bool is_compiled() const                    { return false; }
 
   virtual bool is_compiled_by_c2() const         { return false; }
   virtual bool is_compiled_by_c1() const         { return false; }
   virtual bool is_compiled_by_jvmci() const      { return false; }
 
   // Casting
-  nmethod* as_nmethod_or_null()                  { return is_nmethod() ? (nmethod*) this : NULL; }
+  nmethod* as_nmethod_or_null()                { return is_nmethod() ? (nmethod*) this : NULL; }
+  nmethod* as_nmethod()                        { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; }
+  CompiledMethod* as_compiled_method_or_null() { return is_compiled() ? (CompiledMethod*) this : NULL; }
+  CompiledMethod* as_compiled_method()         { assert(is_compiled(), "must be compiled"); return (CompiledMethod*) this; }
 
   // Boundaries
-  address    header_begin() const                { return (address)    this; }
-  address    header_end() const                  { return ((address)   this) + _header_size; };
-  relocInfo* relocation_begin() const            { return (relocInfo*) header_end(); };
-  relocInfo* relocation_end() const              { return (relocInfo*)(header_end()   + _relocation_size); }
-  address    content_begin() const               { return (address)    header_begin() + _content_offset; }
-  address    content_end() const                 { return (address)    header_begin() + _data_offset; }
-  address    code_begin() const                  { return (address)    header_begin() + _code_offset; }
-  address    code_end() const                    { return (address)    header_begin() + _data_offset; }
-  address    data_begin() const                  { return (address)    header_begin() + _data_offset; }
-  address    data_end() const                    { return (address)    header_begin() + _size; }
-
-  // Offsets
-  int relocation_offset() const                  { return _header_size; }
-  int content_offset() const                     { return _content_offset; }
-  int code_offset() const                        { return _code_offset; }
-  int data_offset() const                        { return _data_offset; }
+  address header_begin() const        { return (address) this; }
+  relocInfo* relocation_begin() const { return (relocInfo*) _relocation_begin; };
+  relocInfo* relocation_end() const   { return (relocInfo*) _relocation_end; }
+  address content_begin() const       { return _content_begin; }
+  address content_end() const         { return _code_end; } // _code_end == _content_end is true for all types of blobs for now, it is also checked in the constructor
+  address code_begin() const          { return _code_begin;    }
+  address code_end() const            { return _code_end; }
+  address data_end() const            { return _data_end;      }
 
   // Sizes
   int size() const                               { return _size; }
@@ -150,17 +141,12 @@
   int relocation_size() const                    { return (address) relocation_end() - (address) relocation_begin(); }
   int content_size() const                       { return           content_end()    -           content_begin();    }
   int code_size() const                          { return           code_end()       -           code_begin();       }
-  int data_size() const                          { return           data_end()       -           data_begin();       }
 
   // Containment
   bool blob_contains(address addr) const         { return header_begin()       <= addr && addr < data_end();       }
-  bool relocation_contains(relocInfo* addr) const{ return relocation_begin()   <= addr && addr < relocation_end(); }
-  bool content_contains(address addr) const      { return content_begin()      <= addr && addr < content_end();    }
   bool code_contains(address addr) const         { return code_begin()         <= addr && addr < code_end();       }
-  bool data_contains(address addr) const         { return data_begin()         <= addr && addr < data_end();       }
-  bool contains(address addr) const              { return content_contains(addr); }
-  bool is_frame_complete_at(address addr) const  { return code_contains(addr) &&
-                                                          addr >= code_begin() + _frame_complete_offset; }
+  bool contains(address addr) const              { return content_begin()      <= addr && addr < content_end();    }
+  bool is_frame_complete_at(address addr) const  { return code_contains(addr) && addr >= code_begin() + _frame_complete_offset; }
 
   // CodeCache support: really only used by the nmethods, but in order to get
   // asserts and certain bookkeeping to work in the CodeCache they are defined
@@ -178,29 +164,26 @@
   ImmutableOopMapSet* oop_maps() const           { return _oop_maps; }
   void set_oop_maps(OopMapSet* p);
   const ImmutableOopMap* oop_map_for_return_address(address return_address);
-  virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f)  { ShouldNotReachHere(); }
+  virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) = 0;
 
   // Frame support
   int  frame_size() const                        { return _frame_size; }
   void set_frame_size(int size)                  { _frame_size = size; }
 
   // Returns true, if the next frame is responsible for GC'ing oops passed as arguments
-  virtual bool caller_must_gc_arguments(JavaThread* thread) const { return false; }
+  bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; }
 
   // Naming
   const char* name() const                       { return _name; }
   void set_name(const char* name)                { _name = name; }
 
   // Debugging
-  virtual void verify();
-  void print() const                             { print_on(tty); }
+  virtual void verify() = 0;
+  virtual void print() const                     { print_on(tty); };
   virtual void print_on(outputStream* st) const;
   virtual void print_value_on(outputStream* st) const;
   void print_code();
 
-  // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.
-  static void trace_new_stub(CodeBlob* blob, const char* name1, const char* name2 = "");
-
   // Print the comment associated with offset on stream, if there is one
   virtual void print_block_comment(outputStream* stream, address block_begin) const {
     intptr_t offset = (intptr_t)(block_begin - code_begin());
@@ -221,11 +204,142 @@
   }
 };
 
+class CodeBlobLayout : public StackObj {
+private:
+  int _size;
+  int _header_size;
+  int _relocation_size;
+  int _content_offset;
+  int _code_offset;
+  int _data_offset;
+  address _code_begin;
+  address _code_end;
+  address _content_begin;
+  address _content_end;
+  address _data_end;
+  address _relocation_begin;
+  address _relocation_end;
+
+public:
+  CodeBlobLayout(address code_begin, address code_end, address content_begin, address content_end, address data_end, address relocation_begin, address relocation_end) :
+    _size(0),
+    _header_size(0),
+    _relocation_size(0),
+    _content_offset(0),
+    _code_offset(0),
+    _data_offset(0),
+    _content_begin(content_begin),
+    _content_end(content_end),
+    _code_begin(code_begin),
+    _code_end(code_end),
+    _data_end(data_end),
+    _relocation_begin(relocation_begin),
+    _relocation_end(relocation_end)
+  {
+  }
+
+  CodeBlobLayout(const address start, int size, int header_size, int relocation_size, int data_offset) :
+    _size(size),
+    _header_size(header_size),
+    _relocation_size(relocation_size),
+    _content_offset(CodeBlob::align_code_offset(_header_size + _relocation_size)),
+    _code_offset(_content_offset),
+    _data_offset(data_offset)
+  {
+    assert(_relocation_size == round_to(_relocation_size, oopSize), "unaligned size");
+
+    _code_begin = (address) start + _code_offset;
+    _code_end = (address) start + _data_offset;
+
+    _content_begin = (address) start + _content_offset;
+    _content_end = (address) start + _data_offset;
+
+    _data_end = (address) start + _size;
+    _relocation_begin = (address) start + _header_size;
+    _relocation_end = _relocation_begin + _relocation_size;
+  }
+
+  CodeBlobLayout(const address start, int size, int header_size, const CodeBuffer* cb) :
+    _size(size),
+    _header_size(header_size),
+    _relocation_size(round_to(cb->total_relocation_size(), oopSize)),
+    _content_offset(CodeBlob::align_code_offset(_header_size + _relocation_size)),
+    _code_offset(_content_offset + cb->total_offset_of(cb->insts())),
+    _data_offset(_content_offset + round_to(cb->total_content_size(), oopSize))
+  {
+    assert(_relocation_size == round_to(_relocation_size, oopSize), "unaligned size");
+
+    _code_begin = (address) start + _code_offset;
+    _code_end = (address) start + _data_offset;
+
+    _content_begin = (address) start + _content_offset;
+    _content_end = (address) start + _data_offset;
+
+    _data_end = (address) start + _size;
+    _relocation_begin = (address) start + _header_size;
+    _relocation_end = _relocation_begin + _relocation_size;
+  }
+
+  int size() const { return _size; }
+  int header_size() const { return _header_size; }
+  int relocation_size() const { return _relocation_size; }
+  int content_offset() const { return _content_offset; }
+  int code_offset() const { return _code_offset; }
+  int data_offset() const { return _data_offset; }
+  address code_begin() const { return _code_begin; }
+  address code_end() const { return _code_end; }
+  address data_end() const { return _data_end; }
+  address relocation_begin() const { return _relocation_begin; }
+  address relocation_end() const { return _relocation_end; }
+  address content_begin() const { return _content_begin; }
+  address content_end() const { return _content_end; }
+};
+
+
+class RuntimeBlob : public CodeBlob {
+  friend class VMStructs;
+ public:
+
+  // Creation
+  // a) simple CodeBlob
+  // frame_complete is the offset from the beginning of the instructions
+  // to where the frame setup (from stackwalk viewpoint) is complete.
+  RuntimeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size);
+
+  // b) full CodeBlob
+  RuntimeBlob(
+    const char* name,
+    CodeBuffer* cb,
+    int         header_size,
+    int         size,
+    int         frame_complete,
+    int         frame_size,
+    OopMapSet*  oop_maps,
+    bool        caller_must_gc_arguments = false
+  );
+
+  // GC support
+  virtual bool is_alive() const                  = 0;
+
+  void verify();
+
+  // OopMap for frame
+  virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f)  { ShouldNotReachHere(); }
+
+  // Debugging
+  void print() const                             { print_on(tty); }
+  virtual void print_on(outputStream* st) const { CodeBlob::print_on(st); }
+  virtual void print_value_on(outputStream* st) const { CodeBlob::print_value_on(st); }
+
+  // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.
+  static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = "");
+};
+
 class WhiteBox;
 //----------------------------------------------------------------------------------------------------
 // BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc.
 
-class BufferBlob: public CodeBlob {
+class BufferBlob: public RuntimeBlob {
   friend class VMStructs;
   friend class AdapterBlob;
   friend class MethodHandlesAdapterBlob;
@@ -293,11 +407,9 @@
 //----------------------------------------------------------------------------------------------------
 // RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
 
-class RuntimeStub: public CodeBlob {
+class RuntimeStub: public RuntimeBlob {
   friend class VMStructs;
  private:
-  bool        _caller_must_gc_arguments;
-
   // Creation support
   RuntimeStub(
     const char* name,
@@ -325,10 +437,7 @@
   // Typing
   bool is_runtime_stub() const                   { return true; }
 
-  // GC support
-  bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; }
-
-  address entry_point()                          { return code_begin(); }
+  address entry_point() const                    { return code_begin(); }
 
   // GC/Verification support
   void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f)  { /* nothing to do */ }
@@ -343,7 +452,7 @@
 //----------------------------------------------------------------------------------------------------
 // Super-class for all blobs that exist in only one instance. Implements default behaviour.
 
-class SingletonBlob: public CodeBlob {
+class SingletonBlob: public RuntimeBlob {
   friend class VMStructs;
 
  protected:
@@ -358,13 +467,15 @@
      int         frame_size,
      OopMapSet*  oop_maps
    )
-   : CodeBlob(name, cb, header_size, size, CodeOffsets::frame_never_safe, frame_size, oop_maps)
+   : RuntimeBlob(name, cb, header_size, size, CodeOffsets::frame_never_safe, frame_size, oop_maps)
   {};
 
   address entry_point()                          { return code_begin(); }
 
   bool is_alive() const                          { return true; }
 
+  // GC/Verification support
+  void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f)  { /* nothing to do */ }
   void verify(); // does nothing
   void print_on(outputStream* st) const;
   void print_value_on(outputStream* st) const;
--- a/hotspot/src/share/vm/code/codeCache.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -561,12 +561,12 @@
 // what you are doing)
 CodeBlob* CodeCache::find_blob_unsafe(void* start) {
   // NMT can walk the stack before code cache is created
-  if (_heaps == NULL || _heaps->is_empty()) return NULL;
-
-  FOR_ALL_HEAPS(heap) {
-    CodeBlob* result = (CodeBlob*) (*heap)->find_start(start);
-    if (result != NULL && result->blob_contains((address)start)) {
-      return result;
+  if (_heaps != NULL && !_heaps->is_empty()) {
+    FOR_ALL_HEAPS(heap) {
+      CodeBlob* result = (CodeBlob*) (*heap)->find_start(start);
+      if (result != NULL && result->blob_contains((address)start)) {
+        return result;
+      }
     }
   }
   return NULL;
@@ -595,11 +595,11 @@
   }
 }
 
-void CodeCache::alive_nmethods_do(void f(nmethod* nm)) {
+void CodeCache::metadata_do(void f(Metadata* m)) {
   assert_locked_or_safepoint(CodeCache_lock);
   NMethodIterator iter;
   while(iter.next_alive()) {
-    f(iter.method());
+    iter.method()->metadata_do(f);
   }
 }
 
@@ -614,7 +614,7 @@
 // Mark nmethods for unloading if they contain otherwise unreachable oops.
 void CodeCache::do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred) {
   assert_locked_or_safepoint(CodeCache_lock);
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
     iter.method()->do_unloading(is_alive, unloading_occurred);
   }
@@ -841,17 +841,18 @@
 void CodeCache::gc_epilogue() {
   assert_locked_or_safepoint(CodeCache_lock);
   NOT_DEBUG(if (needs_cache_clean())) {
-    NMethodIterator iter;
+    CompiledMethodIterator iter;
     while(iter.next_alive()) {
-      nmethod* nm = iter.method();
-      assert(!nm->is_unloaded(), "Tautology");
+      CompiledMethod* cm = iter.method();
+      assert(!cm->is_unloaded(), "Tautology");
       DEBUG_ONLY(if (needs_cache_clean())) {
-        nm->cleanup_inline_caches();
+        cm->cleanup_inline_caches();
       }
-      DEBUG_ONLY(nm->verify());
-      DEBUG_ONLY(nm->verify_oop_relocations());
+      DEBUG_ONLY(cm->verify());
+      DEBUG_ONLY(cm->verify_oop_relocations());
     }
   }
+
   set_needs_cache_clean(false);
   prune_scavenge_root_nmethods();
 
@@ -1036,7 +1037,7 @@
 
 void CodeCache::clear_inline_caches() {
   assert_locked_or_safepoint(CodeCache_lock);
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
     iter.method()->clear_inline_caches();
   }
@@ -1083,6 +1084,11 @@
   return number_of_marked_CodeBlobs;
 }
 
+CompiledMethod* CodeCache::find_compiled(void* start) {
+  CodeBlob *cb = find_blob(start);
+  assert(cb == NULL || cb->is_compiled(), "did not find an compiled_method");
+  return (CompiledMethod*)cb;
+}
 
 #ifdef HOTSWAP
 int CodeCache::mark_for_evol_deoptimization(instanceKlassHandle dependee) {
@@ -1094,16 +1100,16 @@
   for (int i = 0; i < old_methods->length(); i++) {
     ResourceMark rm;
     Method* old_method = old_methods->at(i);
-    nmethod *nm = old_method->code();
+    CompiledMethod* nm = old_method->code();
     if (nm != NULL) {
       nm->mark_for_deoptimization();
       number_of_marked_CodeBlobs++;
     }
   }
 
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
-    nmethod* nm = iter.method();
+    CompiledMethod* nm = iter.method();
     if (nm->is_marked_for_deoptimization()) {
       // ...Already marked in the previous pass; don't count it again.
     } else if (nm->is_evol_dependent_on(dependee())) {
@@ -1124,9 +1130,9 @@
 // Deoptimize all methods
 void CodeCache::mark_all_nmethods_for_deoptimization() {
   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
-    nmethod* nm = iter.method();
+    CompiledMethod* nm = iter.method();
     if (!nm->method()->is_method_handle_intrinsic()) {
       nm->mark_for_deoptimization();
     }
@@ -1137,9 +1143,9 @@
   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   int number_of_marked_CodeBlobs = 0;
 
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
-    nmethod* nm = iter.method();
+    CompiledMethod* nm = iter.method();
     if (nm->is_dependent_on_method(dependee)) {
       ResourceMark rm;
       nm->mark_for_deoptimization();
@@ -1152,9 +1158,9 @@
 
 void CodeCache::make_marked_nmethods_not_entrant() {
   assert_locked_or_safepoint(CodeCache_lock);
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
-    nmethod* nm = iter.method();
+    CompiledMethod* nm = iter.method();
     if (nm->is_marked_for_deoptimization()) {
       nm->make_not_entrant();
     }
@@ -1549,3 +1555,36 @@
             blob_count(), nmethod_count(), adapter_count(),
             unallocated_capacity());
 }
+
+// Initialize iterator to given compiled method
+void CompiledMethodIterator::initialize(CompiledMethod* cm) {
+  _code_blob = (CodeBlob*)cm;
+  if (!SegmentedCodeCache) {
+    // Iterate over all CodeBlobs
+    _code_blob_type = CodeBlobType::All;
+  } else if (cm != NULL) {
+    _code_blob_type = CodeCache::get_code_blob_type(cm);
+  } else {
+    // Only iterate over method code heaps, starting with non-profiled
+    _code_blob_type = CodeBlobType::MethodNonProfiled;
+  }
+}
+
+// Advance iterator to the next compiled method in the current code heap
+bool CompiledMethodIterator::next_compiled_method() {
+  // Get first method CodeBlob
+  if (_code_blob == NULL) {
+    _code_blob = CodeCache::first_blob(_code_blob_type);
+    if (_code_blob == NULL) {
+      return false;
+    } else if (_code_blob->is_nmethod()) {
+      return true;
+    }
+  }
+  // Search for next method CodeBlob
+  _code_blob = CodeCache::next_blob(_code_blob);
+  while (_code_blob != NULL && !_code_blob->is_compiled()) {
+    _code_blob = CodeCache::next_blob(_code_blob);
+  }
+  return _code_blob != NULL;
+}
--- a/hotspot/src/share/vm/code/codeCache.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/codeCache.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,6 +78,7 @@
   friend class VMStructs;
   friend class JVMCIVMStructs;
   friend class NMethodIterator;
+  friend class CompiledMethodIterator;
   friend class WhiteBox;
   friend class CodeCacheLoader;
  private:
@@ -134,12 +135,13 @@
   static void blobs_do(void f(CodeBlob* cb));              // iterates over all CodeBlobs
   static void blobs_do(CodeBlobClosure* f);                // iterates over all CodeBlobs
   static void nmethods_do(void f(nmethod* nm));            // iterates over all nmethods
-  static void alive_nmethods_do(void f(nmethod* nm));      // iterates over all alive nmethods
+  static void metadata_do(void f(Metadata* m));            // iterates over metadata in alive nmethods
 
   // Lookup
   static CodeBlob* find_blob(void* start);              // Returns the CodeBlob containing the given address
   static CodeBlob* find_blob_unsafe(void* start);       // Same as find_blob but does not fail if looking up a zombie method
   static nmethod*  find_nmethod(void* start);           // Returns the nmethod containing the given address
+  static CompiledMethod* find_compiled(void* start);
 
   static int       blob_count();                        // Returns the total number of CodeBlobs in the cache
   static int       blob_count(int code_blob_type);
@@ -207,8 +209,8 @@
   static bool heap_available(int code_blob_type);
 
   // Returns the CodeBlobType for the given nmethod
-  static int get_code_blob_type(nmethod* nm) {
-    return get_code_heap(nm)->code_blob_type();
+  static int get_code_blob_type(CompiledMethod* cm) {
+    return get_code_heap(cm)->code_blob_type();
   }
 
   // Returns the CodeBlobType for the given compilation level
@@ -337,4 +339,53 @@
   }
 };
 
+// Iterator to iterate over compiled methods in the CodeCache.
+class CompiledMethodIterator : public StackObj {
+ private:
+  CodeBlob* _code_blob;   // Current CodeBlob
+  int _code_blob_type;    // Refers to current CodeHeap
+
+ public:
+  CompiledMethodIterator() {
+    initialize(NULL); // Set to NULL, initialized by first call to next()
+  }
+
+  CompiledMethodIterator(CompiledMethod* cm) {
+    initialize(cm);
+  }
+
+  // Advance iterator to next compiled method
+  bool next() {
+    assert_locked_or_safepoint(CodeCache_lock);
+    assert(_code_blob_type < CodeBlobType::NumTypes, "end reached");
+
+    bool result = next_compiled_method();
+    while (!result && (_code_blob_type < CodeBlobType::MethodProfiled)) {
+      // Advance to next code heap if segmented code cache
+      _code_blob_type++;
+      result = next_compiled_method();
+    }
+    return result;
+  }
+
+  // Advance iterator to next alive compiled method
+  bool next_alive() {
+    bool result = next();
+    while(result && !_code_blob->is_alive()) {
+      result = next();
+    }
+    return result;
+  }
+
+  bool end()        const   { return _code_blob == NULL; }
+  CompiledMethod* method() const   { return (_code_blob != NULL) ? _code_blob->as_compiled_method() : NULL; }
+
+private:
+  // Initialize iterator to given compiled method
+  void initialize(CompiledMethod* cm);
+
+  // Advance iterator to the next compiled method in the current code heap
+  bool next_compiled_method();
+};
+
 #endif // SHARE_VM_CODE_CODECACHE_HPP
--- a/hotspot/src/share/vm/code/compiledIC.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/compiledIC.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -103,7 +103,7 @@
     MutexLockerEx pl(SafepointSynchronize::is_at_safepoint() ? NULL : Patching_lock, Mutex::_no_safepoint_check_flag);
 #ifdef ASSERT
     CodeBlob* cb = CodeCache::find_blob_unsafe(_ic_call);
-    assert(cb != NULL && cb->is_nmethod(), "must be nmethod");
+    assert(cb != NULL && cb->is_compiled(), "must be compiled");
 #endif
      _ic_call->set_destination_mt_safe(entry_point);
   }
@@ -182,17 +182,17 @@
   }
 }
 
-CompiledIC::CompiledIC(nmethod* nm, NativeCall* call)
+CompiledIC::CompiledIC(CompiledMethod* cm, NativeCall* call)
   : _ic_call(call)
 {
   address ic_call = _ic_call->instruction_address();
 
   assert(ic_call != NULL, "ic_call address must be set");
-  assert(nm != NULL, "must pass nmethod");
-  assert(nm->contains(ic_call), "must be in nmethod");
+  assert(cm != NULL, "must pass compiled method");
+  assert(cm->contains(ic_call), "must be in compiled method");
 
   // Search for the ic_call at the given address.
-  RelocIterator iter(nm, ic_call, ic_call+1);
+  RelocIterator iter(cm, ic_call, ic_call+1);
   bool ret = iter.next();
   assert(ret == true, "relocInfo must exist at this address");
   assert(iter.addr() == ic_call, "must find ic_call");
@@ -205,10 +205,10 @@
 {
   address ic_call = _ic_call->instruction_address();
 
-  nmethod* nm = iter->code();
+  CompiledMethod* nm = iter->code();
   assert(ic_call != NULL, "ic_call address must be set");
-  assert(nm != NULL, "must pass nmethod");
-  assert(nm->contains(ic_call), "must be in nmethod");
+  assert(nm != NULL, "must pass compiled method");
+  assert(nm->contains(ic_call), "must be in compiled method");
 
   initialize_from_iter(iter);
 }
@@ -278,7 +278,7 @@
   // method is guaranteed to still exist, since we only remove methods after all inline caches
   // has been cleaned up
   CodeBlob* cb = CodeCache::find_blob_unsafe(ic_destination());
-  bool is_monomorphic = (cb != NULL && cb->is_nmethod());
+  bool is_monomorphic = (cb != NULL && cb->is_compiled());
   // Check that the cached_value is a klass for non-optimized monomorphic calls
   // This assertion is invalid for compiler1: a call that does not look optimized (no static stub) can be used
   // for calling directly to vep without using the inline cache (i.e., cached_value == NULL).
@@ -423,7 +423,7 @@
     bool static_bound = info.is_optimized() || (info.cached_metadata() == NULL);
 #ifdef ASSERT
     CodeBlob* cb = CodeCache::find_blob_unsafe(info.entry());
-    assert (cb->is_nmethod(), "must be compiled!");
+    assert (cb->is_compiled(), "must be compiled!");
 #endif /* ASSERT */
 
     // This is MT safe if we come from a clean-cache and go through a
@@ -469,9 +469,11 @@
                                            bool static_bound,
                                            CompiledICInfo& info,
                                            TRAPS) {
-  nmethod* method_code = method->code();
+  CompiledMethod* method_code = method->code();
+
   address entry = NULL;
   if (method_code != NULL && method_code->is_in_use()) {
+    assert(method_code->is_compiled(), "must be compiled");
     // Call to compiled code
     if (static_bound || is_optimized) {
       entry      = method_code->verified_entry_point();
@@ -520,6 +522,7 @@
       info.set_interpreter_entry(method()->get_c2i_entry(), method());
     } else {
       // Use icholder entry
+      assert(method_code == NULL || method_code->is_compiled(), "must be compiled");
       CompiledICHolder* holder = new CompiledICHolder(method(), receiver_klass());
       info.set_icholder_entry(method()->get_c2i_unverified_entry(), holder);
     }
@@ -557,7 +560,7 @@
   MutexLockerEx pl(SafepointSynchronize::is_at_safepoint() ? NULL : Patching_lock, Mutex::_no_safepoint_check_flag);
 #ifdef ASSERT
   CodeBlob* cb = CodeCache::find_blob_unsafe(this);
-  assert(cb != NULL && cb->is_nmethod(), "must be nmethod");
+  assert(cb != NULL && cb->is_compiled(), "must be compiled");
 #endif
   set_destination_mt_safe(SharedRuntime::get_resolve_static_call_stub());
 
@@ -579,8 +582,8 @@
 bool CompiledStaticCall::is_call_to_interpreted() const {
   // It is a call to interpreted, if it calls to a stub. Hence, the destination
   // must be in the stub part of the nmethod that contains the call
-  nmethod* nm = CodeCache::find_nmethod(instruction_address());
-  return nm->stub_contains(destination());
+  CompiledMethod* cm = CodeCache::find_compiled(instruction_address());
+  return cm->stub_contains(destination());
 }
 
 void CompiledStaticCall::set(const StaticCallInfo& info) {
@@ -612,7 +615,7 @@
 // Compute settings for a CompiledStaticCall. Since we might have to set
 // the stub when calling to the interpreter, we need to return arguments.
 void CompiledStaticCall::compute_entry(const methodHandle& m, StaticCallInfo& info) {
-  nmethod* m_code = m->code();
+  CompiledMethod* m_code = m->code();
   info._callee = m;
   if (m_code != NULL && m_code->is_in_use()) {
     info._to_interpreter = false;
--- a/hotspot/src/share/vm/code/compiledIC.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/compiledIC.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -135,7 +135,7 @@
   NativeMovConstReg* _value;    // patchable value cell for this IC
   bool          _is_optimized;  // an optimized virtual call (i.e., no compiled IC)
 
-  CompiledIC(nmethod* nm, NativeCall* ic_call);
+  CompiledIC(CompiledMethod* cm, NativeCall* ic_call);
   CompiledIC(RelocIterator* iter);
 
   void initialize_from_iter(RelocIterator* iter);
@@ -169,8 +169,8 @@
 
  public:
   // conversion (machine PC to CompiledIC*)
-  friend CompiledIC* CompiledIC_before(nmethod* nm, address return_addr);
-  friend CompiledIC* CompiledIC_at(nmethod* nm, address call_site);
+  friend CompiledIC* CompiledIC_before(CompiledMethod* nm, address return_addr);
+  friend CompiledIC* CompiledIC_at(CompiledMethod* nm, address call_site);
   friend CompiledIC* CompiledIC_at(Relocation* call_site);
   friend CompiledIC* CompiledIC_at(RelocIterator* reloc_iter);
 
@@ -234,13 +234,13 @@
   void verify()            PRODUCT_RETURN;
 };
 
-inline CompiledIC* CompiledIC_before(nmethod* nm, address return_addr) {
+inline CompiledIC* CompiledIC_before(CompiledMethod* nm, address return_addr) {
   CompiledIC* c_ic = new CompiledIC(nm, nativeCall_before(return_addr));
   c_ic->verify();
   return c_ic;
 }
 
-inline CompiledIC* CompiledIC_at(nmethod* nm, address call_site) {
+inline CompiledIC* CompiledIC_at(CompiledMethod* nm, address call_site) {
   CompiledIC* c_ic = new CompiledIC(nm, nativeCall_at(call_site));
   c_ic->verify();
   return c_ic;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/code/compiledMethod.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -0,0 +1,707 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "code/compiledIC.hpp"
+#include "code/scopeDesc.hpp"
+#include "code/codeCache.hpp"
+#include "prims/methodHandles.hpp"
+#include "interpreter/bytecode.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/mutexLocker.hpp"
+
+CompiledMethod::CompiledMethod(Method* method, const char* name, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments)
+  : CodeBlob(name, layout, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
+  _method(method), _mark_for_deoptimization_status(not_marked) {
+  init_defaults();
+}
+
+CompiledMethod::CompiledMethod(Method* method, const char* name, int size, int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments)
+  : CodeBlob(name, CodeBlobLayout((address) this, size, header_size, cb), cb, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
+  _method(method), _mark_for_deoptimization_status(not_marked) {
+  init_defaults();
+}
+
+void CompiledMethod::init_defaults() {
+  _has_unsafe_access          = 0;
+  _has_method_handle_invokes  = 0;
+  _lazy_critical_native       = 0;
+  _has_wide_vectors           = 0;
+  _unloading_clock            = 0;
+}
+
+bool CompiledMethod::is_method_handle_return(address return_pc) {
+  if (!has_method_handle_invokes())  return false;
+  PcDesc* pd = pc_desc_at(return_pc);
+  if (pd == NULL)
+    return false;
+  return pd->is_method_handle_invoke();
+}
+
+// When using JVMCI the address might be off by the size of a call instruction.
+bool CompiledMethod::is_deopt_entry(address pc) {
+  return pc == deopt_handler_begin()
+#if INCLUDE_JVMCI
+    || pc == (deopt_handler_begin() + NativeCall::instruction_size)
+#endif
+    ;
+}
+
+// Returns a string version of the method state.
+const char* CompiledMethod::state() const {
+  int state = get_state();
+  switch (state) {
+  case in_use:
+    return "in use";
+  case not_used:
+    return "not_used";
+  case not_entrant:
+    return "not_entrant";
+  case zombie:
+    return "zombie";
+  case unloaded:
+    return "unloaded";
+  default:
+    fatal("unexpected method state: %d", state);
+    return NULL;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void CompiledMethod::add_exception_cache_entry(ExceptionCache* new_entry) {
+  assert(ExceptionCache_lock->owned_by_self(),"Must hold the ExceptionCache_lock");
+  assert(new_entry != NULL,"Must be non null");
+  assert(new_entry->next() == NULL, "Must be null");
+
+  ExceptionCache *ec = exception_cache();
+  if (ec != NULL) {
+    new_entry->set_next(ec);
+  }
+  release_set_exception_cache(new_entry);
+}
+
+void CompiledMethod::clean_exception_cache(BoolObjectClosure* is_alive) {
+  ExceptionCache* prev = NULL;
+  ExceptionCache* curr = exception_cache();
+
+  while (curr != NULL) {
+    ExceptionCache* next = curr->next();
+
+    Klass* ex_klass = curr->exception_type();
+    if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) {
+      if (prev == NULL) {
+        set_exception_cache(next);
+      } else {
+        prev->set_next(next);
+      }
+      delete curr;
+      // prev stays the same.
+    } else {
+      prev = curr;
+    }
+
+    curr = next;
+  }
+}
+
+// public method for accessing the exception cache
+// These are the public access methods.
+address CompiledMethod::handler_for_exception_and_pc(Handle exception, address pc) {
+  // We never grab a lock to read the exception cache, so we may
+  // have false negatives. This is okay, as it can only happen during
+  // the first few exception lookups for a given nmethod.
+  ExceptionCache* ec = exception_cache();
+  while (ec != NULL) {
+    address ret_val;
+    if ((ret_val = ec->match(exception,pc)) != NULL) {
+      return ret_val;
+    }
+    ec = ec->next();
+  }
+  return NULL;
+}
+
+void CompiledMethod::add_handler_for_exception_and_pc(Handle exception, address pc, address handler) {
+  // There are potential race conditions during exception cache updates, so we
+  // must own the ExceptionCache_lock before doing ANY modifications. Because
+  // we don't lock during reads, it is possible to have several threads attempt
+  // to update the cache with the same data. We need to check for already inserted
+  // copies of the current data before adding it.
+
+  MutexLocker ml(ExceptionCache_lock);
+  ExceptionCache* target_entry = exception_cache_entry_for_exception(exception);
+
+  if (target_entry == NULL || !target_entry->add_address_and_handler(pc,handler)) {
+    target_entry = new ExceptionCache(exception,pc,handler);
+    add_exception_cache_entry(target_entry);
+  }
+}
+
+//-------------end of code for ExceptionCache--------------
+
+// private method for handling exception cache
+// These methods are private, and used to manipulate the exception cache
+// directly.
+ExceptionCache* CompiledMethod::exception_cache_entry_for_exception(Handle exception) {
+  ExceptionCache* ec = exception_cache();
+  while (ec != NULL) {
+    if (ec->match_exception_with_space(exception)) {
+      return ec;
+    }
+    ec = ec->next();
+  }
+  return NULL;
+}
+
+bool CompiledMethod::is_at_poll_return(address pc) {
+  RelocIterator iter(this, pc, pc+1);
+  while (iter.next()) {
+    if (iter.type() == relocInfo::poll_return_type)
+      return true;
+  }
+  return false;
+}
+
+
+bool CompiledMethod::is_at_poll_or_poll_return(address pc) {
+  RelocIterator iter(this, pc, pc+1);
+  while (iter.next()) {
+    relocInfo::relocType t = iter.type();
+    if (t == relocInfo::poll_return_type || t == relocInfo::poll_type)
+      return true;
+  }
+  return false;
+}
+
+void CompiledMethod::verify_oop_relocations() {
+  // Ensure sure that the code matches the current oop values
+  RelocIterator iter(this, NULL, NULL);
+  while (iter.next()) {
+    if (iter.type() == relocInfo::oop_type) {
+      oop_Relocation* reloc = iter.oop_reloc();
+      if (!reloc->oop_is_immediate()) {
+        reloc->verify_oop_relocation();
+      }
+    }
+  }
+}
+
+
+ScopeDesc* CompiledMethod::scope_desc_at(address pc) {
+  PcDesc* pd = pc_desc_at(pc);
+  guarantee(pd != NULL, "scope must be present");
+  return new ScopeDesc(this, pd->scope_decode_offset(),
+                       pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(),
+                       pd->return_oop());
+}
+
+void CompiledMethod::cleanup_inline_caches(bool clean_all/*=false*/) {
+  assert_locked_or_safepoint(CompiledIC_lock);
+
+  // If the method is not entrant or zombie then a JMP is plastered over the
+  // first few bytes.  If an oop in the old code was there, that oop
+  // should not get GC'd.  Skip the first few bytes of oops on
+  // not-entrant methods.
+  address low_boundary = verified_entry_point();
+  if (!is_in_use() && is_nmethod()) {
+    low_boundary += NativeJump::instruction_size;
+    // %%% Note:  On SPARC we patch only a 4-byte trap, not a full NativeJump.
+    // This means that the low_boundary is going to be a little too high.
+    // This shouldn't matter, since oops of non-entrant methods are never used.
+    // In fact, why are we bothering to look at oops in a non-entrant method??
+  }
+
+  // Find all calls in an nmethod and clear the ones that point to non-entrant,
+  // zombie and unloaded nmethods.
+  ResourceMark rm;
+  RelocIterator iter(this, low_boundary);
+  while(iter.next()) {
+    switch(iter.type()) {
+      case relocInfo::virtual_call_type:
+      case relocInfo::opt_virtual_call_type: {
+        CompiledIC *ic = CompiledIC_at(&iter);
+        // Ok, to lookup references to zombies here
+        CodeBlob *cb = CodeCache::find_blob_unsafe(ic->ic_destination());
+        if( cb != NULL && cb->is_compiled() ) {
+          CompiledMethod* nm = cb->as_compiled_method();
+          // Clean inline caches pointing to zombie, non-entrant and unloaded methods
+          if (clean_all || !nm->is_in_use() || (nm->method()->code() != nm)) ic->set_to_clean(is_alive());
+        }
+        break;
+      }
+      case relocInfo::static_call_type: {
+          CompiledStaticCall *csc = compiledStaticCall_at(iter.reloc());
+          CodeBlob *cb = CodeCache::find_blob_unsafe(csc->destination());
+          if( cb != NULL && cb->is_compiled() ) {
+            CompiledMethod* cm = cb->as_compiled_method();
+            // Clean inline caches pointing to zombie, non-entrant and unloaded methods
+            if (clean_all || !cm->is_in_use() || (cm->method()->code() != cm)) {
+              csc->set_to_clean();
+            }
+          }
+        break;
+      }
+    }
+  }
+}
+
+int CompiledMethod::verify_icholder_relocations() {
+  ResourceMark rm;
+  int count = 0;
+
+  RelocIterator iter(this);
+  while(iter.next()) {
+    if (iter.type() == relocInfo::virtual_call_type) {
+      if (CompiledIC::is_icholder_call_site(iter.virtual_call_reloc())) {
+        CompiledIC *ic = CompiledIC_at(&iter);
+        if (TraceCompiledIC) {
+          tty->print("noticed icholder " INTPTR_FORMAT " ", p2i(ic->cached_icholder()));
+          ic->print();
+        }
+        assert(ic->cached_icholder() != NULL, "must be non-NULL");
+        count++;
+      }
+    }
+  }
+
+  return count;
+}
+
+// Method that knows how to preserve outgoing arguments at call. This method must be
+// called with a frame corresponding to a Java invoke
+void CompiledMethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) {
+#ifndef SHARK
+  if (method() != NULL && !method()->is_native()) {
+    address pc = fr.pc();
+    SimpleScopeDesc ssd(this, pc);
+    Bytecode_invoke call(ssd.method(), ssd.bci());
+    bool has_receiver = call.has_receiver();
+    bool has_appendix = call.has_appendix();
+    Symbol* signature = call.signature();
+
+    // The method attached by JIT-compilers should be used, if present.
+    // Bytecode can be inaccurate in such case.
+    Method* callee = attached_method_before_pc(pc);
+    if (callee != NULL) {
+      has_receiver = !(callee->access_flags().is_static());
+      has_appendix = false;
+      signature = callee->signature();
+    }
+
+    fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f);
+  }
+#endif // !SHARK
+}
+
+// -----------------------------------------------------------------------------
+// CompiledMethod::get_deopt_original_pc
+//
+// Return the original PC for the given PC if:
+// (a) the given PC belongs to a nmethod and
+// (b) it is a deopt PC
+address CompiledMethod::get_deopt_original_pc(const frame* fr) {
+  if (fr->cb() == NULL)  return NULL;
+
+  CompiledMethod* cm = fr->cb()->as_compiled_method_or_null();
+  if (cm != NULL && cm->is_deopt_pc(fr->pc()))
+    return cm->get_original_pc(fr);
+
+  return NULL;
+}
+
+Method* CompiledMethod::attached_method(address call_instr) {
+  assert(code_contains(call_instr), "not part of the nmethod");
+  RelocIterator iter(this, call_instr, call_instr + 1);
+  while (iter.next()) {
+    if (iter.addr() == call_instr) {
+      switch(iter.type()) {
+        case relocInfo::static_call_type:      return iter.static_call_reloc()->method_value();
+        case relocInfo::opt_virtual_call_type: return iter.opt_virtual_call_reloc()->method_value();
+        case relocInfo::virtual_call_type:     return iter.virtual_call_reloc()->method_value();
+      }
+    }
+  }
+  return NULL; // not found
+}
+
+Method* CompiledMethod::attached_method_before_pc(address pc) {
+  if (NativeCall::is_call_before(pc)) {
+    NativeCall* ncall = nativeCall_before(pc);
+    return attached_method(ncall->instruction_address());
+  }
+  return NULL; // not a call
+}
+
+void CompiledMethod::clear_inline_caches() {
+  assert(SafepointSynchronize::is_at_safepoint(), "cleaning of IC's only allowed at safepoint");
+  if (is_zombie()) {
+    return;
+  }
+
+  RelocIterator iter(this);
+  while (iter.next()) {
+    iter.reloc()->clear_inline_cache();
+  }
+}
+
+// Clear ICStubs of all compiled ICs
+void CompiledMethod::clear_ic_stubs() {
+  assert_locked_or_safepoint(CompiledIC_lock);
+  RelocIterator iter(this);
+  while(iter.next()) {
+    if (iter.type() == relocInfo::virtual_call_type) {
+      CompiledIC* ic = CompiledIC_at(&iter);
+      ic->clear_ic_stub();
+    }
+  }
+}
+
+#ifdef ASSERT
+
+class CheckClass : AllStatic {
+  static BoolObjectClosure* _is_alive;
+
+  // Check class_loader is alive for this bit of metadata.
+  static void check_class(Metadata* md) {
+    Klass* klass = NULL;
+    if (md->is_klass()) {
+      klass = ((Klass*)md);
+    } else if (md->is_method()) {
+      klass = ((Method*)md)->method_holder();
+    } else if (md->is_methodData()) {
+      klass = ((MethodData*)md)->method()->method_holder();
+    } else {
+      md->print();
+      ShouldNotReachHere();
+    }
+    assert(klass->is_loader_alive(_is_alive), "must be alive");
+  }
+ public:
+  static void do_check_class(BoolObjectClosure* is_alive, CompiledMethod* nm) {
+    assert(SafepointSynchronize::is_at_safepoint(), "this is only ok at safepoint");
+    _is_alive = is_alive;
+    nm->metadata_do(check_class);
+  }
+};
+
+// This is called during a safepoint so can use static data
+BoolObjectClosure* CheckClass::_is_alive = NULL;
+#endif // ASSERT
+
+void CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive) {
+  if (ic->is_icholder_call()) {
+    // The only exception is compiledICHolder oops which may
+    // yet be marked below. (We check this further below).
+    CompiledICHolder* cichk_oop = ic->cached_icholder();
+
+    if (cichk_oop->holder_method()->method_holder()->is_loader_alive(is_alive) &&
+        cichk_oop->holder_klass()->is_loader_alive(is_alive)) {
+      return;
+    }
+  } else {
+    Metadata* ic_oop = ic->cached_metadata();
+    if (ic_oop != NULL) {
+      if (ic_oop->is_klass()) {
+        if (((Klass*)ic_oop)->is_loader_alive(is_alive)) {
+          return;
+        }
+      } else if (ic_oop->is_method()) {
+        if (((Method*)ic_oop)->method_holder()->is_loader_alive(is_alive)) {
+          return;
+        }
+      } else {
+        ShouldNotReachHere();
+      }
+    }
+  }
+
+  ic->set_to_clean();
+}
+
+unsigned char CompiledMethod::_global_unloading_clock = 0;
+
+void CompiledMethod::increase_unloading_clock() {
+  _global_unloading_clock++;
+  if (_global_unloading_clock == 0) {
+    // _nmethods are allocated with _unloading_clock == 0,
+    // so 0 is never used as a clock value.
+    _global_unloading_clock = 1;
+  }
+}
+
+void CompiledMethod::set_unloading_clock(unsigned char unloading_clock) {
+  OrderAccess::release_store((volatile jubyte*)&_unloading_clock, unloading_clock);
+}
+
+unsigned char CompiledMethod::unloading_clock() {
+  return (unsigned char)OrderAccess::load_acquire((volatile jubyte*)&_unloading_clock);
+}
+
+// Processing of oop references should have been sufficient to keep
+// all strong references alive.  Any weak references should have been
+// cleared as well.  Visit all the metadata and ensure that it's
+// really alive.
+void CompiledMethod::verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive) {
+#ifdef ASSERT
+    RelocIterator iter(this, low_boundary);
+    while (iter.next()) {
+    // static_stub_Relocations may have dangling references to
+    // Method*s so trim them out here.  Otherwise it looks like
+    // compiled code is maintaining a link to dead metadata.
+    address static_call_addr = NULL;
+    if (iter.type() == relocInfo::opt_virtual_call_type) {
+      CompiledIC* cic = CompiledIC_at(&iter);
+      if (!cic->is_call_to_interpreted()) {
+        static_call_addr = iter.addr();
+      }
+    } else if (iter.type() == relocInfo::static_call_type) {
+      CompiledStaticCall* csc = compiledStaticCall_at(iter.reloc());
+      if (!csc->is_call_to_interpreted()) {
+        static_call_addr = iter.addr();
+      }
+    }
+    if (static_call_addr != NULL) {
+      RelocIterator sciter(this, low_boundary);
+      while (sciter.next()) {
+        if (sciter.type() == relocInfo::static_stub_type &&
+            sciter.static_stub_reloc()->static_call() == static_call_addr) {
+          sciter.static_stub_reloc()->clear_inline_cache();
+        }
+      }
+    }
+  }
+  // Check that the metadata embedded in the nmethod is alive
+  CheckClass::do_check_class(is_alive, this);
+#endif
+}
+
+// This is called at the end of the strong tracing/marking phase of a
+// GC to unload an nmethod if it contains otherwise unreachable
+// oops.
+
+void CompiledMethod::do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred) {
+  // Make sure the oop's ready to receive visitors
+  assert(!is_zombie() && !is_unloaded(),
+         "should not call follow on zombie or unloaded nmethod");
+
+  // If the method is not entrant then a JMP is plastered over the
+  // first few bytes.  If an oop in the old code was there, that oop
+  // should not get GC'd.  Skip the first few bytes of oops on
+  // not-entrant methods.
+  address low_boundary = verified_entry_point();
+  if (is_not_entrant()) {
+    low_boundary += NativeJump::instruction_size;
+    // %%% Note:  On SPARC we patch only a 4-byte trap, not a full NativeJump.
+    // (See comment above.)
+  }
+
+  // The RedefineClasses() API can cause the class unloading invariant
+  // to no longer be true. See jvmtiExport.hpp for details.
+  // Also, leave a debugging breadcrumb in local flag.
+  if (JvmtiExport::has_redefined_a_class()) {
+    // This set of the unloading_occurred flag is done before the
+    // call to post_compiled_method_unload() so that the unloading
+    // of this nmethod is reported.
+    unloading_occurred = true;
+  }
+
+  // Exception cache
+  clean_exception_cache(is_alive);
+
+  // If class unloading occurred we first iterate over all inline caches and
+  // clear ICs where the cached oop is referring to an unloaded klass or method.
+  // The remaining live cached oops will be traversed in the relocInfo::oop_type
+  // iteration below.
+  if (unloading_occurred) {
+    RelocIterator iter(this, low_boundary);
+    while(iter.next()) {
+      if (iter.type() == relocInfo::virtual_call_type) {
+        CompiledIC *ic = CompiledIC_at(&iter);
+        clean_ic_if_metadata_is_dead(ic, is_alive);
+      }
+    }
+  }
+
+  if (do_unloading_oops(low_boundary, is_alive, unloading_occurred)) {
+    return;
+  }
+
+#if INCLUDE_JVMCI
+  if (do_unloading_jvmci(is_alive, unloading_occurred)) {
+    return;
+  }
+#endif
+
+  // Ensure that all metadata is still alive
+  verify_metadata_loaders(low_boundary, is_alive);
+}
+
+template <class CompiledICorStaticCall>
+static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, BoolObjectClosure *is_alive, CompiledMethod* from) {
+  // Ok, to lookup references to zombies here
+  CodeBlob *cb = CodeCache::find_blob_unsafe(addr);
+  CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
+  if (nm != NULL) {
+    if (nm->unloading_clock() != CompiledMethod::global_unloading_clock()) {
+      // The nmethod has not been processed yet.
+      return true;
+    }
+
+    // Clean inline caches pointing to both zombie and not_entrant methods
+    if (!nm->is_in_use() || (nm->method()->code() != nm)) {
+      ic->set_to_clean();
+      assert(ic->is_clean(), "nmethod " PTR_FORMAT "not clean %s", p2i(from), from->method()->name_and_sig_as_C_string());
+    }
+  }
+
+  return false;
+}
+
+static bool clean_if_nmethod_is_unloaded(CompiledIC *ic, BoolObjectClosure *is_alive, CompiledMethod* from) {
+  return clean_if_nmethod_is_unloaded(ic, ic->ic_destination(), is_alive, from);
+}
+
+static bool clean_if_nmethod_is_unloaded(CompiledStaticCall *csc, BoolObjectClosure *is_alive, CompiledMethod* from) {
+  return clean_if_nmethod_is_unloaded(csc, csc->destination(), is_alive, from);
+}
+
+bool CompiledMethod::do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred) {
+  ResourceMark rm;
+
+  // Make sure the oop's ready to receive visitors
+  assert(!is_zombie() && !is_unloaded(),
+         "should not call follow on zombie or unloaded nmethod");
+
+  // If the method is not entrant then a JMP is plastered over the
+  // first few bytes.  If an oop in the old code was there, that oop
+  // should not get GC'd.  Skip the first few bytes of oops on
+  // not-entrant methods.
+  address low_boundary = verified_entry_point();
+  if (is_not_entrant()) {
+    low_boundary += NativeJump::instruction_size;
+    // %%% Note:  On SPARC we patch only a 4-byte trap, not a full NativeJump.
+    // (See comment above.)
+  }
+
+  // The RedefineClasses() API can cause the class unloading invariant
+  // to no longer be true. See jvmtiExport.hpp for details.
+  // Also, leave a debugging breadcrumb in local flag.
+  if (JvmtiExport::has_redefined_a_class()) {
+    // This set of the unloading_occurred flag is done before the
+    // call to post_compiled_method_unload() so that the unloading
+    // of this nmethod is reported.
+    unloading_occurred = true;
+  }
+
+  // Exception cache
+  clean_exception_cache(is_alive);
+
+  bool postponed = false;
+
+  RelocIterator iter(this, low_boundary);
+  while(iter.next()) {
+
+    switch (iter.type()) {
+
+    case relocInfo::virtual_call_type:
+      if (unloading_occurred) {
+        // If class unloading occurred we first iterate over all inline caches and
+        // clear ICs where the cached oop is referring to an unloaded klass or method.
+        clean_ic_if_metadata_is_dead(CompiledIC_at(&iter), is_alive);
+      }
+
+      postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
+      break;
+
+    case relocInfo::opt_virtual_call_type:
+      postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
+      break;
+
+    case relocInfo::static_call_type:
+      postponed |= clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), is_alive, this);
+      break;
+
+    case relocInfo::oop_type:
+      // handled by do_unloading_oops below
+      break;
+
+    case relocInfo::metadata_type:
+      break; // nothing to do.
+    }
+  }
+
+  if (do_unloading_oops(low_boundary, is_alive, unloading_occurred)) {
+    return postponed;
+  }
+
+#if INCLUDE_JVMCI
+  if (do_unloading_jvmci(is_alive, unloading_occurred)) {
+    return postponed;
+  }
+#endif
+
+  // Ensure that all metadata is still alive
+  verify_metadata_loaders(low_boundary, is_alive);
+
+  return postponed;
+}
+
+void CompiledMethod::do_unloading_parallel_postponed(BoolObjectClosure* is_alive, bool unloading_occurred) {
+  ResourceMark rm;
+
+  // Make sure the oop's ready to receive visitors
+  assert(!is_zombie(),
+         "should not call follow on zombie nmethod");
+
+  // If the method is not entrant then a JMP is plastered over the
+  // first few bytes.  If an oop in the old code was there, that oop
+  // should not get GC'd.  Skip the first few bytes of oops on
+  // not-entrant methods.
+  address low_boundary = verified_entry_point();
+  if (is_not_entrant()) {
+    low_boundary += NativeJump::instruction_size;
+    // %%% Note:  On SPARC we patch only a 4-byte trap, not a full NativeJump.
+    // (See comment above.)
+  }
+
+  RelocIterator iter(this, low_boundary);
+  while(iter.next()) {
+
+    switch (iter.type()) {
+
+    case relocInfo::virtual_call_type:
+      clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
+      break;
+
+    case relocInfo::opt_virtual_call_type:
+      clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
+      break;
+
+    case relocInfo::static_call_type:
+      clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), is_alive, this);
+      break;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/code/compiledMethod.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_CODE_COMPILEDMETHOD_HPP
+#define SHARE_VM_CODE_COMPILEDMETHOD_HPP
+
+#include "code/codeBlob.hpp"
+#include "code/pcDesc.hpp"
+#include "oops/metadata.hpp"
+
+class Dependencies;
+class ExceptionHandlerTable;
+class ImplicitExceptionTable;
+class AbstractCompiler;
+class xmlStream;
+class CompiledStaticCall;
+
+// This class is used internally by nmethods, to cache
+// exception/pc/handler information.
+
+class ExceptionCache : public CHeapObj<mtCode> {
+  friend class VMStructs;
+ private:
+  enum { cache_size = 16 };
+  Klass*   _exception_type;
+  address  _pc[cache_size];
+  address  _handler[cache_size];
+  volatile int _count;
+  ExceptionCache* _next;
+
+  address pc_at(int index)                     { assert(index >= 0 && index < count(),""); return _pc[index]; }
+  void    set_pc_at(int index, address a)      { assert(index >= 0 && index < cache_size,""); _pc[index] = a; }
+  address handler_at(int index)                { assert(index >= 0 && index < count(),""); return _handler[index]; }
+  void    set_handler_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _handler[index] = a; }
+  int     count()                              { return OrderAccess::load_acquire(&_count); }
+  // increment_count is only called under lock, but there may be concurrent readers.
+  void    increment_count()                    { OrderAccess::release_store(&_count, _count + 1); }
+
+ public:
+
+  ExceptionCache(Handle exception, address pc, address handler);
+
+  Klass*    exception_type()                { return _exception_type; }
+  ExceptionCache* next()                    { return _next; }
+  void      set_next(ExceptionCache *ec)    { _next = ec; }
+
+  address match(Handle exception, address pc);
+  bool    match_exception_with_space(Handle exception) ;
+  address test_address(address addr);
+  bool    add_address_and_handler(address addr, address handler) ;
+};
+
+class nmethod;
+
+// cache pc descs found in earlier inquiries
+class PcDescCache VALUE_OBJ_CLASS_SPEC {
+  friend class VMStructs;
+ private:
+  enum { cache_size = 4 };
+  // The array elements MUST be volatile! Several threads may modify
+  // and read from the cache concurrently. find_pc_desc_internal has
+  // returned wrong results. C++ compiler (namely xlC12) may duplicate
+  // C++ field accesses if the elements are not volatile.
+  typedef PcDesc* PcDescPtr;
+  volatile PcDescPtr _pc_descs[cache_size]; // last cache_size pc_descs found
+ public:
+  PcDescCache() { debug_only(_pc_descs[0] = NULL); }
+  void    reset_to(PcDesc* initial_pc_desc);
+  PcDesc* find_pc_desc(int pc_offset, bool approximate);
+  void    add_pc_desc(PcDesc* pc_desc);
+  PcDesc* last_pc_desc() { return _pc_descs[0]; }
+};
+
+class PcDescSearch {
+private:
+  address _code_begin;
+  PcDesc* _lower;
+  PcDesc* _upper;
+public:
+  PcDescSearch(address code, PcDesc* lower, PcDesc* upper) :
+    _code_begin(code), _lower(lower), _upper(upper)
+  {
+  }
+
+  address code_begin() const { return _code_begin; }
+  PcDesc* scopes_pcs_begin() const { return _lower; }
+  PcDesc* scopes_pcs_end() const { return _upper; }
+};
+
+class PcDescContainer VALUE_OBJ_CLASS_SPEC {
+private:
+  PcDescCache _pc_desc_cache;
+public:
+  PcDescContainer() {}
+
+  PcDesc* find_pc_desc_internal(address pc, bool approximate, const PcDescSearch& search);
+  void    reset_to(PcDesc* initial_pc_desc) { _pc_desc_cache.reset_to(initial_pc_desc); }
+
+  PcDesc* find_pc_desc(address pc, bool approximate, const PcDescSearch& search) {
+    address base_address = search.code_begin();
+    PcDesc* desc = _pc_desc_cache.last_pc_desc();
+    if (desc != NULL && desc->pc_offset() == pc - base_address) {
+      return desc;
+    }
+    return find_pc_desc_internal(pc, approximate, search);
+  }
+};
+
+
+class CompiledMethod : public CodeBlob {
+  friend class VMStructs;
+  friend class NMethodSweeper;
+
+  void init_defaults();
+protected:
+  enum MarkForDeoptimizationStatus {
+    not_marked,
+    deoptimize,
+    deoptimize_noupdate
+  };
+
+  MarkForDeoptimizationStatus _mark_for_deoptimization_status; // Used for stack deoptimization
+
+  bool _is_far_code; // Code is far from CodeCache.
+                     // Have to use far call instructions to call it from code in CodeCache.
+  // set during construction
+  unsigned int _has_unsafe_access:1;         // May fault due to unsafe access.
+  unsigned int _has_method_handle_invokes:1; // Has this method MethodHandle invokes?
+  unsigned int _lazy_critical_native:1;      // Lazy JNI critical native
+  unsigned int _has_wide_vectors:1;          // Preserve wide vectors at safepoints
+
+  Method*   _method;
+  address _scopes_data_begin;
+  // All deoptee's will resume execution at this location described by
+  // this address.
+  address _deopt_handler_begin;
+  // All deoptee's at a MethodHandle call site will resume execution
+  // at this location described by this offset.
+  address _deopt_mh_handler_begin;
+
+  PcDescContainer _pc_desc_container;
+  ExceptionCache * volatile _exception_cache;
+
+  virtual void flush() = 0;
+protected:
+  CompiledMethod(Method* method, const char* name, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);
+  CompiledMethod(Method* method, const char* name, int size, int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments);
+
+public:
+  virtual bool is_compiled() const                { return true; }
+
+  bool  has_unsafe_access() const                 { return _has_unsafe_access; }
+  void  set_has_unsafe_access(bool z)             { _has_unsafe_access = z; }
+
+  bool  has_method_handle_invokes() const         { return _has_method_handle_invokes; }
+  void  set_has_method_handle_invokes(bool z)     { _has_method_handle_invokes = z; }
+
+  bool  is_lazy_critical_native() const           { return _lazy_critical_native; }
+  void  set_lazy_critical_native(bool z)          { _lazy_critical_native = z; }
+
+  bool  has_wide_vectors() const                  { return _has_wide_vectors; }
+  void  set_has_wide_vectors(bool z)              { _has_wide_vectors = z; }
+
+  enum { in_use       = 0,   // executable nmethod
+         not_used     = 1,   // not entrant, but revivable
+         not_entrant  = 2,   // marked for deoptimization but activations may still exist,
+                             // will be transformed to zombie when all activations are gone
+         zombie       = 3,   // no activations exist, nmethod is ready for purge
+         unloaded     = 4    // there should be no activations, should not be called,
+                             // will be transformed to zombie immediately
+  };
+
+  virtual AbstractCompiler* compiler() const = 0;
+  virtual bool  is_in_use() const = 0;
+  virtual int   comp_level() const = 0;
+  virtual int   compile_id() const = 0;
+
+
+  virtual address verified_entry_point() const = 0;
+  virtual void log_identity(xmlStream* log) const = 0;
+  virtual void log_state_change() const = 0;
+  virtual bool make_not_used() = 0;
+  virtual bool make_not_entrant() = 0;
+  virtual bool make_entrant() = 0;
+  virtual address entry_point() const = 0;
+  virtual bool make_zombie() = 0;
+  virtual bool is_osr_method() const = 0;
+  virtual int osr_entry_bci() const = 0;
+  Method* method() const                          { return _method; }
+  virtual void print_pcs() = 0;
+  bool is_native_method() const { return _method != NULL && _method->is_native(); }
+  bool is_java_method() const { return _method != NULL && !_method->is_native(); }
+
+  // ScopeDesc retrieval operation
+  PcDesc* pc_desc_at(address pc)   { return find_pc_desc(pc, false); }
+  // pc_desc_near returns the first PcDesc at or after the givne pc.
+  PcDesc* pc_desc_near(address pc) { return find_pc_desc(pc, true); }
+
+  // ScopeDesc for an instruction
+  ScopeDesc* scope_desc_at(address pc);
+
+  bool is_at_poll_return(address pc);
+  bool is_at_poll_or_poll_return(address pc);
+
+  bool  is_marked_for_deoptimization() const      { return _mark_for_deoptimization_status != not_marked; }
+  void  mark_for_deoptimization(bool inc_recompile_counts = true) {
+    _mark_for_deoptimization_status = (inc_recompile_counts ? deoptimize : deoptimize_noupdate);
+  }
+  bool update_recompile_counts() const {
+    // Update recompile counts when either the update is explicitly requested (deoptimize)
+    // or the nmethod is not marked for deoptimization at all (not_marked).
+    // The latter happens during uncommon traps when deoptimized nmethod is made not entrant.
+    return _mark_for_deoptimization_status != deoptimize_noupdate;
+  }
+
+  // tells whether frames described by this nmethod can be deoptimized
+  // note: native wrappers cannot be deoptimized.
+  bool can_be_deoptimized() const { return is_java_method(); }
+
+  virtual oop oop_at(int index) const = 0;
+  virtual Metadata* metadata_at(int index) const = 0;
+
+  address scopes_data_begin() const { return _scopes_data_begin; }
+  virtual address scopes_data_end() const = 0;
+  int scopes_data_size() const { return scopes_data_end() - scopes_data_begin(); }
+
+  virtual PcDesc* scopes_pcs_begin() const = 0;
+  virtual PcDesc* scopes_pcs_end() const = 0;
+  int scopes_pcs_size() const { return (intptr_t) scopes_pcs_end() - (intptr_t) scopes_pcs_begin(); }
+
+  address insts_begin() const { return code_begin(); }
+  address insts_end() const { return stub_begin(); }
+  bool insts_contains(address addr) const { return insts_begin() <= addr && addr < insts_end(); }
+  int insts_size() const { return insts_end() - insts_begin(); }
+
+  virtual address consts_begin() const = 0;
+  virtual address consts_end() const = 0;
+  bool consts_contains(address addr) const { return consts_begin() <= addr && addr < consts_end(); }
+  int consts_size() const { return consts_end() - consts_begin(); }
+
+  virtual address stub_begin() const = 0;
+  virtual address stub_end() const = 0;
+  bool stub_contains(address addr) const { return stub_begin() <= addr && addr < stub_end(); }
+  int stub_size() const { return stub_end() - stub_begin(); }
+
+  virtual address handler_table_begin() const = 0;
+  virtual address handler_table_end() const = 0;
+  bool handler_table_contains(address addr) const { return handler_table_begin() <= addr && addr < handler_table_end(); }
+  int handler_table_size() const { return handler_table_end() - handler_table_begin(); }
+
+  virtual address nul_chk_table_begin() const = 0;
+  virtual address nul_chk_table_end() const = 0;
+  bool nul_chk_table_contains(address addr) const { return nul_chk_table_begin() <= addr && addr < nul_chk_table_end(); }
+  int nul_chk_table_size() const { return nul_chk_table_end() - nul_chk_table_begin(); }
+
+  virtual oop* oop_addr_at(int index) const = 0;
+  virtual Metadata** metadata_addr_at(int index) const = 0;
+  virtual void    set_original_pc(const frame* fr, address pc) = 0;
+
+  // Exception cache support
+  // Note: _exception_cache may be read concurrently. We rely on memory_order_consume here.
+  ExceptionCache* exception_cache() const         { return _exception_cache; }
+  void set_exception_cache(ExceptionCache *ec)    { _exception_cache = ec; }
+  void release_set_exception_cache(ExceptionCache *ec) { OrderAccess::release_store_ptr(&_exception_cache, ec); }
+  address handler_for_exception_and_pc(Handle exception, address pc);
+  void add_handler_for_exception_and_pc(Handle exception, address pc, address handler);
+  void clean_exception_cache(BoolObjectClosure* is_alive);
+
+  void add_exception_cache_entry(ExceptionCache* new_entry);
+  ExceptionCache* exception_cache_entry_for_exception(Handle exception);
+
+  // MethodHandle
+  bool is_method_handle_return(address return_pc);
+  address deopt_mh_handler_begin() const  { return _deopt_mh_handler_begin; }
+
+  address deopt_handler_begin() const { return _deopt_handler_begin; }
+  virtual address get_original_pc(const frame* fr) = 0;
+  // Deopt
+  // Return true is the PC is one would expect if the frame is being deopted.
+  bool is_deopt_pc      (address pc) { return is_deopt_entry(pc) || is_deopt_mh_entry(pc); }
+  bool is_deopt_mh_entry(address pc) { return pc == deopt_mh_handler_begin(); }
+  bool is_deopt_entry(address pc);
+
+  virtual bool can_convert_to_zombie() = 0;
+  virtual const char* compile_kind() const = 0;
+  virtual int get_state() const = 0;
+
+  const char* state() const;
+
+  bool is_far_code() const { return _is_far_code; }
+
+  bool inlinecache_check_contains(address addr) const {
+    return (addr >= code_begin() && addr < verified_entry_point());
+  }
+
+  void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f);
+
+  // implicit exceptions support
+  virtual address continuation_for_implicit_exception(address pc) { return NULL; }
+
+  static address get_deopt_original_pc(const frame* fr);
+
+  // Inline cache support
+  void cleanup_inline_caches(bool clean_all = false);
+  virtual void clear_inline_caches();
+  void clear_ic_stubs();
+
+  // Verify and count cached icholder relocations.
+  int  verify_icholder_relocations();
+  void verify_oop_relocations();
+
+  virtual bool is_evol_dependent_on(Klass* dependee) = 0;
+  // Fast breakpoint support. Tells if this compiled method is
+  // dependent on the given method. Returns true if this nmethod
+  // corresponds to the given method as well.
+  virtual bool is_dependent_on_method(Method* dependee) = 0;
+
+  Method* attached_method(address call_pc);
+  Method* attached_method_before_pc(address pc);
+
+  virtual void metadata_do(void f(Metadata*)) = 0;
+
+  // GC support
+
+  void set_unloading_next(CompiledMethod* next) { _unloading_next = next; }
+  CompiledMethod* unloading_next()              { return _unloading_next; }
+
+  void static clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive);
+
+  // Check that all metadata is still alive
+  void verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive);
+
+  virtual void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);
+  //  The parallel versions are used by G1.
+  virtual bool do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred);
+  virtual void do_unloading_parallel_postponed(BoolObjectClosure* is_alive, bool unloading_occurred);
+
+  static unsigned char global_unloading_clock()   { return _global_unloading_clock; }
+  static void increase_unloading_clock();
+
+  void set_unloading_clock(unsigned char unloading_clock);
+  unsigned char unloading_clock();
+
+protected:
+  virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred) = 0;
+#if INCLUDE_JVMCI
+  virtual bool do_unloading_jvmci(BoolObjectClosure* is_alive, bool unloading_occurred) = 0;
+#endif
+
+private:
+  // GC support to help figure out if an nmethod has been
+  // cleaned/unloaded by the current GC.
+  static unsigned char _global_unloading_clock;
+
+  volatile unsigned char _unloading_clock;   // Incremented after GC unloaded/cleaned the nmethod
+
+  PcDesc* find_pc_desc(address pc, bool approximate) {
+    return _pc_desc_container.find_pc_desc(pc, approximate, PcDescSearch(code_begin(), scopes_pcs_begin(), scopes_pcs_end()));
+  }
+
+protected:
+  union {
+    // Used by G1 to chain nmethods.
+    CompiledMethod* _unloading_next;
+    // Used by non-G1 GCs to chain nmethods.
+    nmethod* _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
+  };
+};
+
+#endif //SHARE_VM_CODE_COMPILEDMETHOD_HPP
--- a/hotspot/src/share/vm/code/debugInfo.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/debugInfo.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -261,11 +261,11 @@
 
 class DebugInfoReadStream : public CompressedReadStream {
  private:
-  const nmethod* _code;
-  const nmethod* code() const { return _code; }
+  const CompiledMethod* _code;
+  const CompiledMethod* code() const { return _code; }
   GrowableArray<ScopeValue*>* _obj_pool;
  public:
-  DebugInfoReadStream(const nmethod* code, int offset, GrowableArray<ScopeValue*>* obj_pool = NULL) :
+  DebugInfoReadStream(const CompiledMethod* code, int offset, GrowableArray<ScopeValue*>* obj_pool = NULL) :
     CompressedReadStream(code->scopes_data_begin(), offset) {
     _code = code;
     _obj_pool = obj_pool;
--- a/hotspot/src/share/vm/code/exceptionHandlerTable.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/exceptionHandlerTable.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,9 +65,9 @@
 }
 
 
-ExceptionHandlerTable::ExceptionHandlerTable(const nmethod* nm) {
-  _table  = (HandlerTableEntry*)nm->handler_table_begin();
-  _length = nm->handler_table_size() / sizeof(HandlerTableEntry);
+ExceptionHandlerTable::ExceptionHandlerTable(const CompiledMethod* cm) {
+  _table  = (HandlerTableEntry*)cm->handler_table_begin();
+  _length = cm->handler_table_size() / sizeof(HandlerTableEntry);
   _size   = 0; // no space allocated by ExeptionHandlerTable!
 }
 
@@ -98,9 +98,9 @@
 }
 
 
-void ExceptionHandlerTable::copy_to(nmethod* nm) {
-  assert(size_in_bytes() == nm->handler_table_size(), "size of space allocated in nmethod incorrect");
-  copy_bytes_to(nm->handler_table_begin());
+void ExceptionHandlerTable::copy_to(CompiledMethod* cm) {
+  assert(size_in_bytes() == cm->handler_table_size(), "size of space allocated in compiled method incorrect");
+  copy_bytes_to(cm->handler_table_begin());
 }
 
 void ExceptionHandlerTable::copy_bytes_to(address addr) {
--- a/hotspot/src/share/vm/code/exceptionHandlerTable.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/exceptionHandlerTable.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -98,7 +98,7 @@
   ExceptionHandlerTable(int initial_size = 8);
 
   // (run-time) construction from nmethod
-  ExceptionHandlerTable(const nmethod* nm);
+  ExceptionHandlerTable(const CompiledMethod* nm);
 
   // (compile-time) add entries
   void add_subtable(
@@ -115,7 +115,7 @@
 
   // nmethod support
   int  size_in_bytes() const { return round_to(_length * sizeof(HandlerTableEntry), oopSize); }
-  void copy_to(nmethod* nm);
+  void copy_to(CompiledMethod* nm);
   void copy_bytes_to(address addr);
 
   // lookup
--- a/hotspot/src/share/vm/code/icBuffer.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/icBuffer.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,8 +49,8 @@
 void ICStub::finalize() {
   if (!is_empty()) {
     ResourceMark rm;
-    CompiledIC *ic = CompiledIC_at(CodeCache::find_nmethod(ic_site()), ic_site());
-    assert(CodeCache::find_nmethod(ic->instruction_address()) != NULL, "inline cache in non-nmethod?");
+    CompiledIC *ic = CompiledIC_at(CodeCache::find_compiled(ic_site()), ic_site());
+    assert(CodeCache::find_compiled(ic->instruction_address()) != NULL, "inline cache in non-compiled?");
 
     assert(this == ICStub_from_destination_address(ic->stub_address()), "wrong owner of ic buffer");
     ic->set_ic_destination_and_value(destination(), cached_value());
--- a/hotspot/src/share/vm/code/nmethod.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -73,8 +73,6 @@
 #include "jvmci/jvmciJavaClasses.hpp"
 #endif
 
-unsigned char nmethod::_global_unloading_clock = 0;
-
 #ifdef DTRACE_ENABLED
 
 // Only bother with this argument setup if dtrace is available
@@ -336,22 +334,6 @@
   return false;
 }
 
-
-// private method for handling exception cache
-// These methods are private, and used to manipulate the exception cache
-// directly.
-ExceptionCache* nmethod::exception_cache_entry_for_exception(Handle exception) {
-  ExceptionCache* ec = exception_cache();
-  while (ec != NULL) {
-    if (ec->match_exception_with_space(exception)) {
-      return ec;
-    }
-    ec = ec->next();
-  }
-  return NULL;
-}
-
-
 //-----------------------------------------------------------------------------
 
 
@@ -434,82 +416,6 @@
   return nsize;
 }
 
-//-----------------------------------------------------------------------------
-
-
-void nmethod::add_exception_cache_entry(ExceptionCache* new_entry) {
-  assert(ExceptionCache_lock->owned_by_self(),"Must hold the ExceptionCache_lock");
-  assert(new_entry != NULL,"Must be non null");
-  assert(new_entry->next() == NULL, "Must be null");
-
-  ExceptionCache *ec = exception_cache();
-  if (ec != NULL) {
-    new_entry->set_next(ec);
-  }
-  release_set_exception_cache(new_entry);
-}
-
-void nmethod::clean_exception_cache(BoolObjectClosure* is_alive) {
-  ExceptionCache* prev = NULL;
-  ExceptionCache* curr = exception_cache();
-
-  while (curr != NULL) {
-    ExceptionCache* next = curr->next();
-
-    Klass* ex_klass = curr->exception_type();
-    if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) {
-      if (prev == NULL) {
-        set_exception_cache(next);
-      } else {
-        prev->set_next(next);
-      }
-      delete curr;
-      // prev stays the same.
-    } else {
-      prev = curr;
-    }
-
-    curr = next;
-  }
-}
-
-// public method for accessing the exception cache
-// These are the public access methods.
-address nmethod::handler_for_exception_and_pc(Handle exception, address pc) {
-  // We never grab a lock to read the exception cache, so we may
-  // have false negatives. This is okay, as it can only happen during
-  // the first few exception lookups for a given nmethod.
-  ExceptionCache* ec = exception_cache();
-  while (ec != NULL) {
-    address ret_val;
-    if ((ret_val = ec->match(exception,pc)) != NULL) {
-      return ret_val;
-    }
-    ec = ec->next();
-  }
-  return NULL;
-}
-
-
-void nmethod::add_handler_for_exception_and_pc(Handle exception, address pc, address handler) {
-  // There are potential race conditions during exception cache updates, so we
-  // must own the ExceptionCache_lock before doing ANY modifications. Because
-  // we don't lock during reads, it is possible to have several threads attempt
-  // to update the cache with the same data. We need to check for already inserted
-  // copies of the current data before adding it.
-
-  MutexLocker ml(ExceptionCache_lock);
-  ExceptionCache* target_entry = exception_cache_entry_for_exception(exception);
-
-  if (target_entry == NULL || !target_entry->add_address_and_handler(pc,handler)) {
-    target_entry = new ExceptionCache(exception,pc,handler);
-    add_exception_cache_entry(target_entry);
-  }
-}
-
-
-//-------------end of code for ExceptionCache--------------
-
 
 int nmethod::total_size() const {
   return
@@ -531,13 +437,7 @@
 // Fill in default values for various flag fields
 void nmethod::init_defaults() {
   _state                      = in_use;
-  _unloading_clock            = 0;
   _has_flushed_dependencies   = 0;
-  _has_unsafe_access          = 0;
-  _has_method_handle_invokes  = 0;
-  _lazy_critical_native       = 0;
-  _has_wide_vectors           = 0;
-  _mark_for_deoptimization_status = not_marked;
   _lock_count                 = 0;
   _stack_traversal_mark       = 0;
   _unload_reported            = false; // jvmti state
@@ -579,7 +479,7 @@
   nmethod* nm = NULL;
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    int native_nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
+    int native_nmethod_size = CodeBlob::allocation_size(code_buffer, sizeof(nmethod));
     CodeOffsets offsets;
     offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
     offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
@@ -625,7 +525,7 @@
   nmethod* nm = NULL;
   { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     int nmethod_size =
-      allocation_size(code_buffer, sizeof(nmethod))
+      CodeBlob::allocation_size(code_buffer, sizeof(nmethod))
       + adjust_pcs_size(debug_info->pcs_size())
       + round_to(dependencies->size_in_bytes() , oopSize)
       + round_to(handler_table->size_in_bytes(), oopSize)
@@ -692,31 +592,31 @@
   ByteSize basic_lock_owner_sp_offset,
   ByteSize basic_lock_sp_offset,
   OopMapSet* oop_maps )
-  : CodeBlob("native nmethod", code_buffer, sizeof(nmethod),
-             nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps),
+  : CompiledMethod(method, "native nmethod", nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
   _native_receiver_sp_offset(basic_lock_owner_sp_offset),
   _native_basic_lock_sp_offset(basic_lock_sp_offset)
 {
   {
+    int scopes_data_offset = 0;
+    int deoptimize_offset       = 0;
+    int deoptimize_mh_offset    = 0;
+
     debug_only(NoSafepointVerifier nsv;)
     assert_locked_or_safepoint(CodeCache_lock);
 
     init_defaults();
-    _method                  = method;
     _entry_bci               = InvocationEntryBci;
     // We have no exception handler or deopt handler make the
     // values something that will never match a pc like the nmethod vtable entry
     _exception_offset        = 0;
-    _deoptimize_offset       = 0;
-    _deoptimize_mh_offset    = 0;
     _orig_pc_offset          = 0;
 
     _consts_offset           = data_offset();
     _stub_offset             = data_offset();
     _oops_offset             = data_offset();
     _metadata_offset         = _oops_offset         + round_to(code_buffer->total_oop_size(), oopSize);
-    _scopes_data_offset      = _metadata_offset     + round_to(code_buffer->total_metadata_size(), wordSize);
-    _scopes_pcs_offset       = _scopes_data_offset;
+    scopes_data_offset       = _metadata_offset     + round_to(code_buffer->total_metadata_size(), wordSize);
+    _scopes_pcs_offset       = scopes_data_offset;
     _dependencies_offset     = _scopes_pcs_offset;
     _handler_table_offset    = _dependencies_offset;
     _nul_chk_table_offset    = _handler_table_offset;
@@ -727,9 +627,14 @@
     _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);
     _osr_entry_point         = NULL;
     _exception_cache         = NULL;
-    _pc_desc_cache.reset_to(NULL);
+    _pc_desc_container.reset_to(NULL);
     _hotness_counter         = NMethodSweeper::hotness_counter_reset_val();
 
+    _scopes_data_begin = (address) this + scopes_data_offset;
+    _deopt_handler_begin = (address) this + deoptimize_offset;
+    _deopt_mh_handler_begin = (address) this + deoptimize_mh_offset;
+
+    code_buffer->copy_code_and_locs_to(this);
     code_buffer->copy_values_to(this);
     if (ScavengeRootsInCode) {
       if (detect_scavenge_root_oops()) {
@@ -795,8 +700,7 @@
   Handle speculation_log
 #endif
   )
-  : CodeBlob("nmethod", code_buffer, sizeof(nmethod),
-             nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps),
+  : CompiledMethod(method, "nmethod", nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
   _native_receiver_sp_offset(in_ByteSize(-1)),
   _native_basic_lock_sp_offset(in_ByteSize(-1))
 {
@@ -805,8 +709,10 @@
     debug_only(NoSafepointVerifier nsv;)
     assert_locked_or_safepoint(CodeCache_lock);
 
+    _deopt_handler_begin = (address) this;
+    _deopt_mh_handler_begin = (address) this;
+
     init_defaults();
-    _method                  = method;
     _entry_bci               = entry_bci;
     _compile_id              = compile_id;
     _comp_level              = comp_level;
@@ -830,14 +736,14 @@
         _exception_offset = -1;
       }
       if (offsets->value(CodeOffsets::Deopt) != -1) {
-        _deoptimize_offset       = code_offset()          + offsets->value(CodeOffsets::Deopt);
+        _deopt_handler_begin       = (address) this + code_offset()          + offsets->value(CodeOffsets::Deopt);
       } else {
-        _deoptimize_offset = -1;
+        _deopt_handler_begin = NULL;
       }
       if (offsets->value(CodeOffsets::DeoptMH) != -1) {
-        _deoptimize_mh_offset  = code_offset()          + offsets->value(CodeOffsets::DeoptMH);
+        _deopt_mh_handler_begin  = (address) this + code_offset()          + offsets->value(CodeOffsets::DeoptMH);
       } else {
-        _deoptimize_mh_offset  = -1;
+        _deopt_mh_handler_begin = NULL;
       }
     } else {
 #endif
@@ -845,12 +751,12 @@
     assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set");
     assert(offsets->value(CodeOffsets::Deopt     ) != -1, "must be set");
 
-    _exception_offset        = _stub_offset          + offsets->value(CodeOffsets::Exceptions);
-    _deoptimize_offset       = _stub_offset          + offsets->value(CodeOffsets::Deopt);
+    _exception_offset       = _stub_offset          + offsets->value(CodeOffsets::Exceptions);
+    _deopt_handler_begin    = (address) this + _stub_offset          + offsets->value(CodeOffsets::Deopt);
     if (offsets->value(CodeOffsets::DeoptMH) != -1) {
-      _deoptimize_mh_offset  = _stub_offset          + offsets->value(CodeOffsets::DeoptMH);
+      _deopt_mh_handler_begin  = (address) this + _stub_offset          + offsets->value(CodeOffsets::DeoptMH);
     } else {
-      _deoptimize_mh_offset  = -1;
+      _deopt_mh_handler_begin  = NULL;
 #if INCLUDE_JVMCI
     }
 #endif
@@ -863,20 +769,23 @@
 
     _oops_offset             = data_offset();
     _metadata_offset         = _oops_offset          + round_to(code_buffer->total_oop_size(), oopSize);
-    _scopes_data_offset      = _metadata_offset      + round_to(code_buffer->total_metadata_size(), wordSize);
+    int scopes_data_offset   = _metadata_offset      + round_to(code_buffer->total_metadata_size(), wordSize);
 
-    _scopes_pcs_offset       = _scopes_data_offset   + round_to(debug_info->data_size       (), oopSize);
+    _scopes_pcs_offset       = scopes_data_offset    + round_to(debug_info->data_size       (), oopSize);
     _dependencies_offset     = _scopes_pcs_offset    + adjust_pcs_size(debug_info->pcs_size());
     _handler_table_offset    = _dependencies_offset  + round_to(dependencies->size_in_bytes (), oopSize);
     _nul_chk_table_offset    = _handler_table_offset + round_to(handler_table->size_in_bytes(), oopSize);
     _nmethod_end_offset      = _nul_chk_table_offset + round_to(nul_chk_table->size_in_bytes(), oopSize);
-
     _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
     _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);
     _osr_entry_point         = code_begin()          + offsets->value(CodeOffsets::OSR_Entry);
     _exception_cache         = NULL;
-    _pc_desc_cache.reset_to(scopes_pcs_begin());
+
+    _scopes_data_begin = (address) this + scopes_data_offset;
 
+    _pc_desc_container.reset_to(scopes_pcs_begin());
+
+    code_buffer->copy_code_and_locs_to(this);
     // Copy contents of ScopeDescRecorder to nmethod
     code_buffer->copy_values_to(this);
     debug_info->copy_to(this);
@@ -1052,27 +961,6 @@
   }
 }
 
-bool nmethod::is_at_poll_return(address pc) {
-  RelocIterator iter(this, pc, pc+1);
-  while (iter.next()) {
-    if (iter.type() == relocInfo::poll_return_type)
-      return true;
-  }
-  return false;
-}
-
-
-bool nmethod::is_at_poll_or_poll_return(address pc) {
-  RelocIterator iter(this, pc, pc+1);
-  while (iter.next()) {
-    relocInfo::relocType t = iter.type();
-    if (t == relocInfo::poll_return_type || t == relocInfo::poll_type)
-      return true;
-  }
-  return false;
-}
-
-
 void nmethod::fix_oop_relocations(address begin, address end, bool initialize_immediates) {
   // re-patch all oop-bearing instructions, just in case some oops moved
   RelocIterator iter(this, begin, end);
@@ -1093,101 +981,6 @@
 }
 
 
-void nmethod::verify_oop_relocations() {
-  // Ensure sure that the code matches the current oop values
-  RelocIterator iter(this, NULL, NULL);
-  while (iter.next()) {
-    if (iter.type() == relocInfo::oop_type) {
-      oop_Relocation* reloc = iter.oop_reloc();
-      if (!reloc->oop_is_immediate()) {
-        reloc->verify_oop_relocation();
-      }
-    }
-  }
-}
-
-
-ScopeDesc* nmethod::scope_desc_at(address pc) {
-  PcDesc* pd = pc_desc_at(pc);
-  guarantee(pd != NULL, "scope must be present");
-  return new ScopeDesc(this, pd->scope_decode_offset(),
-                       pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(),
-                       pd->return_oop());
-}
-
-
-void nmethod::clear_inline_caches() {
-  assert(SafepointSynchronize::is_at_safepoint(), "cleaning of IC's only allowed at safepoint");
-  if (is_zombie()) {
-    return;
-  }
-
-  RelocIterator iter(this);
-  while (iter.next()) {
-    iter.reloc()->clear_inline_cache();
-  }
-}
-
-// Clear ICStubs of all compiled ICs
-void nmethod::clear_ic_stubs() {
-  assert_locked_or_safepoint(CompiledIC_lock);
-  RelocIterator iter(this);
-  while(iter.next()) {
-    if (iter.type() == relocInfo::virtual_call_type) {
-      CompiledIC* ic = CompiledIC_at(&iter);
-      ic->clear_ic_stub();
-    }
-  }
-}
-
-void nmethod::cleanup_inline_caches(bool clean_all/*=false*/) {
-  assert_locked_or_safepoint(CompiledIC_lock);
-
-  // If the method is not entrant or zombie then a JMP is plastered over the
-  // first few bytes.  If an oop in the old code was there, that oop
-  // should not get GC'd.  Skip the first few bytes of oops on
-  // not-entrant methods.
-  address low_boundary = verified_entry_point();
-  if (!is_in_use()) {
-    low_boundary += NativeJump::instruction_size;
-    // %%% Note:  On SPARC we patch only a 4-byte trap, not a full NativeJump.
-    // This means that the low_boundary is going to be a little too high.
-    // This shouldn't matter, since oops of non-entrant methods are never used.
-    // In fact, why are we bothering to look at oops in a non-entrant method??
-  }
-
-  // Find all calls in an nmethod and clear the ones that point to non-entrant,
-  // zombie and unloaded nmethods.
-  ResourceMark rm;
-  RelocIterator iter(this, low_boundary);
-  while(iter.next()) {
-    switch(iter.type()) {
-      case relocInfo::virtual_call_type:
-      case relocInfo::opt_virtual_call_type: {
-        CompiledIC *ic = CompiledIC_at(&iter);
-        // Ok, to lookup references to zombies here
-        CodeBlob *cb = CodeCache::find_blob_unsafe(ic->ic_destination());
-        if( cb != NULL && cb->is_nmethod() ) {
-          nmethod* nm = (nmethod*)cb;
-          // Clean inline caches pointing to zombie, non-entrant and unloaded methods
-          if (clean_all || !nm->is_in_use() || (nm->method()->code() != nm)) ic->set_to_clean(is_alive());
-        }
-        break;
-      }
-      case relocInfo::static_call_type: {
-        CompiledStaticCall *csc = compiledStaticCall_at(iter.reloc());
-        CodeBlob *cb = CodeCache::find_blob_unsafe(csc->destination());
-        if( cb != NULL && cb->is_nmethod() ) {
-          nmethod* nm = (nmethod*)cb;
-          // Clean inline caches pointing to zombie, non-entrant and unloaded methods
-          if (clean_all || !nm->is_in_use() || (nm->method()->code() != nm)) csc->set_to_clean();
-        }
-        break;
-      }
-    }
-  }
-}
-
 void nmethod::verify_clean_inline_caches() {
   assert_locked_or_safepoint(CompiledIC_lock);
 
@@ -1213,8 +1006,8 @@
         CompiledIC *ic = CompiledIC_at(&iter);
         // Ok, to lookup references to zombies here
         CodeBlob *cb = CodeCache::find_blob_unsafe(ic->ic_destination());
-        if( cb != NULL && cb->is_nmethod() ) {
-          nmethod* nm = (nmethod*)cb;
+        nmethod* nm = cb->as_nmethod_or_null();
+        if( nm != NULL ) {
           // Verify that inline caches pointing to both zombie and not_entrant methods are clean
           if (!nm->is_in_use() || (nm->method()->code() != nm)) {
             assert(ic->is_clean(), "IC should be clean");
@@ -1225,8 +1018,8 @@
       case relocInfo::static_call_type: {
         CompiledStaticCall *csc = compiledStaticCall_at(iter.reloc());
         CodeBlob *cb = CodeCache::find_blob_unsafe(csc->destination());
-        if( cb != NULL && cb->is_nmethod() ) {
-          nmethod* nm = (nmethod*)cb;
+        nmethod* nm = cb->as_nmethod_or_null();
+        if( nm != NULL ) {
           // Verify that inline caches pointing to both zombie and not_entrant methods are clean
           if (!nm->is_in_use() || (nm->method()->code() != nm)) {
             assert(csc->is_clean(), "IC should be clean");
@@ -1238,27 +1031,6 @@
   }
 }
 
-int nmethod::verify_icholder_relocations() {
-  int count = 0;
-
-  RelocIterator iter(this);
-  while(iter.next()) {
-    if (iter.type() == relocInfo::virtual_call_type) {
-      if (CompiledIC::is_icholder_call_site(iter.virtual_call_reloc())) {
-        CompiledIC *ic = CompiledIC_at(&iter);
-        if (TraceCompiledIC) {
-          tty->print("noticed icholder " INTPTR_FORMAT " ", p2i(ic->cached_icholder()));
-          ic->print();
-        }
-        assert(ic->cached_icholder() != NULL, "must be non-NULL");
-        count++;
-      }
-    }
-  }
-
-  return count;
-}
-
 // This is a private interface with the sweeper.
 void nmethod::mark_as_seen_on_stack() {
   assert(is_alive(), "Must be an alive method");
@@ -1291,23 +1063,6 @@
   mdo->inc_decompile_count();
 }
 
-void nmethod::increase_unloading_clock() {
-  _global_unloading_clock++;
-  if (_global_unloading_clock == 0) {
-    // _nmethods are allocated with _unloading_clock == 0,
-    // so 0 is never used as a clock value.
-    _global_unloading_clock = 1;
-  }
-}
-
-void nmethod::set_unloading_clock(unsigned char unloading_clock) {
-  OrderAccess::release_store((volatile jubyte*)&_unloading_clock, unloading_clock);
-}
-
-unsigned char nmethod::unloading_clock() {
-  return (unsigned char)OrderAccess::load_acquire((volatile jubyte*)&_unloading_clock);
-}
-
 void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) {
 
   post_compiled_method_unload();
@@ -1608,8 +1363,7 @@
   ((SharkCompiler *) compiler())->free_compiled_method(insts_begin());
 #endif // SHARK
 
-  ((CodeBlob*)(this))->flush();
-
+  CodeBlob::flush();
   CodeCache::free(this);
 }
 
@@ -1753,171 +1507,6 @@
   set_unload_reported();
 }
 
-void static clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive) {
-  if (ic->is_icholder_call()) {
-    // The only exception is compiledICHolder oops which may
-    // yet be marked below. (We check this further below).
-    CompiledICHolder* cichk_oop = ic->cached_icholder();
-
-    if (cichk_oop->holder_method()->method_holder()->is_loader_alive(is_alive) &&
-        cichk_oop->holder_klass()->is_loader_alive(is_alive)) {
-      return;
-    }
-  } else {
-    Metadata* ic_oop = ic->cached_metadata();
-    if (ic_oop != NULL) {
-      if (ic_oop->is_klass()) {
-        if (((Klass*)ic_oop)->is_loader_alive(is_alive)) {
-          return;
-        }
-      } else if (ic_oop->is_method()) {
-        if (((Method*)ic_oop)->method_holder()->is_loader_alive(is_alive)) {
-          return;
-        }
-      } else {
-        ShouldNotReachHere();
-      }
-    }
-  }
-
-  ic->set_to_clean();
-}
-
-// This is called at the end of the strong tracing/marking phase of a
-// GC to unload an nmethod if it contains otherwise unreachable
-// oops.
-
-void nmethod::do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred) {
-  // Make sure the oop's ready to receive visitors
-  assert(!is_zombie() && !is_unloaded(),
-         "should not call follow on zombie or unloaded nmethod");
-
-  // If the method is not entrant then a JMP is plastered over the
-  // first few bytes.  If an oop in the old code was there, that oop
-  // should not get GC'd.  Skip the first few bytes of oops on
-  // not-entrant methods.
-  address low_boundary = verified_entry_point();
-  if (is_not_entrant()) {
-    low_boundary += NativeJump::instruction_size;
-    // %%% Note:  On SPARC we patch only a 4-byte trap, not a full NativeJump.
-    // (See comment above.)
-  }
-
-  // The RedefineClasses() API can cause the class unloading invariant
-  // to no longer be true. See jvmtiExport.hpp for details.
-  // Also, leave a debugging breadcrumb in local flag.
-  if (JvmtiExport::has_redefined_a_class()) {
-    // This set of the unloading_occurred flag is done before the
-    // call to post_compiled_method_unload() so that the unloading
-    // of this nmethod is reported.
-    unloading_occurred = true;
-  }
-
-  // Exception cache
-  clean_exception_cache(is_alive);
-
-  // If class unloading occurred we first iterate over all inline caches and
-  // clear ICs where the cached oop is referring to an unloaded klass or method.
-  // The remaining live cached oops will be traversed in the relocInfo::oop_type
-  // iteration below.
-  if (unloading_occurred) {
-    RelocIterator iter(this, low_boundary);
-    while(iter.next()) {
-      if (iter.type() == relocInfo::virtual_call_type) {
-        CompiledIC *ic = CompiledIC_at(&iter);
-        clean_ic_if_metadata_is_dead(ic, is_alive);
-      }
-    }
-  }
-
-  // Compiled code
-  {
-  RelocIterator iter(this, low_boundary);
-  while (iter.next()) {
-    if (iter.type() == relocInfo::oop_type) {
-      oop_Relocation* r = iter.oop_reloc();
-      // In this loop, we must only traverse those oops directly embedded in
-      // the code.  Other oops (oop_index>0) are seen as part of scopes_oops.
-      assert(1 == (r->oop_is_immediate()) +
-                  (r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()),
-             "oop must be found in exactly one place");
-      if (r->oop_is_immediate() && r->oop_value() != NULL) {
-        if (can_unload(is_alive, r->oop_addr(), unloading_occurred)) {
-          return;
-        }
-      }
-    }
-  }
-  }
-
-
-  // Scopes
-  for (oop* p = oops_begin(); p < oops_end(); p++) {
-    if (*p == Universe::non_oop_word())  continue;  // skip non-oops
-    if (can_unload(is_alive, p, unloading_occurred)) {
-      return;
-    }
-  }
-
-#if INCLUDE_JVMCI
-  // Follow JVMCI method
-  BarrierSet* bs = Universe::heap()->barrier_set();
-  if (_jvmci_installed_code != NULL) {
-    if (_jvmci_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_jvmci_installed_code)) {
-      if (!is_alive->do_object_b(_jvmci_installed_code)) {
-        clear_jvmci_installed_code();
-      }
-    } else {
-      if (can_unload(is_alive, (oop*)&_jvmci_installed_code, unloading_occurred)) {
-        return;
-      }
-    }
-  }
-
-  if (_speculation_log != NULL) {
-    if (!is_alive->do_object_b(_speculation_log)) {
-      bs->write_ref_nmethod_pre(&_speculation_log, this);
-      _speculation_log = NULL;
-      bs->write_ref_nmethod_post(&_speculation_log, this);
-    }
-  }
-#endif
-
-
-  // Ensure that all metadata is still alive
-  verify_metadata_loaders(low_boundary, is_alive);
-}
-
-template <class CompiledICorStaticCall>
-static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, BoolObjectClosure *is_alive, nmethod* from) {
-  // Ok, to lookup references to zombies here
-  CodeBlob *cb = CodeCache::find_blob_unsafe(addr);
-  if (cb != NULL && cb->is_nmethod()) {
-    nmethod* nm = (nmethod*)cb;
-
-    if (nm->unloading_clock() != nmethod::global_unloading_clock()) {
-      // The nmethod has not been processed yet.
-      return true;
-    }
-
-    // Clean inline caches pointing to both zombie and not_entrant methods
-    if (!nm->is_in_use() || (nm->method()->code() != nm)) {
-      ic->set_to_clean();
-      assert(ic->is_clean(), "nmethod " PTR_FORMAT "not clean %s", p2i(from), from->method()->name_and_sig_as_C_string());
-    }
-  }
-
-  return false;
-}
-
-static bool clean_if_nmethod_is_unloaded(CompiledIC *ic, BoolObjectClosure *is_alive, nmethod* from) {
-  return clean_if_nmethod_is_unloaded(ic, ic->ic_destination(), is_alive, from);
-}
-
-static bool clean_if_nmethod_is_unloaded(CompiledStaticCall *csc, BoolObjectClosure *is_alive, nmethod* from) {
-  return clean_if_nmethod_is_unloaded(csc, csc->destination(), is_alive, from);
-}
-
 bool nmethod::unload_if_dead_at(RelocIterator* iter_at_oop, BoolObjectClosure *is_alive, bool unloading_occurred) {
   assert(iter_at_oop->type() == relocInfo::oop_type, "Wrong relocation type");
 
@@ -1937,93 +1526,36 @@
   return false;
 }
 
-
-bool nmethod::do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred) {
-  ResourceMark rm;
-
-  // Make sure the oop's ready to receive visitors
-  assert(!is_zombie() && !is_unloaded(),
-         "should not call follow on zombie or unloaded nmethod");
-
-  // If the method is not entrant then a JMP is plastered over the
-  // first few bytes.  If an oop in the old code was there, that oop
-  // should not get GC'd.  Skip the first few bytes of oops on
-  // not-entrant methods.
-  address low_boundary = verified_entry_point();
-  if (is_not_entrant()) {
-    low_boundary += NativeJump::instruction_size;
-    // %%% Note:  On SPARC we patch only a 4-byte trap, not a full NativeJump.
-    // (See comment above.)
-  }
-
-  // The RedefineClasses() API can cause the class unloading invariant
-  // to no longer be true. See jvmtiExport.hpp for details.
-  // Also, leave a debugging breadcrumb in local flag.
-  if (JvmtiExport::has_redefined_a_class()) {
-    // This set of the unloading_occurred flag is done before the
-    // call to post_compiled_method_unload() so that the unloading
-    // of this nmethod is reported.
-    unloading_occurred = true;
-  }
-
-  // Exception cache
-  clean_exception_cache(is_alive);
-
-  bool is_unloaded = false;
-  bool postponed = false;
-
-  RelocIterator iter(this, low_boundary);
-  while(iter.next()) {
-
-    switch (iter.type()) {
-
-    case relocInfo::virtual_call_type:
-      if (unloading_occurred) {
-        // If class unloading occurred we first iterate over all inline caches and
-        // clear ICs where the cached oop is referring to an unloaded klass or method.
-        clean_ic_if_metadata_is_dead(CompiledIC_at(&iter), is_alive);
-      }
-
-      postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
-      break;
-
-    case relocInfo::opt_virtual_call_type:
-      postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
-      break;
-
-    case relocInfo::static_call_type:
-      postponed |= clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), is_alive, this);
-      break;
-
-    case relocInfo::oop_type:
-      if (!is_unloaded) {
-        is_unloaded = unload_if_dead_at(&iter, is_alive, unloading_occurred);
-      }
-      break;
-
-    case relocInfo::metadata_type:
-      break; // nothing to do.
-    }
-  }
-
-  if (is_unloaded) {
-    return postponed;
-  }
-
+bool nmethod::do_unloading_scopes(BoolObjectClosure* is_alive, bool unloading_occurred) {
   // Scopes
   for (oop* p = oops_begin(); p < oops_end(); p++) {
     if (*p == Universe::non_oop_word())  continue;  // skip non-oops
     if (can_unload(is_alive, p, unloading_occurred)) {
-      is_unloaded = true;
-      break;
+      return true;
     }
   }
+  return false;
+}
+
+bool nmethod::do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred) {
+  // Compiled code
+  {
+  RelocIterator iter(this, low_boundary);
+  while (iter.next()) {
+    if (iter.type() == relocInfo::oop_type) {
+      if (unload_if_dead_at(&iter, is_alive, unloading_occurred)) {
+        return true;
+      }
+    }
+  }
+  }
 
-  if (is_unloaded) {
-    return postponed;
-  }
+  return do_unloading_scopes(is_alive, unloading_occurred);
+}
 
 #if INCLUDE_JVMCI
+bool nmethod::do_unloading_jvmci(BoolObjectClosure* is_alive, bool unloading_occurred) {
+  bool is_unloaded = false;
   // Follow JVMCI method
   BarrierSet* bs = Universe::heap()->barrier_set();
   if (_jvmci_installed_code != NULL) {
@@ -2033,7 +1565,7 @@
       }
     } else {
       if (can_unload(is_alive, (oop*)&_jvmci_installed_code, unloading_occurred)) {
-        is_unloaded = true;
+        return true;
       }
     }
   }
@@ -2045,123 +1577,9 @@
       bs->write_ref_nmethod_post(&_speculation_log, this);
     }
   }
-#endif
-
-  // Ensure that all metadata is still alive
-  verify_metadata_loaders(low_boundary, is_alive);
-
-  return postponed;
-}
-
-void nmethod::do_unloading_parallel_postponed(BoolObjectClosure* is_alive, bool unloading_occurred) {
-  ResourceMark rm;
-
-  // Make sure the oop's ready to receive visitors
-  assert(!is_zombie(),
-         "should not call follow on zombie nmethod");
-
-  // If the method is not entrant then a JMP is plastered over the
-  // first few bytes.  If an oop in the old code was there, that oop
-  // should not get GC'd.  Skip the first few bytes of oops on
-  // not-entrant methods.
-  address low_boundary = verified_entry_point();
-  if (is_not_entrant()) {
-    low_boundary += NativeJump::instruction_size;
-    // %%% Note:  On SPARC we patch only a 4-byte trap, not a full NativeJump.
-    // (See comment above.)
-  }
-
-  RelocIterator iter(this, low_boundary);
-  while(iter.next()) {
-
-    switch (iter.type()) {
-
-    case relocInfo::virtual_call_type:
-      clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
-      break;
-
-    case relocInfo::opt_virtual_call_type:
-      clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
-      break;
-
-    case relocInfo::static_call_type:
-      clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), is_alive, this);
-      break;
-    }
-  }
+  return is_unloaded;
 }
-
-#ifdef ASSERT
-
-class CheckClass : AllStatic {
-  static BoolObjectClosure* _is_alive;
-
-  // Check class_loader is alive for this bit of metadata.
-  static void check_class(Metadata* md) {
-    Klass* klass = NULL;
-    if (md->is_klass()) {
-      klass = ((Klass*)md);
-    } else if (md->is_method()) {
-      klass = ((Method*)md)->method_holder();
-    } else if (md->is_methodData()) {
-      klass = ((MethodData*)md)->method()->method_holder();
-    } else {
-      md->print();
-      ShouldNotReachHere();
-    }
-    assert(klass->is_loader_alive(_is_alive), "must be alive");
-  }
- public:
-  static void do_check_class(BoolObjectClosure* is_alive, nmethod* nm) {
-    assert(SafepointSynchronize::is_at_safepoint(), "this is only ok at safepoint");
-    _is_alive = is_alive;
-    nm->metadata_do(check_class);
-  }
-};
-
-// This is called during a safepoint so can use static data
-BoolObjectClosure* CheckClass::_is_alive = NULL;
-#endif // ASSERT
-
-
-// Processing of oop references should have been sufficient to keep
-// all strong references alive.  Any weak references should have been
-// cleared as well.  Visit all the metadata and ensure that it's
-// really alive.
-void nmethod::verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive) {
-#ifdef ASSERT
-    RelocIterator iter(this, low_boundary);
-    while (iter.next()) {
-    // static_stub_Relocations may have dangling references to
-    // Method*s so trim them out here.  Otherwise it looks like
-    // compiled code is maintaining a link to dead metadata.
-    address static_call_addr = NULL;
-    if (iter.type() == relocInfo::opt_virtual_call_type) {
-      CompiledIC* cic = CompiledIC_at(&iter);
-      if (!cic->is_call_to_interpreted()) {
-        static_call_addr = iter.addr();
-      }
-    } else if (iter.type() == relocInfo::static_call_type) {
-      CompiledStaticCall* csc = compiledStaticCall_at(iter.reloc());
-      if (!csc->is_call_to_interpreted()) {
-        static_call_addr = iter.addr();
-      }
-    }
-    if (static_call_addr != NULL) {
-      RelocIterator sciter(this, low_boundary);
-      while (sciter.next()) {
-        if (sciter.type() == relocInfo::static_stub_type &&
-            sciter.static_stub_reloc()->static_call() == static_call_addr) {
-          sciter.static_stub_reloc()->clear_inline_cache();
-        }
-      }
-    }
-  }
-  // Check that the metadata embedded in the nmethod is alive
-  CheckClass::do_check_class(is_alive, this);
 #endif
-}
-
 
 // Iterate over metadata calling this function.   Used by RedefineClasses
 void nmethod::metadata_do(void f(Metadata*)) {
@@ -2360,32 +1778,6 @@
   return detect_scavenge_root.detected_scavenge_root();
 }
 
-// Method that knows how to preserve outgoing arguments at call. This method must be
-// called with a frame corresponding to a Java invoke
-void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) {
-#ifndef SHARK
-  if (method() != NULL && !method()->is_native()) {
-    address pc = fr.pc();
-    SimpleScopeDesc ssd(this, pc);
-    Bytecode_invoke call(ssd.method(), ssd.bci());
-    bool has_receiver = call.has_receiver();
-    bool has_appendix = call.has_appendix();
-    Symbol* signature = call.signature();
-
-    // The method attached by JIT-compilers should be used, if present.
-    // Bytecode can be inaccurate in such case.
-    Method* callee = attached_method_before_pc(pc);
-    if (callee != NULL) {
-      has_receiver = !(callee->access_flags().is_static());
-      has_appendix = false;
-      signature = callee->signature();
-    }
-
-    fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f);
-  }
-#endif // !SHARK
-}
-
 inline bool includes(void* p, void* from, void* to) {
   return from <= p && p < to;
 }
@@ -2415,7 +1807,7 @@
       break;
     }
   }
-  assert(has_method_handle_invokes() == (_deoptimize_mh_offset != -1), "must have deopt mh handler");
+  assert(has_method_handle_invokes() == (_deopt_mh_handler_begin != NULL), "must have deopt mh handler");
 
   int size = count * sizeof(PcDesc);
   assert(scopes_pcs_size() >= size, "oob");
@@ -2441,19 +1833,10 @@
   memcpy(scopes_data_begin(), buffer, size);
 }
 
-// When using JVMCI the address might be off by the size of a call instruction.
-bool nmethod::is_deopt_entry(address pc) {
-  return pc == deopt_handler_begin()
-#if INCLUDE_JVMCI
-    || pc == (deopt_handler_begin() + NativeCall::instruction_size)
-#endif
-    ;
-}
-
 #ifdef ASSERT
-static PcDesc* linear_search(nmethod* nm, int pc_offset, bool approximate) {
-  PcDesc* lower = nm->scopes_pcs_begin();
-  PcDesc* upper = nm->scopes_pcs_end();
+static PcDesc* linear_search(const PcDescSearch& search, int pc_offset, bool approximate) {
+  PcDesc* lower = search.scopes_pcs_begin();
+  PcDesc* upper = search.scopes_pcs_end();
   lower += 1; // exclude initial sentinel
   PcDesc* res = NULL;
   for (PcDesc* p = lower; p < upper; p++) {
@@ -2471,8 +1854,8 @@
 
 
 // Finds a PcDesc with real-pc equal to "pc"
-PcDesc* nmethod::find_pc_desc_internal(address pc, bool approximate) {
-  address base_address = code_begin();
+PcDesc* PcDescContainer::find_pc_desc_internal(address pc, bool approximate, const PcDescSearch& search) {
+  address base_address = search.code_begin();
   if ((pc < base_address) ||
       (pc - base_address) >= (ptrdiff_t) PcDesc::upper_offset_limit) {
     return NULL;  // PC is wildly out of range
@@ -2483,7 +1866,7 @@
   // (This as an almost 100% hit rate.)
   PcDesc* res = _pc_desc_cache.find_pc_desc(pc_offset, approximate);
   if (res != NULL) {
-    assert(res == linear_search(this, pc_offset, approximate), "cache ok");
+    assert(res == linear_search(search, pc_offset, approximate), "cache ok");
     return res;
   }
 
@@ -2491,8 +1874,8 @@
   // Find the last pc_offset less than the given offset.
   // The successor must be the required match, if there is a match at all.
   // (Use a fixed radix to avoid expensive affine pointer arithmetic.)
-  PcDesc* lower = scopes_pcs_begin();
-  PcDesc* upper = scopes_pcs_end();
+  PcDesc* lower = search.scopes_pcs_begin();
+  PcDesc* upper = search.scopes_pcs_end();
   upper -= 1; // exclude final sentinel
   if (lower >= upper)  return NULL;  // native method; no PcDescs at all
 
@@ -2543,11 +1926,11 @@
 #undef assert_LU_OK
 
   if (match_desc(upper, pc_offset, approximate)) {
-    assert(upper == linear_search(this, pc_offset, approximate), "search ok");
+    assert(upper == linear_search(search, pc_offset, approximate), "search ok");
     _pc_desc_cache.add_pc_desc(upper);
     return upper;
   } else {
-    assert(NULL == linear_search(this, pc_offset, approximate), "search ok");
+    assert(NULL == linear_search(search, pc_offset, approximate), "search ok");
     return NULL;
   }
 }
@@ -2701,53 +2084,27 @@
 // QQQ might we make this work from a frame??
 nmethodLocker::nmethodLocker(address pc) {
   CodeBlob* cb = CodeCache::find_blob(pc);
-  guarantee(cb != NULL && cb->is_nmethod(), "bad pc for a nmethod found");
-  _nm = (nmethod*)cb;
+  guarantee(cb != NULL && cb->is_compiled(), "bad pc for a nmethod found");
+  _nm = cb->as_compiled_method();
   lock_nmethod(_nm);
 }
 
 // Only JvmtiDeferredEvent::compiled_method_unload_event()
 // should pass zombie_ok == true.
-void nmethodLocker::lock_nmethod(nmethod* nm, bool zombie_ok) {
-  if (nm == NULL)  return;
+void nmethodLocker::lock_nmethod(CompiledMethod* cm, bool zombie_ok) {
+  if (cm == NULL)  return;
+  nmethod* nm = cm->as_nmethod();
   Atomic::inc(&nm->_lock_count);
   assert(zombie_ok || !nm->is_zombie(), "cannot lock a zombie method");
 }
 
-void nmethodLocker::unlock_nmethod(nmethod* nm) {
-  if (nm == NULL)  return;
+void nmethodLocker::unlock_nmethod(CompiledMethod* cm) {
+  if (cm == NULL)  return;
+  nmethod* nm = cm->as_nmethod();
   Atomic::dec(&nm->_lock_count);
   assert(nm->_lock_count >= 0, "unmatched nmethod lock/unlock");
 }
 
-// -----------------------------------------------------------------------------
-// nmethod::get_deopt_original_pc
-//
-// Return the original PC for the given PC if:
-// (a) the given PC belongs to a nmethod and
-// (b) it is a deopt PC
-address nmethod::get_deopt_original_pc(const frame* fr) {
-  if (fr->cb() == NULL)  return NULL;
-
-  nmethod* nm = fr->cb()->as_nmethod_or_null();
-  if (nm != NULL && nm->is_deopt_pc(fr->pc()))
-    return nm->get_original_pc(fr);
-
-  return NULL;
-}
-
-
-// -----------------------------------------------------------------------------
-// MethodHandle
-
-bool nmethod::is_method_handle_return(address return_pc) {
-  if (!has_method_handle_invokes())  return false;
-  PcDesc* pd = pc_desc_at(return_pc);
-  if (pd == NULL)
-    return false;
-  return pd->is_method_handle_invoke();
-}
-
 
 // -----------------------------------------------------------------------------
 // Verification
@@ -3201,7 +2558,7 @@
   if (block_begin == verified_entry_point())    stream->print_cr("[Verified Entry Point]");
   if (JVMCI_ONLY(_exception_offset >= 0 &&) block_begin == exception_begin())         stream->print_cr("[Exception Handler]");
   if (block_begin == stub_begin())              stream->print_cr("[Stub Code]");
-  if (JVMCI_ONLY(_deoptimize_offset >= 0 &&) block_begin == deopt_handler_begin())     stream->print_cr("[Deopt Handler Code]");
+  if (JVMCI_ONLY(_deopt_handler_begin != NULL &&) block_begin == deopt_handler_begin())     stream->print_cr("[Deopt Handler Code]");
 
   if (has_method_handle_invokes())
     if (block_begin == deopt_mh_handler_begin())  stream->print_cr("[Deopt MH Handler Code]");
@@ -3565,26 +2922,3 @@
 }
 #endif
 
-Method* nmethod::attached_method(address call_instr) {
-  assert(code_contains(call_instr), "not part of the nmethod");
-  RelocIterator iter(this, call_instr, call_instr + 1);
-  while (iter.next()) {
-    if (iter.addr() == call_instr) {
-      switch(iter.type()) {
-        case relocInfo::static_call_type:      return iter.static_call_reloc()->method_value();
-        case relocInfo::opt_virtual_call_type: return iter.opt_virtual_call_reloc()->method_value();
-        case relocInfo::virtual_call_type:     return iter.virtual_call_reloc()->method_value();
-      }
-    }
-  }
-  return NULL; // not found
-}
-
-Method* nmethod::attached_method_before_pc(address pc) {
-  if (NativeCall::is_call_before(pc)) {
-    NativeCall* ncall = nativeCall_before(pc);
-    return attached_method(ncall->instruction_address());
-  }
-  return NULL; // not a call
-}
-
--- a/hotspot/src/share/vm/code/nmethod.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/nmethod.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -25,67 +25,10 @@
 #ifndef SHARE_VM_CODE_NMETHOD_HPP
 #define SHARE_VM_CODE_NMETHOD_HPP
 
-#include "code/codeBlob.hpp"
-#include "code/pcDesc.hpp"
-#include "oops/metadata.hpp"
-
-class DirectiveSet;
-
-// This class is used internally by nmethods, to cache
-// exception/pc/handler information.
-
-class ExceptionCache : public CHeapObj<mtCode> {
-  friend class VMStructs;
- private:
-  enum { cache_size = 16 };
-  Klass*   _exception_type;
-  address  _pc[cache_size];
-  address  _handler[cache_size];
-  volatile int _count;
-  ExceptionCache* _next;
-
-  address pc_at(int index)                     { assert(index >= 0 && index < count(),""); return _pc[index]; }
-  void    set_pc_at(int index, address a)      { assert(index >= 0 && index < cache_size,""); _pc[index] = a; }
-  address handler_at(int index)                { assert(index >= 0 && index < count(),""); return _handler[index]; }
-  void    set_handler_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _handler[index] = a; }
-  int     count()                              { return OrderAccess::load_acquire(&_count); }
-  // increment_count is only called under lock, but there may be concurrent readers.
-  void    increment_count()                    { OrderAccess::release_store(&_count, _count + 1); }
-
- public:
-
-  ExceptionCache(Handle exception, address pc, address handler);
+#include "code/compiledMethod.hpp"
 
-  Klass*    exception_type()                { return _exception_type; }
-  ExceptionCache* next()                    { return _next; }
-  void      set_next(ExceptionCache *ec)    { _next = ec; }
-
-  address match(Handle exception, address pc);
-  bool    match_exception_with_space(Handle exception) ;
-  address test_address(address addr);
-  bool    add_address_and_handler(address addr, address handler) ;
-};
-
-
-// cache pc descs found in earlier inquiries
-class PcDescCache VALUE_OBJ_CLASS_SPEC {
-  friend class VMStructs;
- private:
-  enum { cache_size = 4 };
-  // The array elements MUST be volatile! Several threads may modify
-  // and read from the cache concurrently. find_pc_desc_internal has
-  // returned wrong results. C++ compiler (namely xlC12) may duplicate
-  // C++ field accesses if the elements are not volatile.
-  typedef PcDesc* PcDescPtr;
-  volatile PcDescPtr _pc_descs[cache_size]; // last cache_size pc_descs found
- public:
-  PcDescCache() { debug_only(_pc_descs[0] = NULL); }
-  void    reset_to(PcDesc* initial_pc_desc);
-  PcDesc* find_pc_desc(int pc_offset, bool approximate);
-  void    add_pc_desc(PcDesc* pc_desc);
-  PcDesc* last_pc_desc() { return _pc_descs[0]; }
-};
-
+class DepChange;
+class DirectiveSet;
 
 // nmethods (native methods) are the compiled code versions of Java methods.
 //
@@ -108,26 +51,14 @@
 //  [Implicit Null Pointer exception table]
 //  - implicit null table array
 
-class DepChange;
-class Dependencies;
-class ExceptionHandlerTable;
-class ImplicitExceptionTable;
-class AbstractCompiler;
-class xmlStream;
-
-class nmethod : public CodeBlob {
+class nmethod : public CompiledMethod {
   friend class VMStructs;
   friend class JVMCIVMStructs;
   friend class NMethodSweeper;
   friend class CodeCache;  // scavengable oops
  private:
 
-  // GC support to help figure out if an nmethod has been
-  // cleaned/unloaded by the current GC.
-  static unsigned char _global_unloading_clock;
-
   // Shared fields for all nmethod's
-  Method*   _method;
   int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
   jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
 
@@ -140,13 +71,6 @@
   // To support simple linked-list chaining of nmethods:
   nmethod*  _osr_link;         // from InstanceKlass::osr_nmethods_head
 
-  union {
-    // Used by G1 to chain nmethods.
-    nmethod* _unloading_next;
-    // Used by non-G1 GCs to chain nmethods.
-    nmethod* _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
-  };
-
   static nmethod* volatile _oops_do_mark_nmethods;
   nmethod*        volatile _oops_do_mark_link;
 
@@ -158,13 +82,7 @@
   address _osr_entry_point;                  // entry point for on stack replacement
 
   // Offsets for different nmethod parts
-  int _exception_offset;
-  // All deoptee's will resume execution at this location described by
-  // this offset.
-  int _deoptimize_offset;
-  // All deoptee's at a MethodHandle call site will resume execution
-  // at this location described by this offset.
-  int _deoptimize_mh_offset;
+  int  _exception_offset;
   // Offset of the unwind handler if it exists
   int _unwind_handler_offset;
 
@@ -179,6 +97,8 @@
   int _nul_chk_table_offset;
   int _nmethod_end_offset;
 
+  int code_offset() const { return (address) code_begin() - header_begin(); }
+
   // location in frame (offset for sp) that deopt can store the original
   // pc during a deopt.
   int _orig_pc_offset;
@@ -189,27 +109,12 @@
   // protected by CodeCache_lock
   bool _has_flushed_dependencies;            // Used for maintenance of dependencies (CodeCache_lock)
 
-  enum MarkForDeoptimizationStatus {
-    not_marked,
-    deoptimize,
-    deoptimize_noupdate };
-
-  MarkForDeoptimizationStatus _mark_for_deoptimization_status; // Used for stack deoptimization
-
   // used by jvmti to track if an unload event has been posted for this nmethod.
   bool _unload_reported;
 
-  // set during construction
-  unsigned int _has_unsafe_access:1;         // May fault due to unsafe access.
-  unsigned int _has_method_handle_invokes:1; // Has this method MethodHandle invokes?
-  unsigned int _lazy_critical_native:1;      // Lazy JNI critical native
-  unsigned int _has_wide_vectors:1;          // Preserve wide vectors at safepoints
-
   // Protected by Patching_lock
   volatile unsigned char _state;             // {in_use, not_entrant, zombie, unloaded}
 
-  volatile unsigned char _unloading_clock;   // Incremented after GC unloaded/cleaned the nmethod
-
 #ifdef ASSERT
   bool _oops_are_stale;  // indicates that it's no longer safe to access oops section
 #endif
@@ -242,9 +147,6 @@
   // counter is decreased (by 1) while sweeping.
   int _hotness_counter;
 
-  ExceptionCache * volatile _exception_cache;
-  PcDescCache     _pc_desc_cache;
-
   // These are used for compiled synchronized native methods to
   // locate the owner and stack slot for the BasicLock so that we can
   // properly revoke the bias of the owner if necessary. They are
@@ -302,18 +204,21 @@
   // Returns true if this thread changed the state of the nmethod or
   // false if another thread performed the transition.
   bool make_not_entrant_or_zombie(unsigned int state);
+  bool make_entrant() { Unimplemented(); return false; }
   void inc_decompile_count();
 
-  // Used to manipulate the exception cache
-  void add_exception_cache_entry(ExceptionCache* new_entry);
-  ExceptionCache* exception_cache_entry_for_exception(Handle exception);
-
   // Inform external interfaces that a compiled method has been unloaded
   void post_compiled_method_unload();
 
   // Initailize fields to their default values
   void init_defaults();
 
+  // Offsets
+  int content_offset() const                  { return content_begin() - header_begin(); }
+  int data_offset() const                     { return _data_offset; }
+
+  address header_end() const                  { return (address)    header_begin() + header_size(); }
+
  public:
   // create nmethod with entry_bci
   static nmethod* new_nmethod(const methodHandle& method,
@@ -334,7 +239,7 @@
                               , Handle installed_code = Handle(),
                               Handle speculation_log = Handle()
 #endif
-                             );
+  );
 
   static nmethod* new_native_nmethod(const methodHandle& method,
                                      int compile_id,
@@ -347,13 +252,10 @@
                                      OopMapSet* oop_maps);
 
   // accessors
-  Method* method() const                          { return _method; }
   AbstractCompiler* compiler() const              { return _compiler; }
 
   // type info
   bool is_nmethod() const                         { return true; }
-  bool is_java_method() const                     { return !method()->is_native(); }
-  bool is_native_method() const                   { return method()->is_native(); }
   bool is_osr_method() const                      { return _entry_bci != InvocationEntryBci; }
 
   bool is_compiled_by_c1() const;
@@ -363,22 +265,17 @@
 
   // boundaries for different parts
   address consts_begin          () const          { return           header_begin() + _consts_offset        ; }
-  address consts_end            () const          { return           header_begin() +  code_offset()        ; }
-  address insts_begin           () const          { return           header_begin() +  code_offset()        ; }
-  address insts_end             () const          { return           header_begin() + _stub_offset          ; }
+  address consts_end            () const          { return           code_begin()                           ; }
   address stub_begin            () const          { return           header_begin() + _stub_offset          ; }
   address stub_end              () const          { return           header_begin() + _oops_offset          ; }
   address exception_begin       () const          { return           header_begin() + _exception_offset     ; }
-  address deopt_handler_begin   () const          { return           header_begin() + _deoptimize_offset    ; }
-  address deopt_mh_handler_begin() const          { return           header_begin() + _deoptimize_mh_offset ; }
   address unwind_handler_begin  () const          { return _unwind_handler_offset != -1 ? (header_begin() + _unwind_handler_offset) : NULL; }
   oop*    oops_begin            () const          { return (oop*)   (header_begin() + _oops_offset)         ; }
   oop*    oops_end              () const          { return (oop*)   (header_begin() + _metadata_offset)     ; }
 
   Metadata** metadata_begin   () const            { return (Metadata**)  (header_begin() + _metadata_offset)     ; }
-  Metadata** metadata_end     () const            { return (Metadata**)  (header_begin() + _scopes_data_offset)  ; }
+  Metadata** metadata_end     () const            { return (Metadata**)  _scopes_data_begin; }
 
-  address scopes_data_begin     () const          { return           header_begin() + _scopes_data_offset   ; }
   address scopes_data_end       () const          { return           header_begin() + _scopes_pcs_offset    ; }
   PcDesc* scopes_pcs_begin      () const          { return (PcDesc*)(header_begin() + _scopes_pcs_offset   ); }
   PcDesc* scopes_pcs_end        () const          { return (PcDesc*)(header_begin() + _dependencies_offset) ; }
@@ -390,16 +287,9 @@
   address nul_chk_table_end     () const          { return           header_begin() + _nmethod_end_offset   ; }
 
   // Sizes
-  int consts_size       () const                  { return            consts_end       () -            consts_begin       (); }
-  int insts_size        () const                  { return            insts_end        () -            insts_begin        (); }
-  int stub_size         () const                  { return            stub_end         () -            stub_begin         (); }
   int oops_size         () const                  { return (address)  oops_end         () - (address)  oops_begin         (); }
   int metadata_size     () const                  { return (address)  metadata_end     () - (address)  metadata_begin     (); }
-  int scopes_data_size  () const                  { return            scopes_data_end  () -            scopes_data_begin  (); }
-  int scopes_pcs_size   () const                  { return (intptr_t) scopes_pcs_end   () - (intptr_t) scopes_pcs_begin   (); }
   int dependencies_size () const                  { return            dependencies_end () -            dependencies_begin (); }
-  int handler_table_size() const                  { return            handler_table_end() -            handler_table_begin(); }
-  int nul_chk_table_size() const                  { return            nul_chk_table_end() -            nul_chk_table_begin(); }
 
   int     oops_count() const { assert(oops_size() % oopSize == 0, "");  return (oops_size() / oopSize) + 1; }
   int metadata_count() const { assert(metadata_size() % wordSize == 0, ""); return (metadata_size() / wordSize) + 1; }
@@ -411,15 +301,10 @@
   int  hotness_counter() const      { return _hotness_counter; }
 
   // Containment
-  bool consts_contains       (address addr) const { return consts_begin       () <= addr && addr < consts_end       (); }
-  bool insts_contains        (address addr) const { return insts_begin        () <= addr && addr < insts_end        (); }
-  bool stub_contains         (address addr) const { return stub_begin         () <= addr && addr < stub_end         (); }
   bool oops_contains         (oop*    addr) const { return oops_begin         () <= addr && addr < oops_end         (); }
   bool metadata_contains     (Metadata** addr) const   { return metadata_begin     () <= addr && addr < metadata_end     (); }
   bool scopes_data_contains  (address addr) const { return scopes_data_begin  () <= addr && addr < scopes_data_end  (); }
   bool scopes_pcs_contains   (PcDesc* addr) const { return scopes_pcs_begin   () <= addr && addr < scopes_pcs_end   (); }
-  bool handler_table_contains(address addr) const { return handler_table_begin() <= addr && addr < handler_table_end(); }
-  bool nul_chk_table_contains(address addr) const { return nul_chk_table_begin() <= addr && addr < nul_chk_table_end(); }
 
   // entry points
   address entry_point() const                     { return _entry_point;             } // normal entry point
@@ -434,24 +319,11 @@
 
   // flag accessing and manipulation
   bool  is_in_use() const                         { return _state == in_use; }
-  bool  is_alive() const                          { unsigned char s = _state; return s == in_use || s == not_entrant; }
+  bool  is_alive() const                          { unsigned char s = _state; return s < zombie; }
   bool  is_not_entrant() const                    { return _state == not_entrant; }
   bool  is_zombie() const                         { return _state == zombie; }
   bool  is_unloaded() const                       { return _state == unloaded; }
 
-  // returns a string version of the nmethod state
-  const char* state() const {
-    switch(_state) {
-      case in_use:      return "in use";
-      case not_entrant: return "not_entrant";
-      case zombie:      return "zombie";
-      case unloaded:    return "unloaded";
-      default:
-        fatal("unexpected nmethod state: %d", _state);
-        return NULL;
-    }
-  }
-
 #if INCLUDE_RTM_OPT
   // rtm state accessing and manipulating
   RTMState  rtm_state() const                     { return _rtm_state; }
@@ -466,30 +338,15 @@
     assert(!method()->is_method_handle_intrinsic(), "Cannot make MH intrinsic not entrant");
     return make_not_entrant_or_zombie(not_entrant);
   }
+  bool  make_not_used()    { return make_not_entrant(); }
   bool  make_zombie()      { return make_not_entrant_or_zombie(zombie); }
 
   // used by jvmti to track if the unload event has been reported
   bool  unload_reported()                         { return _unload_reported; }
   void  set_unload_reported()                     { _unload_reported = true; }
 
-  void set_unloading_next(nmethod* next)          { _unloading_next = next; }
-  nmethod* unloading_next()                       { return _unloading_next; }
-
-  static unsigned char global_unloading_clock()   { return _global_unloading_clock; }
-  static void increase_unloading_clock();
-
-  void set_unloading_clock(unsigned char unloading_clock);
-  unsigned char unloading_clock();
-
-  bool  is_marked_for_deoptimization() const      { return _mark_for_deoptimization_status != not_marked; }
-  void  mark_for_deoptimization(bool inc_recompile_counts = true) {
-    _mark_for_deoptimization_status = (inc_recompile_counts ? deoptimize : deoptimize_noupdate);
-  }
-  bool update_recompile_counts() const {
-    // Update recompile counts when either the update is explicitly requested (deoptimize)
-    // or the nmethod is not marked for deoptimization at all (not_marked).
-    // The latter happens during uncommon traps when deoptimized nmethod is made not entrant.
-    return _mark_for_deoptimization_status != deoptimize_noupdate;
+  int get_state() const {
+    return _state;
   }
 
   void  make_unloaded(BoolObjectClosure* is_alive, oop cause);
@@ -502,18 +359,6 @@
     _has_flushed_dependencies = 1;
   }
 
-  bool  has_unsafe_access() const                 { return _has_unsafe_access; }
-  void  set_has_unsafe_access(bool z)             { _has_unsafe_access = z; }
-
-  bool  has_method_handle_invokes() const         { return _has_method_handle_invokes; }
-  void  set_has_method_handle_invokes(bool z)     { _has_method_handle_invokes = z; }
-
-  bool  is_lazy_critical_native() const           { return _lazy_critical_native; }
-  void  set_lazy_critical_native(bool z)          { _lazy_critical_native = z; }
-
-  bool  has_wide_vectors() const                  { return _has_wide_vectors; }
-  void  set_has_wide_vectors(bool z)              { _has_wide_vectors = z; }
-
   int   comp_level() const                        { return _comp_level; }
 
   // Support for oops in scopes and relocs:
@@ -538,9 +383,6 @@
   void copy_values(GrowableArray<jobject>* oops);
   void copy_values(GrowableArray<Metadata*>* metadata);
 
-  Method* attached_method(address call_pc);
-  Method* attached_method_before_pc(address pc);
-
   // Relocation support
 private:
   void fix_oop_relocations(address begin, address end, bool initialize_immediates);
@@ -549,10 +391,6 @@
 public:
   void fix_oop_relocations(address begin, address end) { fix_oop_relocations(begin, end, false); }
   void fix_oop_relocations()                           { fix_oop_relocations(NULL, NULL, false); }
-  void verify_oop_relocations();
-
-  bool is_at_poll_return(address pc);
-  bool is_at_poll_or_poll_return(address pc);
 
   // Scavengable oop support
   bool  on_scavenge_root_list() const                  { return (_scavenge_root_state & 1) != 0; }
@@ -576,15 +414,6 @@
   long  stack_traversal_mark()                    { return _stack_traversal_mark; }
   void  set_stack_traversal_mark(long l)          { _stack_traversal_mark = l; }
 
-  // Exception cache support
-  // Note: _exception_cache may be read concurrently. We rely on memory_order_consume here.
-  ExceptionCache* exception_cache() const         { return _exception_cache; }
-  void set_exception_cache(ExceptionCache *ec)    { _exception_cache = ec; }
-  void release_set_exception_cache(ExceptionCache *ec) { OrderAccess::release_store_ptr(&_exception_cache, ec); }
-  address handler_for_exception_and_pc(Handle exception, address pc);
-  void add_handler_for_exception_and_pc(Handle exception, address pc, address handler);
-  void clean_exception_cache(BoolObjectClosure* is_alive);
-
   // implicit exceptions support
   address continuation_for_implicit_exception(address pc);
 
@@ -595,24 +424,8 @@
   nmethod* osr_link() const                       { return _osr_link; }
   void     set_osr_link(nmethod *n)               { _osr_link = n; }
 
-  // tells whether frames described by this nmethod can be deoptimized
-  // note: native wrappers cannot be deoptimized.
-  bool can_be_deoptimized() const { return is_java_method(); }
-
-  // Inline cache support
-  void clear_inline_caches();
-  void clear_ic_stubs();
-  void cleanup_inline_caches(bool clean_all = false);
-  bool inlinecache_check_contains(address addr) const {
-    return (addr >= code_begin() && addr < verified_entry_point());
-  }
-
   // Verify calls to dead methods have been cleaned.
   void verify_clean_inline_caches();
-  // Verify and count cached icholder relocations.
-  int  verify_icholder_relocations();
-  // Check that all metadata is still alive
-  void verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive);
 
   // unlink and deallocate this nmethod
   // Only NMethodSweeper class is expected to use this. NMethodSweeper is not
@@ -653,20 +466,19 @@
  public:
 #endif
 
-  // GC support
-  void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);
-  //  The parallel versions are used by G1.
-  bool do_unloading_parallel(BoolObjectClosure* is_alive, bool unloading_occurred);
-  void do_unloading_parallel_postponed(BoolObjectClosure* is_alive, bool unloading_occurred);
+ protected:
+  virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred);
+#if INCLUDE_JVMCI
+  virtual bool do_unloading_jvmci(BoolObjectClosure* is_alive, bool unloading_occurred);
+#endif
 
  private:
+  bool do_unloading_scopes(BoolObjectClosure* is_alive, bool unloading_occurred);
   //  Unload a nmethod if the *root object is dead.
   bool can_unload(BoolObjectClosure* is_alive, oop* root, bool unloading_occurred);
   bool unload_if_dead_at(RelocIterator *iter_at_oop, BoolObjectClosure* is_alive, bool unloading_occurred);
 
  public:
-  void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map,
-                                     OopClosure* f);
   void oops_do(OopClosure* f) { oops_do(f, false); }
   void oops_do(OopClosure* f, bool allow_zombie);
   bool detect_scavenge_root_oops();
@@ -678,49 +490,20 @@
   static bool oops_do_marking_is_active() { return _oops_do_mark_nmethods != NULL; }
   bool test_oops_do_mark() { return _oops_do_mark_link != NULL; }
 
-  // ScopeDesc for an instruction
-  ScopeDesc* scope_desc_at(address pc);
-
  private:
   ScopeDesc* scope_desc_in(address begin, address end);
 
   address* orig_pc_addr(const frame* fr) { return (address*) ((address)fr->unextended_sp() + _orig_pc_offset); }
 
-  PcDesc* find_pc_desc_internal(address pc, bool approximate);
-
-  PcDesc* find_pc_desc(address pc, bool approximate) {
-    PcDesc* desc = _pc_desc_cache.last_pc_desc();
-    if (desc != NULL && desc->pc_offset() == pc - code_begin()) {
-      return desc;
-    }
-    return find_pc_desc_internal(pc, approximate);
-  }
-
- public:
-  // ScopeDesc retrieval operation
-  PcDesc* pc_desc_at(address pc)   { return find_pc_desc(pc, false); }
-  // pc_desc_near returns the first PcDesc at or after the givne pc.
-  PcDesc* pc_desc_near(address pc) { return find_pc_desc(pc, true); }
-
  public:
   // copying of debugging information
   void copy_scopes_pcs(PcDesc* pcs, int count);
   void copy_scopes_data(address buffer, int size);
 
-  // Deopt
-  // Return true is the PC is one would expect if the frame is being deopted.
-  bool is_deopt_pc      (address pc) { return is_deopt_entry(pc) || is_deopt_mh_entry(pc); }
-  bool is_deopt_entry   (address pc);
-  bool is_deopt_mh_entry(address pc) { return pc == deopt_mh_handler_begin(); }
   // Accessor/mutator for the original pc of a frame before a frame was deopted.
   address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); }
   void    set_original_pc(const frame* fr, address pc) { *orig_pc_addr(fr) = pc; }
 
-  static address get_deopt_original_pc(const frame* fr);
-
-  // MethodHandle
-  bool is_method_handle_return(address return_pc);
-
   // jvmti support:
   void post_compiled_method_load_event();
   jmethodID get_and_cache_jmethod_id();
@@ -770,7 +553,7 @@
   // are numbered in an independent sequence if CICountOSR is true,
   // and native method wrappers are also numbered independently if
   // CICountNative is true.
-  int  compile_id() const                         { return _compile_id; }
+  virtual int compile_id() const { return _compile_id; }
   const char* compile_kind() const;
 
   // tells if any of this method's dependencies have been invalidated
@@ -789,7 +572,7 @@
   // Fast breakpoint support. Tells if this compiled method is
   // dependent on the given method. Returns true if this nmethod
   // corresponds to the given method as well.
-  bool is_dependent_on_method(Method* dependee);
+  virtual bool is_dependent_on_method(Method* dependee);
 
   // is it ok to patch at address?
   bool is_patchable_at(address instr_address);
@@ -807,12 +590,7 @@
   static int osr_entry_point_offset()             { return offset_of(nmethod, _osr_entry_point); }
   static int state_offset()                       { return offset_of(nmethod, _state); }
 
-  // RedefineClasses support.   Mark metadata in nmethods as on_stack so that
-  // redefine classes doesn't purge it.
-  static void mark_on_stack(nmethod* nm) {
-    nm->metadata_do(Metadata::mark_on_stack);
-  }
-  void metadata_do(void f(Metadata*));
+  virtual void metadata_do(void f(Metadata*));
 };
 
 // Locks an nmethod so its code will not get removed and it will not
@@ -821,26 +599,43 @@
 // needs to be done, then lock_nmethod() is used directly to keep the
 // generated code from being reused too early.
 class nmethodLocker : public StackObj {
-  nmethod* _nm;
+  CompiledMethod* _nm;
 
  public:
 
   // note: nm can be NULL
   // Only JvmtiDeferredEvent::compiled_method_unload_event()
   // should pass zombie_ok == true.
-  static void lock_nmethod(nmethod* nm, bool zombie_ok = false);
-  static void unlock_nmethod(nmethod* nm); // (ditto)
+  static void lock_nmethod(CompiledMethod* nm, bool zombie_ok = false);
+  static void unlock_nmethod(CompiledMethod* nm); // (ditto)
 
   nmethodLocker(address pc); // derive nm from pc
   nmethodLocker(nmethod *nm) { _nm = nm; lock_nmethod(_nm); }
-  nmethodLocker() { _nm = NULL; }
-  ~nmethodLocker() { unlock_nmethod(_nm); }
+  nmethodLocker(CompiledMethod *nm) {
+    _nm = nm;
+    lock(_nm);
+  }
+
+  static void lock(CompiledMethod* method) {
+    if (method == NULL) return;
+    lock_nmethod(method);
+  }
 
-  nmethod* code() { return _nm; }
-  void set_code(nmethod* new_nm) {
-    unlock_nmethod(_nm);   // note:  This works even if _nm==new_nm.
+  static void unlock(CompiledMethod* method) {
+    if (method == NULL) return;
+    unlock_nmethod(method);
+  }
+
+  nmethodLocker() { _nm = NULL; }
+  ~nmethodLocker() {
+    unlock(_nm);
+  }
+
+  CompiledMethod* code() { return _nm; }
+  void set_code(CompiledMethod* new_nm) {
+    unlock(_nm);   // note:  This works even if _nm==new_nm.
     _nm = new_nm;
-    lock_nmethod(_nm);
+    lock(_nm);
   }
 };
 
--- a/hotspot/src/share/vm/code/pcDesc.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/pcDesc.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,11 +36,11 @@
   _flags               = 0;
 }
 
-address PcDesc::real_pc(const nmethod* code) const {
+address PcDesc::real_pc(const CompiledMethod* code) const {
   return code->code_begin() + pc_offset();
 }
 
-void PcDesc::print(nmethod* code) {
+void PcDesc::print(CompiledMethod* code) {
 #ifndef PRODUCT
   ResourceMark rm;
   tty->print_cr("PcDesc(pc=" PTR_FORMAT " offset=%x bits=%x):", p2i(real_pc(code)), pc_offset(), _flags);
@@ -57,7 +57,7 @@
 #endif
 }
 
-bool PcDesc::verify(nmethod* code) {
+bool PcDesc::verify(CompiledMethod* code) {
   //Unimplemented();
   return true;
 }
--- a/hotspot/src/share/vm/code/pcDesc.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/pcDesc.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
 // PcDescs map a physical PC (given as offset from start of nmethod) to
 // the corresponding source scope and byte code index.
 
-class nmethod;
+class CompiledMethod;
 
 class PcDesc VALUE_OBJ_CLASS_SPEC {
   friend class VMStructs;
@@ -91,10 +91,10 @@
   void set_return_oop(bool z)                    { set_flag(PCDESC_return_oop, z); }
 
   // Returns the real pc
-  address real_pc(const nmethod* code) const;
+  address real_pc(const CompiledMethod* code) const;
 
-  void print(nmethod* code);
-  bool verify(nmethod* code);
+  void print(CompiledMethod* code);
+  bool verify(CompiledMethod* code);
 };
 
 #endif // SHARE_VM_CODE_PCDESC_HPP
--- a/hotspot/src/share/vm/code/relocInfo.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/relocInfo.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -81,7 +81,6 @@
   return (relocInfo*)prefix_limit;
 }
 
-
 void relocInfo::set_type(relocType t) {
   int old_offset = addr_offset();
   int old_format = format();
@@ -91,6 +90,9 @@
   assert(format()==old_format, "sanity check");
 }
 
+nmethod* RelocIterator::code_as_nmethod() const {
+  return _code->as_nmethod();
+}
 
 void relocInfo::set_format(int f) {
   int old_offset = addr_offset();
@@ -121,13 +123,13 @@
 // ----------------------------------------------------------------------------------------------------
 // Implementation of RelocIterator
 
-void RelocIterator::initialize(nmethod* nm, address begin, address limit) {
+void RelocIterator::initialize(CompiledMethod* nm, address begin, address limit) {
   initialize_misc();
 
   if (nm == NULL && begin != NULL) {
     // allow nmethod to be deduced from beginning address
     CodeBlob* cb = CodeCache::find_blob(begin);
-    nm = cb->as_nmethod_or_null();
+    nm = cb->as_compiled_method_or_null();
   }
   assert(nm != NULL, "must be able to deduce nmethod from other arguments");
 
--- a/hotspot/src/share/vm/code/relocInfo.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/relocInfo.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
 #include "memory/allocation.hpp"
 #include "runtime/os.hpp"
 
+class nmethod;
+class CompiledMethod;
 class Metadata;
 class NativeMovConstReg;
 
@@ -539,7 +541,7 @@
   address         _limit;   // stop producing relocations after this _addr
   relocInfo*      _current; // the current relocation information
   relocInfo*      _end;     // end marker; we're done iterating when _current == _end
-  nmethod*        _code;    // compiled method containing _addr
+  CompiledMethod* _code;    // compiled method containing _addr
   address         _addr;    // instruction to which the relocation applies
   short           _databuf; // spare buffer for compressed data
   short*          _data;    // pointer to the relocation's data
@@ -570,13 +572,13 @@
 
   void initialize_misc();
 
-  void initialize(nmethod* nm, address begin, address limit);
+  void initialize(CompiledMethod* nm, address begin, address limit);
 
   RelocIterator() { initialize_misc(); }
 
  public:
   // constructor
-  RelocIterator(nmethod* nm, address begin = NULL, address limit = NULL);
+  RelocIterator(CompiledMethod* nm, address begin = NULL, address limit = NULL);
   RelocIterator(CodeSection* cb, address begin = NULL, address limit = NULL);
 
   // get next reloc info, return !eos
@@ -611,7 +613,8 @@
   relocType    type()         const { return current()->type(); }
   int          format()       const { return (relocInfo::have_format) ? current()->format() : 0; }
   address      addr()         const { return _addr; }
-  nmethod*     code()         const { return _code; }
+  CompiledMethod*     code()  const { return _code; }
+  nmethod*     code_as_nmethod() const;
   short*       data()         const { return _data; }
   int          datalen()      const { return _datalen; }
   bool     has_current()      const { return _datalen >= 0; }
@@ -810,9 +813,10 @@
 
  public:
   // accessors which only make sense for a bound Relocation
-  address  addr()         const { return binding()->addr(); }
-  nmethod* code()         const { return binding()->code(); }
-  bool     addr_in_const() const { return binding()->addr_in_const(); }
+  address         addr()            const { return binding()->addr(); }
+  CompiledMethod* code()            const { return binding()->code(); }
+  nmethod*        code_as_nmethod() const { return binding()->code_as_nmethod(); }
+  bool            addr_in_const()   const { return binding()->addr_in_const(); }
  protected:
   short*   data()         const { return binding()->data(); }
   int      datalen()      const { return binding()->datalen(); }
@@ -1371,7 +1375,7 @@
 APPLY_TO_RELOCATIONS(EACH_CASE);
 #undef EACH_CASE
 
-inline RelocIterator::RelocIterator(nmethod* nm, address begin, address limit) {
+inline RelocIterator::RelocIterator(CompiledMethod* nm, address begin, address limit) {
   initialize(nm, begin, limit);
 }
 
--- a/hotspot/src/share/vm/code/scopeDesc.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/scopeDesc.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
 
-ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) {
+ScopeDesc::ScopeDesc(const CompiledMethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) {
   _code          = code;
   _decode_offset = decode_offset;
   _objects       = decode_object_values(obj_decode_offset);
@@ -40,7 +40,7 @@
   decode_body();
 }
 
-ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) {
+ScopeDesc::ScopeDesc(const CompiledMethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) {
   _code          = code;
   _decode_offset = decode_offset;
   _objects       = decode_object_values(DebugInformationRecorder::serialized_null);
--- a/hotspot/src/share/vm/code/scopeDesc.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/scopeDesc.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@
   int _bci;
 
  public:
-  SimpleScopeDesc(nmethod* code, address pc) {
+  SimpleScopeDesc(CompiledMethod* code, address pc) {
     PcDesc* pc_desc = code->pc_desc_at(pc);
     assert(pc_desc != NULL, "Must be able to find matching PcDesc");
     DebugInfoReadStream buffer(code, pc_desc->scope_decode_offset());
@@ -60,12 +60,12 @@
 class ScopeDesc : public ResourceObj {
  public:
   // Constructor
-  ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
+  ScopeDesc(const CompiledMethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
 
   // Calls above, giving default value of "serialized_null" to the
   // "obj_decode_offset" argument.  (We don't use a default argument to
   // avoid a .hpp-.hpp dependency.)
-  ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
+  ScopeDesc(const CompiledMethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
 
   // JVM state
   Method* method()      const { return _method; }
@@ -110,7 +110,7 @@
   GrowableArray<ScopeValue*>* _objects;
 
   // Nmethod information
-  const nmethod* _code;
+  const CompiledMethod* _code;
 
   // Decoding operations
   void decode_body();
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1075,10 +1075,10 @@
 
   if (osr_bci == InvocationEntryBci) {
     // standard compilation
-    nmethod* method_code = method->code();
-    if (method_code != NULL) {
+    CompiledMethod* method_code = method->code();
+    if (method_code != NULL && method_code->is_nmethod()) {
       if (compilation_is_complete(method, osr_bci, comp_level)) {
-        return method_code;
+        return (nmethod*) method_code;
       }
     }
     if (method->is_not_compilable(comp_level)) {
@@ -1184,7 +1184,12 @@
   // return requested nmethod
   // We accept a higher level osr method
   if (osr_bci == InvocationEntryBci) {
-    return method->code();
+    CompiledMethod* code = method->code();
+    if (code == NULL) {
+      return (nmethod*) code;
+    } else {
+      return code->as_nmethod_or_null();
+    }
   }
   return method->lookup_osr_nmethod_for(osr_bci, comp_level, false);
 }
@@ -1209,7 +1214,7 @@
     if (method->is_not_compilable(comp_level)) {
       return true;
     } else {
-      nmethod* result = method->code();
+      CompiledMethod* result = method->code();
       if (result == NULL) return false;
       return comp_level == result->comp_level();
     }
--- a/hotspot/src/share/vm/compiler/compileTask.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/compiler/compileTask.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -135,7 +135,11 @@
 //
 nmethod* CompileTask::code() const {
   if (_code_handle == NULL)  return NULL;
-  return _code_handle->code();
+  CodeBlob *blob = _code_handle->code();
+  if (blob != NULL) {
+    return blob->as_nmethod();
+  }
+  return NULL;
 }
 
 void CompileTask::set_code(nmethod* nm) {
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -3776,12 +3776,12 @@
   const uint               _num_workers;
 
   // Variables used to claim nmethods.
-  nmethod* _first_nmethod;
-  volatile nmethod* _claimed_nmethod;
+  CompiledMethod* _first_nmethod;
+  volatile CompiledMethod* _claimed_nmethod;
 
   // The list of nmethods that need to be processed by the second pass.
-  volatile nmethod* _postponed_list;
-  volatile uint     _num_entered_barrier;
+  volatile CompiledMethod* _postponed_list;
+  volatile uint            _num_entered_barrier;
 
  public:
   G1CodeCacheUnloadingTask(uint num_workers, BoolObjectClosure* is_alive, bool unloading_occurred) :
@@ -3793,13 +3793,13 @@
       _postponed_list(NULL),
       _num_entered_barrier(0)
   {
-    nmethod::increase_unloading_clock();
+    CompiledMethod::increase_unloading_clock();
     // Get first alive nmethod
-    NMethodIterator iter = NMethodIterator();
+    CompiledMethodIterator iter = CompiledMethodIterator();
     if(iter.next_alive()) {
       _first_nmethod = iter.method();
     }
-    _claimed_nmethod = (volatile nmethod*)_first_nmethod;
+    _claimed_nmethod = (volatile CompiledMethod*)_first_nmethod;
   }
 
   ~G1CodeCacheUnloadingTask() {
@@ -3812,15 +3812,15 @@
   }
 
  private:
-  void add_to_postponed_list(nmethod* nm) {
-      nmethod* old;
+  void add_to_postponed_list(CompiledMethod* nm) {
+      CompiledMethod* old;
       do {
-        old = (nmethod*)_postponed_list;
+        old = (CompiledMethod*)_postponed_list;
         nm->set_unloading_next(old);
-      } while ((nmethod*)Atomic::cmpxchg_ptr(nm, &_postponed_list, old) != old);
-  }
-
-  void clean_nmethod(nmethod* nm) {
+      } while ((CompiledMethod*)Atomic::cmpxchg_ptr(nm, &_postponed_list, old) != old);
+  }
+
+  void clean_nmethod(CompiledMethod* nm) {
     bool postponed = nm->do_unloading_parallel(_is_alive, _unloading_occurred);
 
     if (postponed) {
@@ -3830,24 +3830,24 @@
 
     // Mark that this thread has been cleaned/unloaded.
     // After this call, it will be safe to ask if this nmethod was unloaded or not.
-    nm->set_unloading_clock(nmethod::global_unloading_clock());
-  }
-
-  void clean_nmethod_postponed(nmethod* nm) {
+    nm->set_unloading_clock(CompiledMethod::global_unloading_clock());
+  }
+
+  void clean_nmethod_postponed(CompiledMethod* nm) {
     nm->do_unloading_parallel_postponed(_is_alive, _unloading_occurred);
   }
 
   static const int MaxClaimNmethods = 16;
 
-  void claim_nmethods(nmethod** claimed_nmethods, int *num_claimed_nmethods) {
-    nmethod* first;
-    NMethodIterator last;
+  void claim_nmethods(CompiledMethod** claimed_nmethods, int *num_claimed_nmethods) {
+    CompiledMethod* first;
+    CompiledMethodIterator last;
 
     do {
       *num_claimed_nmethods = 0;
 
-      first = (nmethod*)_claimed_nmethod;
-      last = NMethodIterator(first);
+      first = (CompiledMethod*)_claimed_nmethod;
+      last = CompiledMethodIterator(first);
 
       if (first != NULL) {
 
@@ -3860,22 +3860,22 @@
         }
       }
 
-    } while ((nmethod*)Atomic::cmpxchg_ptr(last.method(), &_claimed_nmethod, first) != first);
-  }
-
-  nmethod* claim_postponed_nmethod() {
-    nmethod* claim;
-    nmethod* next;
+    } while ((CompiledMethod*)Atomic::cmpxchg_ptr(last.method(), &_claimed_nmethod, first) != first);
+  }
+
+  CompiledMethod* claim_postponed_nmethod() {
+    CompiledMethod* claim;
+    CompiledMethod* next;
 
     do {
-      claim = (nmethod*)_postponed_list;
+      claim = (CompiledMethod*)_postponed_list;
       if (claim == NULL) {
         return NULL;
       }
 
       next = claim->unloading_next();
 
-    } while ((nmethod*)Atomic::cmpxchg_ptr(next, &_postponed_list, claim) != claim);
+    } while ((CompiledMethod*)Atomic::cmpxchg_ptr(next, &_postponed_list, claim) != claim);
 
     return claim;
   }
@@ -3911,7 +3911,7 @@
     }
 
     int num_claimed_nmethods;
-    nmethod* claimed_nmethods[MaxClaimNmethods];
+    CompiledMethod* claimed_nmethods[MaxClaimNmethods];
 
     while (true) {
       claim_nmethods(claimed_nmethods, &num_claimed_nmethods);
@@ -3927,7 +3927,7 @@
   }
 
   void work_second_pass(uint worker_id) {
-    nmethod* nm;
+    CompiledMethod* nm;
     // Take care of postponed nmethods.
     while ((nm = claim_postponed_nmethod()) != NULL) {
       clean_nmethod_postponed(nm);
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -992,7 +992,7 @@
   }
   NOT_PRODUCT(method->set_compiled_invocation_count(0));
 
-  nmethod* code = method->code();
+  CompiledMethod* code = method->code();
   if (code != NULL) {
     code->make_not_entrant();
   }
--- a/hotspot/src/share/vm/jvmci/jvmciEnv.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/jvmci/jvmciEnv.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -546,7 +546,7 @@
           if (entry_bci == InvocationEntryBci) {
             if (TieredCompilation) {
               // If there is an old version we're done with it
-              nmethod* old = method->code();
+              CompiledMethod* old = method->code();
               if (TraceMethodReplacement && old != NULL) {
                 ResourceMark rm;
                 char *method_name = method->name_and_sig_as_C_string();
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -220,15 +220,15 @@
 // been deoptimized. If that is the case we return the deopt blob
 // unpack_with_exception entry instead. This makes life for the exception blob easier
 // because making that same check and diverting is painful from assembly language.
-JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm))
+JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, CompiledMethod*& cm))
   // Reset method handle flag.
   thread->set_is_method_handle_return(false);
 
   Handle exception(thread, ex);
-  nm = CodeCache::find_nmethod(pc);
-  assert(nm != NULL, "this is not a compiled method");
+  cm = CodeCache::find_compiled(pc);
+  assert(cm != NULL, "this is not a compiled method");
   // Adjust the pc as needed/
-  if (nm->is_deopt_pc(pc)) {
+  if (cm->is_deopt_pc(pc)) {
     RegisterMap map(thread, false);
     frame exception_frame = thread->last_frame().sender(&map);
     // if the frame isn't deopted then pc must not correspond to the caller of last_frame
@@ -275,10 +275,10 @@
 
   // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions
   if (guard_pages_enabled) {
-    address fast_continuation = nm->handler_for_exception_and_pc(exception, pc);
+    address fast_continuation = cm->handler_for_exception_and_pc(exception, pc);
     if (fast_continuation != NULL) {
       // Set flag if return address is a method handle call site.
-      thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
+      thread->set_is_method_handle_return(cm->is_method_handle_return(pc));
       return fast_continuation;
     }
   }
@@ -299,7 +299,7 @@
       stringStream tempst;
       tempst.print("compiled method <%s>\n"
                    " at PC" INTPTR_FORMAT " for thread " INTPTR_FORMAT,
-                   nm->method()->print_value_string(), p2i(pc), p2i(thread));
+                   cm->method()->print_value_string(), p2i(pc), p2i(thread));
       Exceptions::log_exception(exception, tempst);
     }
     // for AbortVMOnException flag
@@ -311,19 +311,19 @@
     // normal bytecode execution.
     thread->clear_exception_oop_and_pc();
 
-    continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false);
+    continuation = SharedRuntime::compute_compiled_exc_handler(cm, pc, exception, false, false);
     // If an exception was thrown during exception dispatch, the exception oop may have changed
     thread->set_exception_oop(exception());
     thread->set_exception_pc(pc);
 
     // the exception cache is used only by non-implicit exceptions
     if (continuation != NULL && !SharedRuntime::deopt_blob()->contains(continuation)) {
-      nm->add_handler_for_exception_and_pc(exception, pc, continuation);
+      cm->add_handler_for_exception_and_pc(exception, pc, continuation);
     }
   }
 
   // Set flag if return address is a method handle call site.
-  thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
+  thread->set_is_method_handle_return(cm->is_method_handle_return(pc));
 
   if (log_is_enabled(Info, exceptions)) {
     ResourceMark rm;
@@ -345,18 +345,18 @@
   address pc = thread->exception_pc();
   // Still in Java mode
   DEBUG_ONLY(ResetNoHandleMark rnhm);
-  nmethod* nm = NULL;
+  CompiledMethod* cm = NULL;
   address continuation = NULL;
   {
     // Enter VM mode by calling the helper
     ResetNoHandleMark rnhm;
-    continuation = exception_handler_for_pc_helper(thread, exception, pc, nm);
+    continuation = exception_handler_for_pc_helper(thread, exception, pc, cm);
   }
   // Back in JAVA, use no oops DON'T safepoint
 
   // Now check to see if the compiled method we were called from is now deoptimized.
   // If so we must return to the deopt blob and deoptimize the nmethod
-  if (nm != NULL && caller_is_deopted()) {
+  if (cm != NULL && caller_is_deopted()) {
     continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
   }
 
--- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -186,7 +186,7 @@
   nonstatic_field(Method,                      _vtable_index,                                 int)                                   \
   nonstatic_field(Method,                      _intrinsic_id,                                 u2)                                    \
   nonstatic_field(Method,                      _flags,                                        u2)                                    \
-  volatile_nonstatic_field(Method,             _code,                                         nmethod*)                              \
+  volatile_nonstatic_field(Method,             _code,                                         CompiledMethod*)                       \
   volatile_nonstatic_field(Method,             _from_compiled_entry,                          address)                               \
                                                                                                                                      \
   nonstatic_field(MethodCounters,              _invocation_counter,                           InvocationCounter)                     \
--- a/hotspot/src/share/vm/oops/method.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/oops/method.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -746,7 +746,7 @@
   // This function can be called more than once. We must make sure that we always
   // use the latest registered method -> check if a stub already has been generated.
   // If so, we have to make it not_entrant.
-  nmethod* nm = code(); // Put it into local variable to guard against concurrent updates
+  CompiledMethod* nm = code(); // Put it into local variable to guard against concurrent updates
   if (nm != NULL) {
     nm->make_not_entrant();
   }
@@ -1046,12 +1046,12 @@
 // Not inline to avoid circular ref.
 bool Method::check_code() const {
   // cached in a register or local.  There's a race on the value of the field.
-  nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code);
+  CompiledMethod *code = (CompiledMethod *)OrderAccess::load_ptr_acquire(&_code);
   return code == NULL || (code->method() == NULL) || (code->method() == (Method*)this && !code->is_osr_method());
 }
 
 // Install compiled code.  Instantly it can execute.
-void Method::set_code(methodHandle mh, nmethod *code) {
+void Method::set_code(methodHandle mh, CompiledMethod *code) {
   assert( code, "use clear_code to remove code" );
   assert( mh->check_code(), "" );
 
--- a/hotspot/src/share/vm/oops/method.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/oops/method.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -58,6 +58,7 @@
 class ConstMethod;
 class InlineTableSizes;
 class KlassSizeStats;
+class CompiledMethod;
 
 class Method : public Metadata {
  friend class VMStructs;
@@ -101,7 +102,7 @@
   // field can come and go.  It can transition from NULL to not-null at any
   // time (whenever a compile completes).  It can transition from not-null to
   // NULL only at safepoints (because of a de-opt).
-  nmethod* volatile _code;                       // Points to the corresponding piece of native code
+  CompiledMethod* volatile _code;                       // Points to the corresponding piece of native code
   volatile address           _from_interpreted_entry; // Cache of _code ? _adapter->i2c_entry() : _i2i_entry
 
   // Constructor
@@ -431,9 +432,9 @@
   // nmethod/verified compiler entry
   address verified_code_entry();
   bool check_code() const;      // Not inline to avoid circular ref
-  nmethod* volatile code() const                 { assert( check_code(), "" ); return (nmethod *)OrderAccess::load_ptr_acquire(&_code); }
+  CompiledMethod* volatile code() const                 { assert( check_code(), "" ); return (CompiledMethod *)OrderAccess::load_ptr_acquire(&_code); }
   void clear_code();            // Clear out any compiled code
-  static void set_code(methodHandle mh, nmethod* code);
+  static void set_code(methodHandle mh, CompiledMethod* code);
   void set_adapter_entry(AdapterHandlerEntry* adapter) {
     constMethod()->set_adapter_entry(adapter);
   }
--- a/hotspot/src/share/vm/opto/compile.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/opto/compile.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -565,7 +565,7 @@
   relocInfo* locs_buf = scratch_locs_memory();
   address blob_begin = blob->content_begin();
   address blob_end   = (address)locs_buf;
-  assert(blob->content_contains(blob_end), "sanity");
+  assert(blob->contains(blob_end), "sanity");
   CodeBuffer buf(blob_begin, blob_end - blob_begin);
   buf.initialize_consts_size(_scratch_const_size);
   buf.initialize_stubs_size(MAX_stubs_size);
--- a/hotspot/src/share/vm/opto/runtime.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/opto/runtime.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1663,9 +1663,9 @@
   exception_oop->print_value_on(&tempst);
   tempst.print(" in ");
   CodeBlob* blob = CodeCache::find_blob(exception_pc);
-  if (blob->is_nmethod()) {
-    nmethod* nm = blob->as_nmethod_or_null();
-    nm->method()->print_value_on(&tempst);
+  if (blob->is_compiled()) {
+    CompiledMethod* cm = blob->as_compiled_method_or_null();
+    cm->method()->print_value_on(&tempst);
   } else if (blob->is_runtime_stub()) {
     tempst.print("<runtime-stub>");
   } else {
--- a/hotspot/src/share/vm/prims/whitebox.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/prims/whitebox.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -483,9 +483,9 @@
             RegisterMap* reg_map = fst.register_map();
             Deoptimization::deoptimize(t, *f, reg_map);
             if (_make_not_entrant) {
-                nmethod* nm = CodeCache::find_nmethod(f->pc());
-                assert(nm != NULL, "sanity check");
-                nm->make_not_entrant();
+                CompiledMethod* cm = CodeCache::find_compiled(f->pc());
+                assert(cm != NULL, "sanity check");
+                cm->make_not_entrant();
             }
             ++_result;
           }
@@ -533,7 +533,7 @@
   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
   MutexLockerEx mu(Compile_lock);
   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
-  nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
+  CompiledMethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
   if (code == NULL) {
     return JNI_FALSE;
   }
@@ -589,7 +589,7 @@
   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
   CHECK_JNI_EXCEPTION_(env, CompLevel_none);
   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
-  nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
+  CompiledMethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
   return (code != NULL ? code->comp_level() : CompLevel_none);
 WB_END
 
@@ -608,7 +608,7 @@
   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
   CHECK_JNI_EXCEPTION_(env, InvocationEntryBci);
   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
-  nmethod* code = mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false);
+  CompiledMethod* code = mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false);
   return (code != NULL && code->is_osr_method() ? code->osr_entry_bci() : InvocationEntryBci);
 WB_END
 
@@ -1093,7 +1093,7 @@
   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
   CHECK_JNI_EXCEPTION_(env, NULL);
   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
-  nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
+  CompiledMethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
   jobjectArray result = NULL;
   if (code == NULL) {
     return result;
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -496,7 +496,7 @@
 
 // Handle the invocation event.
 void AdvancedThresholdPolicy::method_invocation_event(const methodHandle& mh, const methodHandle& imh,
-                                                      CompLevel level, nmethod* nm, JavaThread* thread) {
+                                                      CompLevel level, CompiledMethod* nm, JavaThread* thread) {
   if (should_create_mdo(mh(), level)) {
     create_mdo(mh, thread);
   }
@@ -511,7 +511,7 @@
 // Handle the back branch event. Notice that we can compile the method
 // with a regular entry from here.
 void AdvancedThresholdPolicy::method_back_branch_event(const methodHandle& mh, const methodHandle& imh,
-                                                       int bci, CompLevel level, nmethod* nm, JavaThread* thread) {
+                                                       int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread) {
   if (should_create_mdo(mh(), level)) {
     create_mdo(mh, thread);
   }
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -216,9 +216,9 @@
   virtual void submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
   // event() from SimpleThresholdPolicy would call these.
   virtual void method_invocation_event(const methodHandle& method, const methodHandle& inlinee,
-                                       CompLevel level, nmethod* nm, JavaThread* thread);
+                                       CompLevel level, CompiledMethod* nm, JavaThread* thread);
   virtual void method_back_branch_event(const methodHandle& method, const methodHandle& inlinee,
-                                        int bci, CompLevel level, nmethod* nm, JavaThread* thread);
+                                        int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread);
 public:
   AdvancedThresholdPolicy() : _start_time(0) { }
   // Select task is called by CompileBroker. We should return a task or NULL.
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -379,7 +379,7 @@
 }
 
 nmethod* NonTieredCompPolicy::event(const methodHandle& method, const methodHandle& inlinee, int branch_bci,
-                                    int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) {
+                                    int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) {
   assert(comp_level == CompLevel_none, "This should be only called from the interpreter");
   NOT_PRODUCT(trace_frequency_counter_overflow(method, branch_bci, bci));
   if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {
@@ -484,7 +484,7 @@
   const char* comment = "count";
 
   if (is_compilation_enabled() && can_be_compiled(m, comp_level)) {
-    nmethod* nm = m->code();
+    CompiledMethod* nm = m->code();
     if (nm == NULL ) {
       CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, comment, thread);
     }
@@ -713,7 +713,7 @@
   // note: we allow ik->is_abstract()
   if (!m->method_holder()->is_initialized()) return (_msg = "method holder not initialized");
   if (m->is_native()) return (_msg = "native method");
-  nmethod* m_code = m->code();
+  CompiledMethod* m_code = m->code();
   if (m_code != NULL && m_code->code_size() > InlineSmallCode)
     return (_msg = "already compiled into a big method");
 
--- a/hotspot/src/share/vm/runtime/compilationPolicy.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -68,7 +68,7 @@
   virtual int compiler_count(CompLevel comp_level) = 0;
   // main notification entry, return a pointer to an nmethod if the OSR is required,
   // returns NULL otherwise.
-  virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) = 0;
+  virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) = 0;
   // safepoint() is called at the end of the safepoint
   virtual void do_safepoint_work() = 0;
   // reprofile request
@@ -109,7 +109,7 @@
   virtual bool is_mature(Method* method);
   virtual void initialize();
   virtual CompileTask* select_task(CompileQueue* compile_queue);
-  virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread);
+  virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread);
   virtual void method_invocation_event(const methodHandle& m, JavaThread* thread) = 0;
   virtual void method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) = 0;
 };
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -168,9 +168,10 @@
   // Now get the deoptee with a valid map
   frame deoptee = stub_frame.sender(&map);
   // Set the deoptee nmethod
-  assert(thread->deopt_nmethod() == NULL, "Pending deopt!");
-  thread->set_deopt_nmethod(deoptee.cb()->as_nmethod_or_null());
-  bool skip_internal = thread->deopt_nmethod() != NULL && !thread->deopt_nmethod()->compiler()->is_jvmci();
+  assert(thread->deopt_compiled_method() == NULL, "Pending deopt!");
+  CompiledMethod* cm = deoptee.cb()->as_compiled_method_or_null();
+  thread->set_deopt_compiled_method(cm);
+  bool skip_internal = (cm != NULL) && !cm->is_compiled_by_jvmci();
 
   if (VerifyStack) {
     thread->validate_frame_layout();
@@ -548,7 +549,7 @@
 
   delete thread->deopt_mark();
   thread->set_deopt_mark(NULL);
-  thread->set_deopt_nmethod(NULL);
+  thread->set_deopt_compiled_method(NULL);
 
 
   if (JvmtiExport::can_pop_frame()) {
@@ -1292,14 +1293,14 @@
   gather_statistics(reason, Action_none, Bytecodes::_illegal);
 
   if (LogCompilation && xtty != NULL) {
-    nmethod* nm = fr.cb()->as_nmethod_or_null();
-    assert(nm != NULL, "only compiled methods can deopt");
+    CompiledMethod* cm = fr.cb()->as_compiled_method_or_null();
+    assert(cm != NULL, "only compiled methods can deopt");
 
     ttyLocker ttyl;
     xtty->begin_head("deoptimized thread='" UINTX_FORMAT "'", (uintx)thread->osthread()->thread_id());
-    nm->log_identity(xtty);
+    cm->log_identity(xtty);
     xtty->end_head();
-    for (ScopeDesc* sd = nm->scope_desc_at(fr.pc()); ; sd = sd->sender()) {
+    for (ScopeDesc* sd = cm->scope_desc_at(fr.pc()); ; sd = sd->sender()) {
       xtty->begin_elem("jvms bci='%d'", sd->bci());
       xtty->method(sd->method());
       xtty->end_elem();
@@ -1480,7 +1481,7 @@
     vframe*  vf  = vframe::new_vframe(&fr, &reg_map, thread);
     compiledVFrame* cvf = compiledVFrame::cast(vf);
 
-    nmethod* nm = cvf->code();
+    CompiledMethod* nm = cvf->code();
 
     ScopeDesc*      trap_scope  = cvf->scope();
 
@@ -1499,7 +1500,7 @@
     oop speculation = thread->pending_failed_speculation();
     if (nm->is_compiled_by_jvmci()) {
       if (speculation != NULL) {
-        oop speculation_log = nm->speculation_log();
+        oop speculation_log = nm->as_nmethod()->speculation_log();
         if (speculation_log != NULL) {
           if (TraceDeoptimization || TraceUncollectedSpeculations) {
             if (HotSpotSpeculationLog::lastFailed(speculation_log) != NULL) {
@@ -1615,19 +1616,21 @@
         nm->method()->print_short_name(tty);
         tty->print(" compiler=%s compile_id=%d", nm->compiler() == NULL ? "" : nm->compiler()->name(), nm->compile_id());
 #if INCLUDE_JVMCI
-        oop installedCode = nm->jvmci_installed_code();
-        if (installedCode != NULL) {
-          oop installedCodeName = NULL;
-          if (installedCode->is_a(InstalledCode::klass())) {
-            installedCodeName = InstalledCode::name(installedCode);
+        if (nm->is_nmethod()) {
+          oop installedCode = nm->as_nmethod()->jvmci_installed_code();
+          if (installedCode != NULL) {
+            oop installedCodeName = NULL;
+            if (installedCode->is_a(InstalledCode::klass())) {
+              installedCodeName = InstalledCode::name(installedCode);
+            }
+            if (installedCodeName != NULL) {
+              tty->print(" (JVMCI: installedCodeName=%s) ", java_lang_String::as_utf8_string(installedCodeName));
+            } else {
+              tty->print(" (JVMCI: installed code has no name) ");
+            }
+          } else if (nm->is_compiled_by_jvmci()) {
+            tty->print(" (JVMCI: no installed code) ");
           }
-          if (installedCodeName != NULL) {
-            tty->print(" (JVMCI: installedCodeName=%s) ", java_lang_String::as_utf8_string(installedCodeName));
-          } else {
-            tty->print(" (JVMCI: installed code has no name) ");
-          }
-        } else if (nm->is_compiled_by_jvmci()) {
-          tty->print(" (JVMCI: no installed code) ");
         }
 #endif
         tty->print(" (@" INTPTR_FORMAT ") thread=" UINTX_FORMAT " reason=%s action=%s unloaded_class_index=%d" JVMCI_ONLY(" debug_id=%d"),
@@ -1867,7 +1870,7 @@
       // Assume that in new recompiled code the statistic could be different,
       // for example, due to different inlining.
       if ((reason != Reason_rtm_state_change) && (trap_mdo != NULL) &&
-          UseRTMDeopt && (nm->rtm_state() != ProfileRTM)) {
+          UseRTMDeopt && (nm->as_nmethod()->rtm_state() != ProfileRTM)) {
         trap_mdo->atomic_set_rtm_state(ProfileRTM);
       }
 #endif
--- a/hotspot/src/share/vm/runtime/fprofiler.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/fprofiler.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -538,11 +538,12 @@
 
 class runtimeStubNode : public ProfilerNode {
  private:
-   const CodeBlob* _stub;
+  const RuntimeStub* _stub;
   const char* _symbol;     // The name of the nearest VM symbol when ProfileVM is on. Points to a unique string.
  public:
-   runtimeStubNode(const CodeBlob* stub, const char* name, TickPosition where) : ProfilerNode(), _stub(stub),  _symbol(name) {
+   runtimeStubNode(const CodeBlob* stub, const char* name, TickPosition where) : ProfilerNode(), _stub(NULL),  _symbol(name) {
      assert(stub->is_runtime_stub(), "wrong code blob");
+     _stub = (RuntimeStub*) stub;
      update(where);
    }
 
@@ -550,7 +551,7 @@
 
   bool runtimeStub_match(const CodeBlob* stub, const char* name) const {
     assert(stub->is_runtime_stub(), "wrong code blob");
-    return ((RuntimeStub*)_stub)->entry_point() == ((RuntimeStub*)stub)->entry_point() &&
+    return _stub->entry_point() == ((RuntimeStub*)stub)->entry_point() &&
             (_symbol == name);
   }
 
@@ -571,7 +572,7 @@
   }
 
   void print_method_on(outputStream* st) {
-    st->print("%s", ((RuntimeStub*)_stub)->name());
+    st->print("%s", _stub->name());
     print_symbol_on(st);
   }
 
@@ -588,18 +589,18 @@
  public:
    unknown_compiledNode(const CodeBlob* cb, TickPosition where) : ProfilerNode() {
      if ( cb->is_buffer_blob() )
-       _name = ((BufferBlob*)cb)->name();
+       _name = ((const BufferBlob*)cb)->name();
      else
-       _name = ((SingletonBlob*)cb)->name();
+       _name = ((const SingletonBlob*)cb)->name();
      update(where);
   }
   bool is_compiled()    const { return true; }
 
   bool unknown_compiled_match(const CodeBlob* cb) const {
      if ( cb->is_buffer_blob() )
-       return !strcmp(((BufferBlob*)cb)->name(), _name);
+       return !strcmp(((const BufferBlob*)cb)->name(), _name);
      else
-       return !strcmp(((SingletonBlob*)cb)->name(), _name);
+       return !strcmp(((const SingletonBlob*)cb)->name(), _name);
   }
 
   Method* method()         { return NULL; }
@@ -993,16 +994,15 @@
 
   CodeBlob* cb = fr.cb();
 
-// For runtime stubs, record as native rather than as compiled
-   if (cb->is_runtime_stub()) {
-        RegisterMap map(thread, false);
-        fr = fr.sender(&map);
-        cb = fr.cb();
-        localwhere = tp_native;
-  }
-  Method* method = (cb->is_nmethod()) ? ((nmethod *)cb)->method() :
-                                          (Method*)NULL;
+  // For runtime stubs, record as native rather than as compiled
+  if (cb->is_runtime_stub()) {
+    RegisterMap map(thread, false);
+    fr = fr.sender(&map);
+    cb = fr.cb();
+    localwhere = tp_native;
+ }
 
+  Method* method = cb->is_compiled() ? cb->as_compiled_method()->method() : (Method*) NULL;
   if (method == NULL) {
     if (cb->is_runtime_stub())
       runtime_stub_update(cb, name, localwhere);
--- a/hotspot/src/share/vm/runtime/frame.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/frame.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -132,11 +132,11 @@
 
 address frame::raw_pc() const {
   if (is_deoptimized_frame()) {
-    nmethod* nm = cb()->as_nmethod_or_null();
-    if (nm->is_method_handle_return(pc()))
-      return nm->deopt_mh_handler_begin() - pc_return_offset;
+    CompiledMethod* cm = cb()->as_compiled_method_or_null();
+    if (cm->is_method_handle_return(pc()))
+      return cm->deopt_mh_handler_begin() - pc_return_offset;
     else
-      return nm->deopt_handler_begin() - pc_return_offset;
+      return cm->deopt_handler_begin() - pc_return_offset;
   } else {
     return (pc() - pc_return_offset);
   }
@@ -183,8 +183,8 @@
 
 bool frame::is_compiled_frame() const {
   if (_cb != NULL &&
-      _cb->is_nmethod() &&
-      ((nmethod*)_cb)->is_java_method()) {
+      _cb->is_compiled() &&
+      ((CompiledMethod*)_cb)->is_java_method()) {
     return true;
   }
   return false;
@@ -228,8 +228,8 @@
 bool frame::should_be_deoptimized() const {
   if (_deopt_state == is_deoptimized ||
       !is_compiled_frame() ) return false;
-  assert(_cb != NULL && _cb->is_nmethod(), "must be an nmethod");
-  nmethod* nm = (nmethod *)_cb;
+  assert(_cb != NULL && _cb->is_compiled(), "must be an nmethod");
+  CompiledMethod* nm = (CompiledMethod *)_cb;
   if (TraceDependencies) {
     tty->print("checking (%s) ", nm->is_marked_for_deoptimization() ? "true" : "false");
     nm->print_value_on(tty);
@@ -246,7 +246,7 @@
 
 bool frame::can_be_deoptimized() const {
   if (!is_compiled_frame()) return false;
-  nmethod* nm = (nmethod*)_cb;
+  CompiledMethod* nm = (CompiledMethod*)_cb;
 
   if( !nm->can_be_deoptimized() )
     return false;
@@ -256,8 +256,7 @@
 
 void frame::deoptimize(JavaThread* thread) {
   // Schedule deoptimization of an nmethod activation with this frame.
-  assert(_cb != NULL && _cb->is_nmethod(), "must be");
-  nmethod* nm = (nmethod*)_cb;
+  assert(_cb != NULL && _cb->is_compiled(), "must be");
 
   // This is a fix for register window patching race
   if (NeedsDeoptSuspend && Thread::current() != thread) {
@@ -316,12 +315,13 @@
 
   // If the call site is a MethodHandle call site use the MH deopt
   // handler.
-  address deopt = nm->is_method_handle_return(pc()) ?
-    nm->deopt_mh_handler_begin() :
-    nm->deopt_handler_begin();
+  CompiledMethod* cm = (CompiledMethod*) _cb;
+  address deopt = cm->is_method_handle_return(pc()) ?
+                        cm->deopt_mh_handler_begin() :
+                        cm->deopt_handler_begin();
 
   // Save the original pc before we patch in the new one
-  nm->set_original_pc(this, pc());
+  cm->set_original_pc(this, pc());
   patch_pc(thread, deopt);
 
 #ifdef ASSERT
@@ -661,13 +661,16 @@
       }
     } else if (_cb->is_buffer_blob()) {
       st->print("v  ~BufferBlob::%s", ((BufferBlob *)_cb)->name());
-    } else if (_cb->is_nmethod()) {
-      nmethod* nm = (nmethod*)_cb;
-      Method* m = nm->method();
+    } else if (_cb->is_compiled()) {
+      CompiledMethod* cm = (CompiledMethod*)_cb;
+      Method* m = cm->method();
       if (m != NULL) {
-        st->print("J %d%s", nm->compile_id(), (nm->is_osr_method() ? "%" : ""));
-        if (nm->compiler() != NULL) {
-          st->print(" %s", nm->compiler()->name());
+        if (cm->is_nmethod()) {
+          nmethod* nm = cm->as_nmethod();
+          st->print("J %d%s", nm->compile_id(), (nm->is_osr_method() ? "%" : ""));
+          if (nm->compiler() != NULL) {
+            st->print(" %s", nm->compiler()->name());
+          }
         }
         m->name_and_sig_as_C_string(buf, buflen);
         st->print(" %s", buf);
@@ -681,9 +684,12 @@
         st->print(" (%d bytes) @ " PTR_FORMAT " [" PTR_FORMAT "+" INTPTR_FORMAT "]",
                   m->code_size(), p2i(_pc), p2i(_cb->code_begin()), _pc - _cb->code_begin());
 #if INCLUDE_JVMCI
-        char* jvmciName = nm->jvmci_installed_code_name(buf, buflen);
-        if (jvmciName != NULL) {
-          st->print(" (%s)", jvmciName);
+        if (cm->is_nmethod()) {
+          nmethod* nm = cm->as_nmethod();
+          char* jvmciName = nm->jvmci_installed_code_name(buf, buflen);
+          if (jvmciName != NULL) {
+            st->print(" (%s)", jvmciName);
+          }
         }
 #endif
       } else {
@@ -1244,10 +1250,10 @@
     values.describe(-1, info_address, err_msg("#%d entry frame", frame_no), 2);
   } else if (is_compiled_frame()) {
     // For now just label the frame
-    nmethod* nm = cb()->as_nmethod_or_null();
+    CompiledMethod* cm = (CompiledMethod*)cb();
     values.describe(-1, info_address,
                     FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for method %s%s", frame_no,
-                                       p2i(nm), nm->method()->name_and_sig_as_C_string(),
+                                       p2i(cm), cm->method()->name_and_sig_as_C_string(),
                                        (_deopt_state == is_deoptimized) ?
                                        " (deoptimized)" :
                                        ((_deopt_state == unknown) ? " (state unknown)" : "")),
--- a/hotspot/src/share/vm/runtime/rframe.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/rframe.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -127,7 +127,7 @@
 }
 
 int CompiledRFrame::cost() const {
-  nmethod* nm = top_method()->code();
+  CompiledMethod* nm = top_method()->code();
   if (nm != NULL) {
     return nm->insts_size();
   } else {
@@ -139,7 +139,7 @@
   RegisterMap map(thread(), false);
   vframe* vf = vframe::new_vframe(&_fr, &map, thread());
   assert(vf->is_compiled_frame(), "must be compiled");
-  _nm = compiledVFrame::cast(vf)->code();
+  _nm = compiledVFrame::cast(vf)->code()->as_nmethod();
   vf = vf->top();
   _vf = javaVFrame::cast(vf);
   _method = CodeCache::find_nmethod(_fr.pc())->method();
--- a/hotspot/src/share/vm/runtime/safepoint.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1010,8 +1010,8 @@
   address real_return_addr = thread()->saved_exception_pc();
 
   CodeBlob *cb = CodeCache::find_blob(real_return_addr);
-  assert(cb != NULL && cb->is_nmethod(), "return address should be in nmethod");
-  nmethod* nm = (nmethod*)cb;
+  assert(cb != NULL && cb->is_compiled(), "return address should be in nmethod");
+  CompiledMethod* nm = (CompiledMethod*)cb;
 
   // Find frame of caller
   frame stub_fr = thread()->last_frame();
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -540,10 +540,10 @@
   CodeBlob *cb = CodeCache::find_blob(pc);
 
   // Should be an nmethod
-  assert(cb && cb->is_nmethod(), "safepoint polling: pc must refer to an nmethod");
+  assert(cb && cb->is_compiled(), "safepoint polling: pc must refer to an nmethod");
 
   // Look up the relocation information
-  assert(((nmethod*)cb)->is_at_poll_or_poll_return(pc),
+  assert(((CompiledMethod*)cb)->is_at_poll_or_poll_return(pc),
     "safepoint polling: type must be poll");
 
 #ifdef ASSERT
@@ -554,8 +554,8 @@
   }
 #endif
 
-  bool at_poll_return = ((nmethod*)cb)->is_at_poll_return(pc);
-  bool has_wide_vectors = ((nmethod*)cb)->has_wide_vectors();
+  bool at_poll_return = ((CompiledMethod*)cb)->is_at_poll_return(pc);
+  bool has_wide_vectors = ((CompiledMethod*)cb)->has_wide_vectors();
   if (at_poll_return) {
     assert(SharedRuntime::polling_page_return_handler_blob() != NULL,
            "polling page return stub not created yet");
@@ -630,22 +630,22 @@
 
 // ret_pc points into caller; we are returning caller's exception handler
 // for given exception
-address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception,
+address SharedRuntime::compute_compiled_exc_handler(CompiledMethod* cm, address ret_pc, Handle& exception,
                                                     bool force_unwind, bool top_frame_only) {
-  assert(nm != NULL, "must exist");
+  assert(cm != NULL, "must exist");
   ResourceMark rm;
 
 #if INCLUDE_JVMCI
-  if (nm->is_compiled_by_jvmci()) {
+  if (cm->is_compiled_by_jvmci()) {
     // lookup exception handler for this pc
-    int catch_pco = ret_pc - nm->code_begin();
-    ExceptionHandlerTable table(nm);
+    int catch_pco = ret_pc - cm->code_begin();
+    ExceptionHandlerTable table(cm);
     HandlerTableEntry *t = table.entry_for(catch_pco, -1, 0);
     if (t != NULL) {
-      return nm->code_begin() + t->pco();
+      return cm->code_begin() + t->pco();
     } else {
       // there is no exception handler for this pc => deoptimize
-      nm->make_not_entrant();
+      cm->make_not_entrant();
 
       // Use Deoptimization::deoptimize for all of its side-effects:
       // revoking biases of monitors, gathering traps statistics, logging...
@@ -662,6 +662,7 @@
   }
 #endif // INCLUDE_JVMCI
 
+  nmethod* nm = cm->as_nmethod();
   ScopeDesc* sd = nm->scope_desc_at(ret_pc);
   // determine handler bci, if any
   EXCEPTION_MARK;
@@ -797,7 +798,7 @@
 }
 
 #if INCLUDE_JVMCI
-address SharedRuntime::deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason) {
+address SharedRuntime::deoptimize_for_implicit_exception(JavaThread* thread, address pc, CompiledMethod* nm, int deopt_reason) {
   assert(deopt_reason > Deoptimization::Reason_none && deopt_reason < Deoptimization::Reason_LIMIT, "invalid deopt reason");
   thread->set_jvmci_implicit_exception_pc(pc);
   thread->set_pending_deoptimization(Deoptimization::make_trap_request((Deoptimization::DeoptReason)deopt_reason, Deoptimization::Action_reinterpret));
@@ -871,7 +872,7 @@
           // 2. Inline-cache check in nmethod, or
           // 3. Implicit null exception in nmethod
 
-          if (!cb->is_nmethod()) {
+          if (!cb->is_compiled()) {
             bool is_in_blob = cb->is_adapter_blob() || cb->is_method_handles_adapter_blob();
             if (!is_in_blob) {
               // Allow normal crash reporting to handle this
@@ -882,9 +883,9 @@
             return StubRoutines::throw_NullPointerException_at_call_entry();
           }
 
-          // Otherwise, it's an nmethod.  Consult its exception handlers.
-          nmethod* nm = (nmethod*)cb;
-          if (nm->inlinecache_check_contains(pc)) {
+          // Otherwise, it's a compiled method.  Consult its exception handlers.
+          CompiledMethod* cm = (CompiledMethod*)cb;
+          if (cm->inlinecache_check_contains(pc)) {
             // exception happened inside inline-cache check code
             // => the nmethod is not yet active (i.e., the frame
             // is not set up yet) => use return address pushed by
@@ -893,7 +894,7 @@
             return StubRoutines::throw_NullPointerException_at_call_entry();
           }
 
-          if (nm->method()->is_method_handle_intrinsic()) {
+          if (cm->method()->is_method_handle_intrinsic()) {
             // exception happened inside MH dispatch code, similar to a vtable stub
             Events::log_exception(thread, "NullPointerException in MH adapter " INTPTR_FORMAT, p2i(pc));
             return StubRoutines::throw_NullPointerException_at_call_entry();
@@ -903,15 +904,15 @@
           _implicit_null_throws++;
 #endif
 #if INCLUDE_JVMCI
-          if (nm->is_compiled_by_jvmci() && nm->pc_desc_at(pc) != NULL) {
+          if (cm->is_compiled_by_jvmci() && cm->pc_desc_at(pc) != NULL) {
             // If there's no PcDesc then we'll die way down inside of
             // deopt instead of just getting normal error reporting,
             // so only go there if it will succeed.
-            return deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_null_check);
+            return deoptimize_for_implicit_exception(thread, pc, cm, Deoptimization::Reason_null_check);
           } else {
 #endif // INCLUDE_JVMCI
-          assert (nm->is_nmethod(), "Expect nmethod");
-          target_pc = nm->continuation_for_implicit_exception(pc);
+          assert (cm->is_nmethod(), "Expect nmethod");
+          target_pc = ((nmethod*)cm)->continuation_for_implicit_exception(pc);
 #if INCLUDE_JVMCI
           }
 #endif // INCLUDE_JVMCI
@@ -925,17 +926,17 @@
 
 
       case IMPLICIT_DIVIDE_BY_ZERO: {
-        nmethod* nm = CodeCache::find_nmethod(pc);
-        guarantee(nm != NULL, "must have containing compiled method for implicit division-by-zero exceptions");
+        CompiledMethod* cm = CodeCache::find_compiled(pc);
+        guarantee(cm != NULL, "must have containing compiled method for implicit division-by-zero exceptions");
 #ifndef PRODUCT
         _implicit_div0_throws++;
 #endif
 #if INCLUDE_JVMCI
-        if (nm->is_compiled_by_jvmci() && nm->pc_desc_at(pc) != NULL) {
-          return deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_div0_check);
+        if (cm->is_compiled_by_jvmci() && cm->pc_desc_at(pc) != NULL) {
+          return deoptimize_for_implicit_exception(thread, pc, cm, Deoptimization::Reason_div0_check);
         } else {
 #endif // INCLUDE_JVMCI
-        target_pc = nm->continuation_for_implicit_exception(pc);
+        target_pc = cm->continuation_for_implicit_exception(pc);
 #if INCLUDE_JVMCI
         }
 #endif // INCLUDE_JVMCI
@@ -1084,14 +1085,14 @@
 }
 
 methodHandle SharedRuntime::extract_attached_method(vframeStream& vfst) {
-  nmethod* caller_nm = vfst.nm();
-
-  nmethodLocker caller_lock(caller_nm);
+  CompiledMethod* caller = vfst.nm();
+
+  nmethodLocker caller_lock(caller);
 
   address pc = vfst.frame_pc();
   { // Get call instruction under lock because another thread may be busy patching it.
     MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag);
-    return caller_nm->attached_method_before_pc(pc);
+    return caller->attached_method_before_pc(pc);
   }
   return NULL;
 }
@@ -1283,8 +1284,8 @@
   frame caller_frame = thread->last_frame().sender(&cbl_map);
 
   CodeBlob* caller_cb = caller_frame.cb();
-  guarantee(caller_cb != NULL && caller_cb->is_nmethod(), "must be called from nmethod");
-  nmethod* caller_nm = caller_cb->as_nmethod_or_null();
+  guarantee(caller_cb != NULL && caller_cb->is_compiled(), "must be called from compiled method");
+  CompiledMethod* caller_nm = caller_cb->as_compiled_method_or_null();
 
   // make sure caller is not getting deoptimized
   // and removed before we are done with it.
@@ -1347,14 +1348,19 @@
 
   // Make sure the callee nmethod does not get deoptimized and removed before
   // we are done patching the code.
-  nmethod* callee_nm = callee_method->code();
-  if (callee_nm != NULL && !callee_nm->is_in_use()) {
+  CompiledMethod* callee = callee_method->code();
+
+  if (callee != NULL) {
+    assert(callee->is_compiled(), "must be nmethod for patching");
+  }
+
+  if (callee != NULL && !callee->is_in_use()) {
     // Patch call site to C2I adapter if callee nmethod is deoptimized or unloaded.
-    callee_nm = NULL;
+    callee = NULL;
   }
-  nmethodLocker nl_callee(callee_nm);
+  nmethodLocker nl_callee(callee);
 #ifdef ASSERT
-  address dest_entry_point = callee_nm == NULL ? 0 : callee_nm->entry_point(); // used below
+  address dest_entry_point = callee == NULL ? 0 : callee->entry_point(); // used below
 #endif
 
   if (is_virtual) {
@@ -1382,12 +1388,12 @@
     // which may happen when multiply alive nmethod (tiered compilation)
     // will be supported.
     if (!callee_method->is_old() &&
-        (callee_nm == NULL || callee_nm->is_in_use() && (callee_method->code() == callee_nm))) {
+        (callee == NULL || callee->is_in_use() && (callee_method->code() == callee))) {
 #ifdef ASSERT
       // We must not try to patch to jump to an already unloaded method.
       if (dest_entry_point != 0) {
         CodeBlob* cb = CodeCache::find_blob(dest_entry_point);
-        assert((cb != NULL) && cb->is_nmethod() && (((nmethod*)cb) == callee_nm),
+        assert((cb != NULL) && cb->is_compiled() && (((CompiledMethod*)cb) == callee),
                "should not call unloaded nmethod");
       }
 #endif
@@ -1582,8 +1588,9 @@
     RegisterMap reg_map(thread, false);
     frame caller_frame = thread->last_frame().sender(&reg_map);
     CodeBlob* cb = caller_frame.cb();
-    if (cb->is_nmethod()) {
-      CompiledIC* inline_cache = CompiledIC_before(((nmethod*)cb), caller_frame.pc());
+    CompiledMethod* caller_nm = cb->as_compiled_method_or_null();
+    if (cb->is_compiled()) {
+      CompiledIC* inline_cache = CompiledIC_before(((CompiledMethod*)cb), caller_frame.pc());
       bool should_be_mono = false;
       if (inline_cache->is_optimized()) {
         if (TraceCallFixup) {
@@ -1667,7 +1674,7 @@
 
     // Check for static or virtual call
     bool is_static_call = false;
-    nmethod* caller_nm = CodeCache::find_nmethod(pc);
+    CompiledMethod* caller_nm = CodeCache::find_compiled(pc);
 
     // Default call_addr is the location of the "basic" call.
     // Determine the address of the call we a reresolving. With
@@ -1802,12 +1809,12 @@
   // ask me how I know this...
 
   CodeBlob* cb = CodeCache::find_blob(caller_pc);
-  if (!cb->is_nmethod() || entry_point == moop->get_c2i_entry()) {
+  if (!cb->is_compiled() || entry_point == moop->get_c2i_entry()) {
     return;
   }
 
   // The check above makes sure this is a nmethod.
-  nmethod* nm = cb->as_nmethod_or_null();
+  CompiledMethod* nm = cb->as_compiled_method_or_null();
   assert(nm, "must be");
 
   // Get the return PC for the passed caller PC.
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -188,7 +188,7 @@
 #endif // INCLUDE_ALL_GCS
 
   // exception handling and implicit exceptions
-  static address compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception,
+  static address compute_compiled_exc_handler(CompiledMethod* nm, address ret_pc, Handle& exception,
                                               bool force_unwind, bool top_frame_only);
   enum ImplicitExceptionKind {
     IMPLICIT_NULL,
@@ -207,7 +207,7 @@
                                                      address faulting_pc,
                                                      ImplicitExceptionKind exception_kind);
 #if INCLUDE_JVMCI
-  static address deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason);
+  static address deoptimize_for_implicit_exception(JavaThread* thread, address pc, CompiledMethod* nm, int deopt_reason);
 #endif
 
   static void enable_stack_reserved_zone(JavaThread* thread);
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -192,7 +192,7 @@
 }
 
 nmethod* SimpleThresholdPolicy::event(const methodHandle& method, const methodHandle& inlinee,
-                                      int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) {
+                                      int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) {
   if (comp_level == CompLevel_none &&
       JvmtiExport::can_post_interpreter_events() &&
       thread->is_interp_only_mode()) {
@@ -392,7 +392,7 @@
 
 // Handle the invocation event.
 void SimpleThresholdPolicy::method_invocation_event(const methodHandle& mh, const methodHandle& imh,
-                                              CompLevel level, nmethod* nm, JavaThread* thread) {
+                                              CompLevel level, CompiledMethod* nm, JavaThread* thread) {
   if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
     CompLevel next_level = call_event(mh(), level);
     if (next_level != level) {
@@ -404,7 +404,7 @@
 // Handle the back branch event. Notice that we can compile the method
 // with a regular entry from here.
 void SimpleThresholdPolicy::method_back_branch_event(const methodHandle& mh, const methodHandle& imh,
-                                                     int bci, CompLevel level, nmethod* nm, JavaThread* thread) {
+                                                     int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread) {
   // If the method is already compiling, quickly bail out.
   if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
     // Use loop event as an opportunity to also check there's been
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -81,16 +81,16 @@
 
   // Get a compilation level for a given method.
   static CompLevel comp_level(Method* method) {
-    nmethod *nm = method->code();
+    CompiledMethod *nm = method->code();
     if (nm != NULL && nm->is_in_use()) {
       return (CompLevel)nm->comp_level();
     }
     return CompLevel_none;
   }
   virtual void method_invocation_event(const methodHandle& method, const methodHandle& inlinee,
-                                       CompLevel level, nmethod* nm, JavaThread* thread);
+                                       CompLevel level, CompiledMethod* nm, JavaThread* thread);
   virtual void method_back_branch_event(const methodHandle& method, const methodHandle& inlinee,
-                                        int bci, CompLevel level, nmethod* nm, JavaThread* thread);
+                                        int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread);
 public:
   SimpleThresholdPolicy() : _c1_count(0), _c2_count(0) { }
   virtual int compiler_count(CompLevel comp_level) {
@@ -104,7 +104,7 @@
   virtual void disable_compilation(Method* method) { }
   virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
   virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee,
-                         int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread);
+                         int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread);
   // Select task is called by CompileBroker. We should return a task or NULL.
   virtual CompileTask* select_task(CompileQueue* compile_queue);
   // Tell the runtime if we think a given method is adequately profiled.
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -254,8 +254,8 @@
       (_code2 != NULL && _code2->blob_contains(addr)) ;
   }
 
-  static CodeBlob* code1() { return _code1; }
-  static CodeBlob* code2() { return _code2; }
+  static RuntimeBlob* code1() { return _code1; }
+  static RuntimeBlob* code2() { return _code2; }
 
   // Debugging
   static jint    verify_oop_count()                        { return _verify_oop_count; }
--- a/hotspot/src/share/vm/runtime/sweeper.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -109,13 +109,13 @@
   }
 }
 
-void NMethodSweeper::record_sweep(nmethod* nm, int line) {
+void NMethodSweeper::record_sweep(CompiledMethod* nm, int line) {
   if (_records != NULL) {
     _records[_sweep_index].traversal = _traversals;
-    _records[_sweep_index].traversal_mark = nm->_stack_traversal_mark;
+    _records[_sweep_index].traversal_mark = nm->is_nmethod() ? ((nmethod*)nm)->_stack_traversal_mark : 0;
     _records[_sweep_index].compile_id = nm->compile_id();
     _records[_sweep_index].kind = nm->compile_kind();
-    _records[_sweep_index].state = nm->_state;
+    _records[_sweep_index].state = nm->get_state();
     _records[_sweep_index].vep = nm->verified_entry_point();
     _records[_sweep_index].uep = nm->entry_point();
     _records[_sweep_index].line = line;
@@ -134,7 +134,7 @@
 #define SWEEP(nm)
 #endif
 
-NMethodIterator NMethodSweeper::_current;                      // Current nmethod
+CompiledMethodIterator NMethodSweeper::_current;               // Current compiled method
 long     NMethodSweeper::_traversals                   = 0;    // Stack scan count, also sweep ID.
 long     NMethodSweeper::_total_nof_code_cache_sweeps  = 0;    // Total number of full sweeps of the code cache
 long     NMethodSweeper::_time_counter                 = 0;    // Virtual time used to periodically invoke sweeper
@@ -210,10 +210,17 @@
   _time_counter++;
 
   // Check for restart
-  assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
+  if (_current.method() != NULL) {
+    if (_current.method()->is_nmethod()) {
+      assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
+    } else {
+      ShouldNotReachHere();
+    }
+  }
+
   if (wait_for_stack_scanning()) {
     _seen = 0;
-    _current = NMethodIterator();
+    _current = CompiledMethodIterator();
     // Initialize to first nmethod
     _current.next();
     _traversals += 1;
@@ -415,14 +422,15 @@
       // Since we will give up the CodeCache_lock, always skip ahead
       // to the next nmethod.  Other blobs can be deleted by other
       // threads but nmethods are only reclaimed by the sweeper.
-      nmethod* nm = _current.method();
+      CompiledMethod* nm = _current.method();
       _current.next();
 
       // Now ready to process nmethod and give up CodeCache_lock
       {
         MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
         // Save information before potentially flushing the nmethod
-        int size = nm->total_size();
+        // Only flushing nmethods so size only matters for them.
+        int size = nm->is_nmethod() ? ((nmethod*)nm)->total_size() : 0;
         bool is_c2_method = nm->is_compiled_by_c2();
         bool is_osr = nm->is_osr_method();
         int compile_id = nm->compile_id();
@@ -430,7 +438,7 @@
         const char* state_before = nm->state();
         const char* state_after = "";
 
-        MethodStateChange type = process_nmethod(nm);
+        MethodStateChange type = process_compiled_method(nm);
         switch (type) {
           case Flushed:
             state_after = "flushed";
@@ -532,28 +540,28 @@
   }
 }
 
-class NMethodMarker: public StackObj {
+class CompiledMethodMarker: public StackObj {
  private:
   CodeCacheSweeperThread* _thread;
  public:
-  NMethodMarker(nmethod* nm) {
+  CompiledMethodMarker(CompiledMethod* cm) {
     JavaThread* current = JavaThread::current();
     assert (current->is_Code_cache_sweeper_thread(), "Must be");
     _thread = (CodeCacheSweeperThread*)current;
-    if (!nm->is_zombie() && !nm->is_unloaded()) {
+    if (!cm->is_zombie() && !cm->is_unloaded()) {
       // Only expose live nmethods for scanning
-      _thread->set_scanned_nmethod(nm);
+      _thread->set_scanned_compiled_method(cm);
     }
   }
-  ~NMethodMarker() {
-    _thread->set_scanned_nmethod(NULL);
+  ~CompiledMethodMarker() {
+    _thread->set_scanned_compiled_method(NULL);
   }
 };
 
-void NMethodSweeper::release_nmethod(nmethod* nm) {
+void NMethodSweeper::release_compiled_method(CompiledMethod* nm) {
   // Make sure the released nmethod is no longer referenced by the sweeper thread
   CodeCacheSweeperThread* thread = (CodeCacheSweeperThread*)JavaThread::current();
-  thread->set_scanned_nmethod(NULL);
+  thread->set_scanned_compiled_method(NULL);
 
   // Clean up any CompiledICHolders
   {
@@ -571,98 +579,100 @@
   nm->flush();
 }
 
-NMethodSweeper::MethodStateChange NMethodSweeper::process_nmethod(nmethod* nm) {
-  assert(nm != NULL, "sanity");
+NMethodSweeper::MethodStateChange NMethodSweeper::process_compiled_method(CompiledMethod* cm) {
+  assert(cm != NULL, "sanity");
   assert(!CodeCache_lock->owned_by_self(), "just checking");
 
   MethodStateChange result = None;
   // Make sure this nmethod doesn't get unloaded during the scan,
   // since safepoints may happen during acquired below locks.
-  NMethodMarker nmm(nm);
-  SWEEP(nm);
+  CompiledMethodMarker nmm(cm);
+  SWEEP(cm);
 
   // Skip methods that are currently referenced by the VM
-  if (nm->is_locked_by_vm()) {
+  if (cm->is_locked_by_vm()) {
     // But still remember to clean-up inline caches for alive nmethods
-    if (nm->is_alive()) {
+    if (cm->is_alive()) {
       // Clean inline caches that point to zombie/non-entrant/unloaded nmethods
       MutexLocker cl(CompiledIC_lock);
-      nm->cleanup_inline_caches();
-      SWEEP(nm);
+      cm->cleanup_inline_caches();
+      SWEEP(cm);
     }
     return result;
   }
 
-  if (nm->is_zombie()) {
+  if (cm->is_zombie()) {
     // All inline caches that referred to this nmethod were cleaned in the
     // previous sweeper cycle. Now flush the nmethod from the code cache.
-    assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
-    release_nmethod(nm);
+    assert(!cm->is_locked_by_vm(), "must not flush locked Compiled Methods");
+    release_compiled_method(cm);
     assert(result == None, "sanity");
     result = Flushed;
-  } else if (nm->is_not_entrant()) {
+  } else if (cm->is_not_entrant()) {
     // If there are no current activations of this method on the
     // stack we can safely convert it to a zombie method
-    if (nm->can_convert_to_zombie()) {
+    if (cm->can_convert_to_zombie()) {
       // Clear ICStubs to prevent back patching stubs of zombie or flushed
       // nmethods during the next safepoint (see ICStub::finalize).
       {
         MutexLocker cl(CompiledIC_lock);
-        nm->clear_ic_stubs();
+        cm->clear_ic_stubs();
       }
       // Code cache state change is tracked in make_zombie()
-      nm->make_zombie();
-      SWEEP(nm);
+      cm->make_zombie();
+      SWEEP(cm);
       // The nmethod may have been locked by JVMTI after being made zombie (see
       // JvmtiDeferredEvent::compiled_method_unload_event()). If so, we cannot
       // flush the osr nmethod directly but have to wait for a later sweeper cycle.
-      if (nm->is_osr_method() && !nm->is_locked_by_vm()) {
+      if (cm->is_osr_method() && !cm->is_locked_by_vm()) {
         // No inline caches will ever point to osr methods, so we can just remove it.
         // Make sure that we unregistered the nmethod with the heap and flushed all
         // dependencies before removing the nmethod (done in make_zombie()).
-        assert(nm->is_zombie(), "nmethod must be unregistered");
-        release_nmethod(nm);
+        assert(cm->is_zombie(), "nmethod must be unregistered");
+        release_compiled_method(cm);
         assert(result == None, "sanity");
         result = Flushed;
       } else {
         assert(result == None, "sanity");
         result = MadeZombie;
-        assert(nm->is_zombie(), "nmethod must be zombie");
+        assert(cm->is_zombie(), "nmethod must be zombie");
       }
     } else {
       // Still alive, clean up its inline caches
       MutexLocker cl(CompiledIC_lock);
-      nm->cleanup_inline_caches();
-      SWEEP(nm);
+      cm->cleanup_inline_caches();
+      SWEEP(cm);
     }
-  } else if (nm->is_unloaded()) {
+  } else if (cm->is_unloaded()) {
     // Code is unloaded, so there are no activations on the stack.
     // Convert the nmethod to zombie or flush it directly in the OSR case.
     {
       // Clean ICs of unloaded nmethods as well because they may reference other
       // unloaded nmethods that may be flushed earlier in the sweeper cycle.
       MutexLocker cl(CompiledIC_lock);
-      nm->cleanup_inline_caches();
+      cm->cleanup_inline_caches();
     }
-    if (nm->is_osr_method()) {
-      SWEEP(nm);
+    if (cm->is_osr_method()) {
+      SWEEP(cm);
       // No inline caches will ever point to osr methods, so we can just remove it
-      release_nmethod(nm);
+      release_compiled_method(cm);
       assert(result == None, "sanity");
       result = Flushed;
     } else {
       // Code cache state change is tracked in make_zombie()
-      nm->make_zombie();
-      SWEEP(nm);
+      cm->make_zombie();
+      SWEEP(cm);
       assert(result == None, "sanity");
       result = MadeZombie;
     }
   } else {
-    possibly_flush(nm);
+    if (cm->is_nmethod()) {
+      possibly_flush((nmethod*)cm);
+    }
     // Clean inline caches that point to zombie/non-entrant/unloaded nmethods
     MutexLocker cl(CompiledIC_lock);
-    nm->cleanup_inline_caches();
-    SWEEP(nm);
+    cm->cleanup_inline_caches();
+    SWEEP(cm);
   }
   return result;
 }
--- a/hotspot/src/share/vm/runtime/sweeper.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/sweeper.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -66,7 +66,7 @@
   static long      _total_nof_code_cache_sweeps;  // Total number of full sweeps of the code cache
   static long      _time_counter;                 // Virtual time used to periodically invoke sweeper
   static long      _last_sweep;                   // Value of _time_counter when the last sweep happened
-  static NMethodIterator _current;                // Current nmethod
+  static CompiledMethodIterator _current;         // Current compiled method
   static int       _seen;                         // Nof. nmethod we have currently processed in current pass of CodeCache
 
   static volatile int  _sweep_started;            // Flag to control conc sweeper
@@ -88,8 +88,8 @@
 
   static Monitor*  _stat_lock;
 
-  static MethodStateChange process_nmethod(nmethod *nm);
-  static void              release_nmethod(nmethod* nm);
+  static MethodStateChange process_compiled_method(CompiledMethod *nm);
+  static void              release_compiled_method(CompiledMethod* nm);
 
   static void init_sweeper_log() NOT_DEBUG_RETURN;
   static bool wait_for_stack_scanning();
@@ -107,9 +107,8 @@
 
 
 #ifdef ASSERT
-  static bool is_sweeping(nmethod* which) { return _current.method() == which; }
   // Keep track of sweeper activity in the ring buffer
-  static void record_sweep(nmethod* nm, int line);
+  static void record_sweep(CompiledMethod* nm, int line);
   static void report_events(int id, address entry);
   static void report_events();
 #endif
--- a/hotspot/src/share/vm/runtime/thread.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1432,7 +1432,7 @@
   set_vframe_array_last(NULL);
   set_deferred_locals(NULL);
   set_deopt_mark(NULL);
-  set_deopt_nmethod(NULL);
+  set_deopt_compiled_method(NULL);
   clear_must_deopt_id();
   set_monitor_chunks(NULL);
   set_next(NULL);
@@ -3300,26 +3300,26 @@
 // Create sweeper thread
 CodeCacheSweeperThread::CodeCacheSweeperThread()
 : JavaThread(&sweeper_thread_entry) {
-  _scanned_nmethod = NULL;
+  _scanned_compiled_method = NULL;
 }
 
 void CodeCacheSweeperThread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
   JavaThread::oops_do(f, cld_f, cf);
-  if (_scanned_nmethod != NULL && cf != NULL) {
+  if (_scanned_compiled_method != NULL && cf != NULL) {
     // Safepoints can occur when the sweeper is scanning an nmethod so
     // process it here to make sure it isn't unloaded in the middle of
     // a scan.
-    cf->do_code_blob(_scanned_nmethod);
+    cf->do_code_blob(_scanned_compiled_method);
   }
 }
 
 void CodeCacheSweeperThread::nmethods_do(CodeBlobClosure* cf) {
   JavaThread::nmethods_do(cf);
-  if (_scanned_nmethod != NULL && cf != NULL) {
+  if (_scanned_compiled_method != NULL && cf != NULL) {
     // Safepoints can occur when the sweeper is scanning an nmethod so
     // process it here to make sure it isn't unloaded in the middle of
     // a scan.
-    cf->do_code_blob(_scanned_nmethod);
+    cf->do_code_blob(_scanned_compiled_method);
   }
 }
 
@@ -4353,7 +4353,7 @@
   ALL_JAVA_THREADS(p) {
     // This is used by the code cache sweeper to mark nmethods that are active
     // on the stack of a Java thread. Ignore the sweeper thread itself to avoid
-    // marking CodeCacheSweeperThread::_scanned_nmethod as active.
+    // marking CodeCacheSweeperThread::_scanned_compiled_method as active.
     if(!p->is_Code_cache_sweeper_thread()) {
       p->nmethods_do(cf);
     }
--- a/hotspot/src/share/vm/runtime/thread.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -820,7 +820,7 @@
 
   intptr_t*      _must_deopt_id;                 // id of frame that needs to be deopted once we
                                                  // transition out of native
-  nmethod*       _deopt_nmethod;                 // nmethod that is currently being deoptimized
+  CompiledMethod*       _deopt_nmethod;         // CompiledMethod that is currently being deoptimized
   vframeArray*  _vframe_array_head;              // Holds the heap of the active vframeArrays
   vframeArray*  _vframe_array_last;              // Holds last vFrameArray we popped
   // Because deoptimization is lazy we must save jvmti requests to set locals
@@ -1298,8 +1298,8 @@
   void     set_must_deopt_id(intptr_t* id)       { _must_deopt_id = id; }
   void     clear_must_deopt_id()                 { _must_deopt_id = NULL; }
 
-  void set_deopt_nmethod(nmethod* nm)            { _deopt_nmethod = nm;   }
-  nmethod* deopt_nmethod()                       { return _deopt_nmethod; }
+  void set_deopt_compiled_method(CompiledMethod* nm)  { _deopt_nmethod = nm; }
+  CompiledMethod* deopt_compiled_method()        { return _deopt_nmethod; }
 
   Method*    callee_target() const               { return _callee_target; }
   void set_callee_target  (Method* x)          { _callee_target   = x; }
@@ -1980,13 +1980,13 @@
 
 // Dedicated thread to sweep the code cache
 class CodeCacheSweeperThread : public JavaThread {
-  nmethod*       _scanned_nmethod; // nmethod being scanned by the sweeper
+  CompiledMethod*       _scanned_compiled_method; // nmethod being scanned by the sweeper
  public:
   CodeCacheSweeperThread();
   // Track the nmethod currently being scanned by the sweeper
-  void set_scanned_nmethod(nmethod* nm) {
-    assert(_scanned_nmethod == NULL || nm == NULL, "should reset to NULL before writing a new value");
-    _scanned_nmethod = nm;
+  void set_scanned_compiled_method(CompiledMethod* cm) {
+    assert(_scanned_compiled_method == NULL || cm == NULL, "should reset to NULL before writing a new value");
+    _scanned_compiled_method = cm;
   }
 
   // Hide sweeper thread from external view.
@@ -1994,7 +1994,7 @@
 
   bool is_Code_cache_sweeper_thread() const { return true; }
 
-  // Prevent GC from unloading _scanned_nmethod
+  // Prevent GC from unloading _scanned_compiled_method
   void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
   void nmethods_do(CodeBlobClosure* cf);
 };
--- a/hotspot/src/share/vm/runtime/vframe.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/vframe.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -67,8 +67,8 @@
   // Compiled frame
   CodeBlob* cb = f->cb();
   if (cb != NULL) {
-    if (cb->is_nmethod()) {
-      nmethod* nm = (nmethod*)cb;
+    if (cb->is_compiled()) {
+      CompiledMethod* nm = (CompiledMethod*)cb;
       return new compiledVFrame(f, reg_map, thread, nm);
     }
 
--- a/hotspot/src/share/vm/runtime/vframe.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/vframe.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -66,9 +66,9 @@
   // Accessors
   frame              fr()           const { return _fr;       }
   CodeBlob*          cb()         const { return _fr.cb();  }
-  nmethod*           nm()         const {
-      assert( cb() != NULL && cb()->is_nmethod(), "usage");
-      return (nmethod*) cb();
+  CompiledMethod*   nm()         const {
+      assert( cb() != NULL && cb()->is_compiled(), "usage");
+      return (CompiledMethod*) cb();
   }
 
 // ???? Does this need to be a copy?
@@ -326,9 +326,9 @@
   }
 
   CodeBlob*          cb()         const { return _frame.cb();  }
-  nmethod*           nm()         const {
-    assert( cb() != NULL && cb()->is_nmethod(), "usage");
-    return (nmethod*) cb();
+  CompiledMethod*   nm()         const {
+      assert( cb() != NULL && cb()->is_compiled(), "usage");
+      return (CompiledMethod*) cb();
   }
 
   // Frame type
@@ -449,7 +449,7 @@
 
   // Compiled frame
 
-  if (cb() != NULL && cb()->is_nmethod()) {
+  if (cb() != NULL && cb()->is_compiled()) {
     if (nm()->is_native_method()) {
       // Do not rely on scopeDesc since the pc might be unprecise due to the _last_native_pc trick.
       fill_from_compiled_native_frame();
--- a/hotspot/src/share/vm/runtime/vframeArray.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/vframeArray.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -206,8 +206,8 @@
   // in which case bcp should point to the monitorenter since it is within the exception's range.
 
   assert(*bcp != Bytecodes::_monitorenter || is_top_frame, "a _monitorenter must be a top frame");
-  assert(thread->deopt_nmethod() != NULL, "nmethod should be known");
-  guarantee(!(thread->deopt_nmethod()->is_compiled_by_c2() &&
+  assert(thread->deopt_compiled_method() != NULL, "compiled method should be known");
+  guarantee(!(thread->deopt_compiled_method()->is_compiled_by_c2() &&
               *bcp == Bytecodes::_monitorenter             &&
               exec_mode == Deoptimization::Unpack_exception),
             "shouldn't get exception during monitorenter");
--- a/hotspot/src/share/vm/runtime/vframe_hp.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/vframe_hp.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -196,7 +196,7 @@
 GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
   // Natives has no scope
   if (scope() == NULL) {
-    nmethod* nm = code();
+    CompiledMethod* nm = code();
     Method* method = nm->method();
     assert(method->is_native(), "");
     if (!method->is_synchronized()) {
@@ -240,13 +240,13 @@
 }
 
 
-compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, nmethod* nm)
+compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, CompiledMethod* nm)
 : javaVFrame(fr, reg_map, thread) {
   _scope  = NULL;
   // Compiled method (native stub or Java code)
   // native wrappers have no scope data, it is implied
-  if (!nm->is_native_method()) {
-    _scope  = nm->scope_desc_at(_fr.pc());
+  if (!nm->is_compiled() || !nm->as_compiled_method()->is_native_method()) {
+      _scope  = nm->scope_desc_at(_fr.pc());
   }
 }
 
@@ -264,15 +264,15 @@
 }
 
 
-nmethod* compiledVFrame::code() const {
-  return CodeCache::find_nmethod(_fr.pc());
+CompiledMethod* compiledVFrame::code() const {
+  return CodeCache::find_compiled(_fr.pc());
 }
 
 
 Method* compiledVFrame::method() const {
   if (scope() == NULL) {
     // native nmethods have no scope the method is implied
-    nmethod* nm = code();
+    nmethod* nm = code()->as_nmethod();
     assert(nm->is_native_method(), "must be native");
     return nm->method();
   }
@@ -289,7 +289,7 @@
 int compiledVFrame::raw_bci() const {
   if (scope() == NULL) {
     // native nmethods have no scope the method/bci is implied
-    nmethod* nm = code();
+    nmethod* nm = code()->as_nmethod();
     assert(nm->is_native_method(), "must be native");
     return 0;
   }
@@ -299,7 +299,7 @@
 bool compiledVFrame::should_reexecute() const {
   if (scope() == NULL) {
     // native nmethods have no scope the method/bci is implied
-    nmethod* nm = code();
+    nmethod* nm = code()->as_nmethod();
     assert(nm->is_native_method(), "must be native");
     return false;
   }
@@ -310,7 +310,7 @@
   const frame f = fr();
   if (scope() == NULL) {
     // native nmethods have no scope the method/bci is implied
-    nmethod* nm = code();
+    nmethod* nm = code()->as_nmethod();
     assert(nm->is_native_method(), "must be native");
     return vframe::sender();
   } else {
--- a/hotspot/src/share/vm/runtime/vframe_hp.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/vframe_hp.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,13 +52,13 @@
 
  public:
   // Constructors
-  compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, nmethod* nm);
+  compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, CompiledMethod* nm);
 
   // Update a local in a compiled frame. Update happens when deopt occurs
   void update_local(BasicType type, int index, jvalue value);
 
   // Returns the active nmethod
-  nmethod*  code() const;
+  CompiledMethod*  code() const;
 
   // Returns the scopeDesc
   ScopeDesc* scope() const { return _scope; }
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -398,7 +398,7 @@
   nonstatic_field(Method,                      _intrinsic_id,                                 u2)                                    \
   nonstatic_field(Method,                      _flags,                                        u2)                                    \
   nonproduct_nonstatic_field(Method,           _compiled_invocation_count,                    int)                                   \
-  volatile_nonstatic_field(Method,             _code,                                         nmethod*)                              \
+  volatile_nonstatic_field(Method,             _code,                                         CompiledMethod*)                       \
   nonstatic_field(Method,                      _i2i_entry,                                    address)                               \
   volatile_nonstatic_field(Method,             _from_compiled_entry,                          address)                               \
   volatile_nonstatic_field(Method,             _from_interpreted_entry,                       address)                               \
@@ -915,40 +915,47 @@
   /* CodeBlobs (NOTE: incomplete, but only a little) */                                                                              \
   /***************************************************/                                                                              \
                                                                                                                                      \
-  nonstatic_field(CodeBlob,                    _name,                                   const char*)                                 \
-  nonstatic_field(CodeBlob,                    _size,                                   int)                                         \
-  nonstatic_field(CodeBlob,                    _header_size,                            int)                                         \
-  nonstatic_field(CodeBlob,                    _relocation_size,                        int)                                         \
-  nonstatic_field(CodeBlob,                    _content_offset,                         int)                                         \
-  nonstatic_field(CodeBlob,                    _code_offset,                            int)                                         \
-  nonstatic_field(CodeBlob,                    _frame_complete_offset,                  int)                                         \
-  nonstatic_field(CodeBlob,                    _data_offset,                            int)                                         \
-  nonstatic_field(CodeBlob,                    _frame_size,                             int)                                         \
-  nonstatic_field(CodeBlob,                    _oop_maps,                               ImmutableOopMapSet*)                         \
+  nonstatic_field(CodeBlob,                 _name,                                   const char*)                                    \
+  nonstatic_field(CodeBlob,                 _size,                                   int)                                            \
+  nonstatic_field(CodeBlob,                 _header_size,                            int)                                            \
+  nonstatic_field(CodeBlob,                 _frame_complete_offset,                  int)                                            \
+  nonstatic_field(CodeBlob,                 _data_offset,                            int)                                            \
+  nonstatic_field(CodeBlob,                 _frame_size,                             int)                                            \
+  nonstatic_field(CodeBlob,                 _oop_maps,                               ImmutableOopMapSet*)                            \
+  nonstatic_field(CodeBlob,                 _code_begin,                             address)                                        \
+  nonstatic_field(CodeBlob,                 _code_end,                               address)                                        \
+  nonstatic_field(CodeBlob,                 _content_begin,                          address)                                        \
+  nonstatic_field(CodeBlob,                 _data_end,                               address)                                        \
                                                                                                                                      \
   nonstatic_field(DeoptimizationBlob,          _unpack_offset,                                int)                                   \
                                                                                                                                      \
   nonstatic_field(RuntimeStub,                 _caller_must_gc_arguments,                     bool)                                  \
                                                                                                                                      \
+  /********************************************************/                                                                         \
+  /* CompiledMethod (NOTE: incomplete, but only a little) */                                                                         \
+  /********************************************************/                                                                         \
+                                                                                                                                     \
+  nonstatic_field(CompiledMethod,                     _method,                                       Method*)                        \
+  volatile_nonstatic_field(CompiledMethod,            _exception_cache,                              ExceptionCache*)                \
+  nonstatic_field(CompiledMethod,                     _scopes_data_begin,                            address)                        \
+  nonstatic_field(CompiledMethod,                     _deopt_handler_begin,                          address)                        \
+  nonstatic_field(CompiledMethod,                     _deopt_mh_handler_begin,                       address)                        \
+                                                                                                                                     \
   /**************************************************/                                                                               \
   /* NMethods (NOTE: incomplete, but only a little) */                                                                               \
   /**************************************************/                                                                               \
                                                                                                                                      \
-  nonstatic_field(nmethod,                     _method,                                       Method*)                               \
   nonstatic_field(nmethod,                     _entry_bci,                                    int)                                   \
   nonstatic_field(nmethod,                     _osr_link,                                     nmethod*)                              \
   nonstatic_field(nmethod,                     _scavenge_root_link,                           nmethod*)                              \
   nonstatic_field(nmethod,                     _scavenge_root_state,                          jbyte)                                 \
   nonstatic_field(nmethod,                     _state,                                        volatile unsigned char)                \
   nonstatic_field(nmethod,                     _exception_offset,                             int)                                   \
-  nonstatic_field(nmethod,                     _deoptimize_offset,                            int)                                   \
-  nonstatic_field(nmethod,                     _deoptimize_mh_offset,                         int)                                   \
   nonstatic_field(nmethod,                     _orig_pc_offset,                               int)                                   \
   nonstatic_field(nmethod,                     _stub_offset,                                  int)                                   \
   nonstatic_field(nmethod,                     _consts_offset,                                int)                                   \
   nonstatic_field(nmethod,                     _oops_offset,                                  int)                                   \
   nonstatic_field(nmethod,                     _metadata_offset,                              int)                                   \
-  nonstatic_field(nmethod,                     _scopes_data_offset,                           int)                                   \
   nonstatic_field(nmethod,                     _scopes_pcs_offset,                            int)                                   \
   nonstatic_field(nmethod,                     _dependencies_offset,                          int)                                   \
   nonstatic_field(nmethod,                     _handler_table_offset,                         int)                                   \
@@ -961,7 +968,6 @@
   nonstatic_field(nmethod,                     _stack_traversal_mark,                         long)                                  \
   nonstatic_field(nmethod,                     _compile_id,                                   int)                                   \
   nonstatic_field(nmethod,                     _comp_level,                                   int)                                   \
-  volatile_nonstatic_field(nmethod,            _exception_cache,                              ExceptionCache*)                       \
                                                                                                                                      \
   unchecked_c2_static_field(Deoptimization,    _trap_reason_name,                             void*)                                 \
                                                                                                                                      \
@@ -1744,16 +1750,18 @@
   declare_toplevel_type(SharedRuntime)                                    \
                                                                           \
   declare_toplevel_type(CodeBlob)                                         \
-  declare_type(BufferBlob,               CodeBlob)                        \
+  declare_type(RuntimeBlob,             CodeBlob)                        \
+  declare_type(BufferBlob,               RuntimeBlob)                    \
   declare_type(AdapterBlob,              BufferBlob)                      \
   declare_type(MethodHandlesAdapterBlob, BufferBlob)                      \
-  declare_type(nmethod,                  CodeBlob)                        \
-  declare_type(RuntimeStub,              CodeBlob)                        \
-  declare_type(SingletonBlob,            CodeBlob)                        \
+  declare_type(CompiledMethod,           CodeBlob)                        \
+  declare_type(nmethod,                  CompiledMethod)                  \
+  declare_type(RuntimeStub,              RuntimeBlob)                    \
+  declare_type(SingletonBlob,            RuntimeBlob)                    \
   declare_type(SafepointBlob,            SingletonBlob)                   \
   declare_type(DeoptimizationBlob,       SingletonBlob)                   \
   declare_c2_type(ExceptionBlob,         SingletonBlob)                   \
-  declare_c2_type(UncommonTrapBlob,      CodeBlob)                        \
+  declare_c2_type(UncommonTrapBlob,      RuntimeBlob)                        \
                                                                           \
   /***************************************/                               \
   /* PcDesc and other compiled code info */                               \
@@ -2236,6 +2244,7 @@
   declare_toplevel_type(BreakpointInfo)                                   \
   declare_toplevel_type(BreakpointInfo*)                                  \
   declare_toplevel_type(CodeBlob*)                                        \
+  declare_toplevel_type(RuntimeBlob*)                                     \
   declare_toplevel_type(CompressedWriteStream*)                           \
   declare_toplevel_type(ConstantPoolCacheEntry)                           \
   declare_toplevel_type(elapsedTimer)                                     \
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1003,7 +1003,9 @@
 class VMOperationQueue;
 
 class CodeBlob;
-class  nmethod;
+class  CompiledMethod;
+class   nmethod;
+class RuntimeBlob;
 class  OSRAdapter;
 class  I2CAdapter;
 class  C2IAdapter;
--- a/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -84,7 +84,7 @@
             Asserts.assertEQ(initialUsage, 0L, "Unexpected initial usage");
         }
         ArrayList<Long> blobs = new ArrayList<>();
-        long minAllocationUnit = CodeCacheUtils.MIN_ALLOCATION - headerSize;
+        long minAllocationUnit = Math.max(0, CodeCacheUtils.MIN_ALLOCATION - headerSize);
         /* now filling code cache with large-sized allocation first, since
          lots of small allocations takes too much time, so, just a small
          optimization */
--- a/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -67,7 +67,7 @@
 
     protected void runTest() {
         long headerSize = CodeCacheUtils.getHeaderSize(btype);
-        long allocationUnit = CodeCacheUtils.MIN_ALLOCATION - headerSize;
+        long allocationUnit = Math.max(0, CodeCacheUtils.MIN_ALLOCATION - headerSize);
         MemoryPoolMXBean bean = btype.getMemoryPool();
         long initialCount = bean.getUsageThresholdCount();
         long initialSize = bean.getUsage().getUsed();
--- a/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,9 +58,12 @@
         MemoryPoolMXBean bean = btype.getMemoryPool();
         long initialThresholdCount = bean.getUsageThresholdCount();
         long initialUsage = bean.getUsage().getUsed();
+
         bean.setUsageThreshold(initialUsage + 1 + CodeCacheUtils.MIN_ALLOCATION);
-        CodeCacheUtils.WB.allocateCodeBlob(CodeCacheUtils.MIN_ALLOCATION
-                - CodeCacheUtils.getHeaderSize(btype), btype.id);
+        long size = CodeCacheUtils.getHeaderSize(btype);
+
+        CodeCacheUtils.WB.allocateCodeBlob(Math.max(0, CodeCacheUtils.MIN_ALLOCATION
+                - size), btype.id);
         // a gc cycle triggers usage threshold recalculation
         CodeCacheUtils.WB.fullGC();
         CodeCacheUtils.assertEQorGTE(btype, bean.getUsageThresholdCount(), initialThresholdCount,