changeset 52872:e9aa1c8a7794 fibers

Merge
author rbackman
date Fri, 30 Nov 2018 14:43:10 +0100
parents bf14dcc08909 089091b079bc
children bbef43f7dfd8
files
diffstat 9 files changed, 174 insertions(+), 118 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/cpu/x86/frame_x86.cpp	Thu Nov 29 12:48:23 2018 +0000
+++ b/src/hotspot/cpu/x86/frame_x86.cpp	Fri Nov 30 14:43:10 2018 +0100
@@ -537,37 +537,6 @@
   return true;
 }
 
-const ImmutableOopMap* frame::get_oop_map() const {
-  if (_cb == NULL) return NULL;
-  if (_cb->oop_maps() != NULL) {
-    NativePostCallNop* nop = nativePostCallNop_at(_pc);
-    if (nop != NULL && nop->displacement() != 0) {
-      int slot = ((nop->displacement() >> 24) & 0xff);
-      return _cb->oop_map_for_slot(slot, _pc);
-    }
-    const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
-    return oop_map;
-  }
-  return NULL;
-  // if (CodeCache::contains(pc()) && is_compiled_frame()) {
-  //   unsigned char *oopmap_metadata_header = (unsigned char *)pc();
-  //   if (*oopmap_metadata_header != 0x49) {
-  //     tty->print_cr("wrong oopmap_metadata_header");
-  //     print_on(tty);
-  //     for (int i=0; i<10; i++) tty->print_cr("$$ " INTPTR_FORMAT ": %x", p2i(oopmap_metadata_header + i), *(oopmap_metadata_header+i));
-  //   }
-  //   assert (*oopmap_metadata_header == 0x49, "oopmap_metadata_header: %x pc: " INTPTR_FORMAT " (" INTPTR_FORMAT ")", *oopmap_metadata_header, p2i(pc()), p2i(raw_pc()));
-
-  //   long oopmap_metadata = *((long*)(oopmap_metadata_header + 2));
-  //   if (oopmap_metadata != 1234) {
-  //     tty->print_cr("wrong oopmap_metadata");
-  //     print_on(tty);
-  //     for (int i=0; i<10; i++) tty->print_cr("$$ " INTPTR_FORMAT ": %x", p2i(oopmap_metadata_header + i), *(oopmap_metadata_header+i));
-  //   }
-  //   assert (oopmap_metadata == 1234, "oopmap_metadata: %ld pc: " INTPTR_FORMAT " (" INTPTR_FORMAT ")", oopmap_metadata, p2i(pc()), p2i(raw_pc()));
-  // }
-}
-
 BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {
   assert(is_interpreted_frame(), "interpreted frame expected");
   Method* method = interpreter_frame_method();
--- a/src/hotspot/cpu/x86/frame_x86.hpp	Thu Nov 29 12:48:23 2018 +0000
+++ b/src/hotspot/cpu/x86/frame_x86.hpp	Fri Nov 30 14:43:10 2018 +0100
@@ -139,6 +139,8 @@
 
   frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb);
 
+  frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map);
+
   frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, bool deopt);
 
   frame(intptr_t* sp, intptr_t* fp);
--- a/src/hotspot/cpu/x86/frame_x86.inline.hpp	Thu Nov 29 12:48:23 2018 +0000
+++ b/src/hotspot/cpu/x86/frame_x86.inline.hpp	Fri Nov 30 14:43:10 2018 +0100
@@ -26,7 +26,10 @@
 #define CPU_X86_VM_FRAME_X86_INLINE_HPP
 
 #include "code/codeCache.hpp"
+#include "code/codeCache.inline.hpp"
 #include "code/vmreg.inline.hpp"
+#include "compiler/oopMap.inline.hpp"
+#include "runtime/sharedRuntime.hpp"
 
 // Inline functions for Intel frames:
 
@@ -77,6 +80,17 @@
   setup(pc);
 }
 
+inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map) {
+  _sp = sp;
+  _unextended_sp = unextended_sp;
+  _fp = fp;
+  _pc = pc;
+  assert(pc != NULL, "no pc?");
+  _cb = cb;
+  _oop_map = oop_map;
+  setup(pc);
+}
+
 inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) {
   _sp = sp;
   _unextended_sp = unextended_sp;
@@ -99,7 +113,7 @@
            "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
     _deopt_state = is_deoptimized;
   } else {
-    if (_cb->is_deoptimization_stub()) {
+    if (_cb == SharedRuntime::deopt_blob()) {
       _deopt_state = is_deoptimized;
     } else {
       _deopt_state = not_deoptimized;
@@ -374,4 +388,18 @@
   return frame(sender_sp, unextended_sp, *saved_fp_addr, sender_pc);
 }
 
+inline const ImmutableOopMap* frame::get_oop_map() const {
+  if (_cb == NULL) return NULL;
+  if (_cb->oop_maps() != NULL) {
+    NativePostCallNop* nop = nativePostCallNop_at(_pc);
+    if (nop != NULL && nop->displacement() != 0) {
+      int slot = ((nop->displacement() >> 24) & 0xff);
+      return _cb->oop_map_for_slot(slot, _pc);
+    }
+    const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
+    return oop_map;
+  }
+  return NULL;
+}
+
 #endif // CPU_X86_VM_FRAME_X86_INLINE_HPP
--- a/src/hotspot/share/code/codeCache.cpp	Thu Nov 29 12:48:23 2018 +0000
+++ b/src/hotspot/share/code/codeCache.cpp	Fri Nov 30 14:43:10 2018 +0100
@@ -640,32 +640,21 @@
   return NULL;
 }
 
-CodeBlob* CodeCache::find_blob_fast(void* pc) {
-  NativePostCallNop* nop = nativePostCallNop_at((address) pc);
-  if (nop != NULL) {
-    CodeBlob* cb;
-    if (nop->displacement() != 0) {
-      int offset = (nop->displacement() & 0xffffff);
-      cb = (CodeBlob*) ((address) pc - offset);
-    } else {
-      cb = CodeCache::find_blob(pc);
-      int oopmap_slot = cb->oop_maps()->find_slot_for_offset((intptr_t) pc - (intptr_t) cb->code_begin());
-      intptr_t cbaddr = (intptr_t) cb;
-      intptr_t offset = ((intptr_t) pc) - cbaddr;
+CodeBlob* CodeCache::patch_nop(NativePostCallNop* nop, void* pc, int& slot) {
+  CodeBlob* cb = CodeCache::find_blob(pc);
+  int oopmap_slot = cb->oop_maps()->find_slot_for_offset((intptr_t) pc - (intptr_t) cb->code_begin());
+  intptr_t cbaddr = (intptr_t) cb;
+  intptr_t offset = ((intptr_t) pc) - cbaddr;
 
-      if (((oopmap_slot & 0xff) == oopmap_slot) && ((offset & 0xffffff) == offset)) {
-        jint value = (oopmap_slot << 24) | (jint) offset;
-        nop->patch(value);
-      } else {
-        log_debug(codecache)("failed to encode %d %d", oopmap_slot, (int) offset);
-      }
-    }
-    assert(cb != NULL, "must be");
-    return cb;
+  if (((oopmap_slot & 0xff) == oopmap_slot) && ((offset & 0xffffff) == offset)) {
+    jint value = (oopmap_slot << 24) | (jint) offset;
+    nop->patch(value);
+    slot = oopmap_slot;
   } else {
-    CodeBlob* cb = CodeCache::find_blob(pc);
-    return cb;
+    slot = -1;
+    log_debug(codecache)("failed to encode %d %d", oopmap_slot, (int) offset);
   }
+  return cb;
 }
 
 nmethod* CodeCache::find_nmethod(void* start) {
--- a/src/hotspot/share/code/codeCache.hpp	Thu Nov 29 12:48:23 2018 +0000
+++ b/src/hotspot/share/code/codeCache.hpp	Fri Nov 30 14:43:10 2018 +0100
@@ -75,6 +75,7 @@
 class ExceptionCache;
 class KlassDepChange;
 class OopClosure;
+class NativePostCallNop;
 
 class CodeCache : AllStatic {
   friend class VMStructs;
@@ -129,6 +130,7 @@
 
   // Make private to prevent unsafe calls.  Not all CodeBlob*'s are embedded in a CodeHeap.
   static bool contains(CodeBlob *p) { fatal("don't call me!"); return false; }
+  static CodeBlob* patch_nop(NativePostCallNop* nop, void* pc, int& slot);
 
  public:
   // Initialization
@@ -159,6 +161,7 @@
   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 CodeBlob* find_blob_fast(void* start);         // Returns the CodeBlob containing the given address
+  static CodeBlob* find_blob_and_oopmap(void* start, int& slot);         // Returns the CodeBlob containing the given address
   static nmethod*  find_nmethod(void* start);           // Returns the nmethod containing the given address
   static CompiledMethod* find_compiled(void* start);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/code/codeCache.inline.hpp	Fri Nov 30 14:43:10 2018 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, 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_COMPILER_CODECACHE_INLINE_HPP
+#define SHARE_VM_COMPILER_CODECACHE_INLINE_HPP
+
+#include "code/codeCache.hpp"
+#include "code/nativeInst.hpp"
+
+inline CodeBlob* CodeCache::find_blob_fast(void* pc) {
+  int slot = 0;
+  return find_blob_and_oopmap(pc, slot);
+}
+
+inline CodeBlob* CodeCache::find_blob_and_oopmap(void* pc, int& slot) {
+  NativePostCallNop* nop = nativePostCallNop_at((address) pc);
+  if (nop != NULL) {
+    CodeBlob* cb;
+    if (nop->displacement() != 0) {
+      int offset = (nop->displacement() & 0xffffff);
+      cb = (CodeBlob*) ((address) pc - offset);
+      slot = ((nop->displacement() >> 24) & 0xff);
+    } else {
+      cb = CodeCache::patch_nop(nop, pc, slot);
+    }
+    assert(cb != NULL, "must be");
+    return cb;
+  } else {
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    slot = -1;
+    return cb;
+  }
+}
+
+#endif
--- a/src/hotspot/share/runtime/continuation.cpp	Thu Nov 29 12:48:23 2018 +0000
+++ b/src/hotspot/share/runtime/continuation.cpp	Fri Nov 30 14:43:10 2018 +0100
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "code/codeCache.inline.hpp"
 #include "code/compiledMethod.inline.hpp"
 #include "code/scopeDesc.hpp"
 #include "code/vmreg.inline.hpp"
@@ -172,9 +173,15 @@
 
 class ContinuationCodeBlobLookup {
 public:
+  enum { has_oopmap_lookup = true };
+
   static CodeBlob* find_blob(address pc) {
     return CodeCache::find_blob_fast(pc);
   }
+
+  static CodeBlob* find_blob_and_oopmap(address pc, int& slot) {
+    return CodeCache::find_blob_and_oopmap(pc, slot);
+  }
 };
 
 class ContMirror;
@@ -727,17 +734,14 @@
 }
 
 void ContMirror::read() {
-  log_trace(jvmcont)("Reading continuation object:");
 
   _entrySP = java_lang_Continuation::entrySP(_cont);
   _entryFP = java_lang_Continuation::entryFP(_cont);
   _entryPC = java_lang_Continuation::entryPC(_cont);
-  log_trace(jvmcont)("\tentrySP: " INTPTR_FORMAT " entryFP: " INTPTR_FORMAT " entryPC: " INTPTR_FORMAT, p2i(_entrySP), p2i(_entryFP), p2i(_entryPC));
 
   _sp = java_lang_Continuation::sp(_cont);
   _fp = java_lang_Continuation::fp(_cont);
   _pc = (address)java_lang_Continuation::pc(_cont);
-  log_trace(jvmcont)("\tsp: %d fp: %ld 0x%lx pc: " INTPTR_FORMAT, _sp, _fp, _fp, p2i(_pc));
 
   _stack = java_lang_Continuation::stack(_cont);
   if (_stack != NULL) {
@@ -748,51 +752,58 @@
     _hstack = NULL;
   }
   _max_size = java_lang_Continuation::maxSize(_cont);
-  log_trace(jvmcont)("\tstack: " INTPTR_FORMAT " hstack: " INTPTR_FORMAT ", stack_length: %d max_size: " SIZE_FORMAT, p2i((oopDesc*)_stack), p2i(_hstack), _stack_length, _max_size);
 
   _ref_stack = java_lang_Continuation::refStack(_cont);
   _ref_sp = java_lang_Continuation::refSP(_cont);
-  log_trace(jvmcont)("\tref_stack: " INTPTR_FORMAT " ref_sp: %d", p2i((oopDesc*)_ref_stack), _ref_sp);
 
   _flags = java_lang_Continuation::flags(_cont);
-  log_trace(jvmcont)("\tflags: %d", _flags);
 
   _num_frames = java_lang_Continuation::numFrames(_cont);
-  log_trace(jvmcont)("\tnum_frames: %d", _num_frames);
 
   _num_interpreted_frames = java_lang_Continuation::numInterpretedFrames(_cont);
-  log_trace(jvmcont)("\tnum_interpreted_frames: %d", _num_interpreted_frames);
+
+  if (log_is_enabled(Trace, jvmcont)) {
+    log_trace(jvmcont)("Reading continuation object:");
+    log_trace(jvmcont)("\tentrySP: " INTPTR_FORMAT " entryFP: " INTPTR_FORMAT " entryPC: " INTPTR_FORMAT, p2i(_entrySP), p2i(_entryFP), p2i(_entryPC));
+    log_trace(jvmcont)("\tsp: %d fp: %ld 0x%lx pc: " INTPTR_FORMAT, _sp, _fp, _fp, p2i(_pc));
+    log_trace(jvmcont)("\tstack: " INTPTR_FORMAT " hstack: " INTPTR_FORMAT ", stack_length: %d max_size: " SIZE_FORMAT, p2i((oopDesc*)_stack), p2i(_hstack), _stack_length, _max_size);
+    log_trace(jvmcont)("\tref_stack: " INTPTR_FORMAT " ref_sp: %d", p2i((oopDesc*)_ref_stack), _ref_sp);
+    log_trace(jvmcont)("\tflags: %d", _flags);
+    log_trace(jvmcont)("\tnum_frames: %d", _num_frames);
+    log_trace(jvmcont)("\tnum_interpreted_frames: %d", _num_interpreted_frames);
+  }
 }
 
 void ContMirror::write() {
-  log_trace(jvmcont)("Writing continuation object:");
-
-  log_trace(jvmcont)("\tsp: %d fp: %ld 0x%lx pc: " INTPTR_FORMAT, _sp, _fp, _fp, p2i(_pc));
+  if (log_is_enabled(Trace, jvmcont)) {
+    log_trace(jvmcont)("Writing continuation object:");
+    log_trace(jvmcont)("\tsp: %d fp: %ld 0x%lx pc: " INTPTR_FORMAT, _sp, _fp, _fp, p2i(_pc));
+    log_trace(jvmcont)("\tentrySP: " INTPTR_FORMAT " entryFP: " INTPTR_FORMAT " entryPC: " INTPTR_FORMAT, p2i(_entrySP), p2i(_entryFP), p2i(_entryPC));
+    log_trace(jvmcont)("\tmax_size: " SIZE_FORMAT, _max_size);
+    log_trace(jvmcont)("\tref_sp: %d", _ref_sp);
+    log_trace(jvmcont)("\tflags: %d", _flags);
+    log_trace(jvmcont)("\tnum_frames: %d", _num_frames);
+    log_trace(jvmcont)("\tnum_interpreted_frames: %d", _num_interpreted_frames);
+    log_trace(jvmcont)("\tend write");
+  }
+
   java_lang_Continuation::set_sp(_cont, _sp);
   java_lang_Continuation::set_fp(_cont, _fp);
   java_lang_Continuation::set_pc(_cont, _pc);
 
-  log_trace(jvmcont)("\tentrySP: " INTPTR_FORMAT " entryFP: " INTPTR_FORMAT " entryPC: " INTPTR_FORMAT, p2i(_entrySP), p2i(_entryFP), p2i(_entryPC));
   java_lang_Continuation::set_entrySP(_cont, _entrySP);
   java_lang_Continuation::set_entryFP(_cont, _entryFP);
   java_lang_Continuation::set_entryPC(_cont, _entryPC);
 
-  log_trace(jvmcont)("\tmax_size: " SIZE_FORMAT, _max_size);
   java_lang_Continuation::set_maxSize(_cont, (jint)_max_size);
 
-  log_trace(jvmcont)("\tref_sp: %d", _ref_sp);
   java_lang_Continuation::set_refSP(_cont, _ref_sp);
 
   java_lang_Continuation::set_flags(_cont, _flags);
-  log_trace(jvmcont)("\tflags: %d", _flags);
 
   java_lang_Continuation::set_numFrames(_cont, _num_frames);
-  log_trace(jvmcont)("\tnum_frames: %d", _num_frames);
 
   java_lang_Continuation::set_numInterpretedFrames(_cont, _num_interpreted_frames);
-  log_trace(jvmcont)("\tnum_interpreted_frames: %d", _num_interpreted_frames);
-
-  log_trace(jvmcont)("\tend write");
 }
 
 bool ContMirror::is_empty() {
@@ -816,8 +827,11 @@
     set_fp(0);
     set_pc(NULL);
   }
-  log_trace(jvmcont)("set_last_frame cont sp: %d fp: 0x%lx pc: " INTPTR_FORMAT " interpreted: %d flag: %d", sp(), fp(), p2i(pc()), f.is_interpreted_frame(), is_flag(FLAG_LAST_FRAME_INTERPRETED));
-  if (log_is_enabled(Trace, jvmcont)) f.print_on(*this, tty);
+
+  if (log_is_enabled(Trace, jvmcont)) {
+    log_trace(jvmcont)("set_last_frame cont sp: %d fp: 0x%lx pc: " INTPTR_FORMAT " interpreted: %d flag: %d", sp(), fp(), p2i(pc()), f.is_interpreted_frame(), is_flag(FLAG_LAST_FRAME_INTERPRETED));
+    f.print_on(*this, tty);
+  }
 }
 
 inline int ContMirror::stack_index(void* p) const {
@@ -843,7 +857,8 @@
   //assert (write_stack_index(to) == _wsp + to_index(METADATA_SIZE), "to: %d wsp: %d", write_stack_index(to), _wsp);
 
   if (Continuation::PERFTEST_LEVEL >= 25) {
-    Copy::conjoint_memory_atomic(from, to, size); // Copy::disjoint_words((HeapWord*)from, (HeapWord*)to, size/wordSize); // 
+    memcpy(to, from, size);
+    //Copy::conjoint_memory_atomic(from, to, size); // Copy::disjoint_words((HeapWord*)from, (HeapWord*)to, size/wordSize); // 
   }
 
   _e_size += size;
@@ -857,7 +872,8 @@
   assert (stack_index(from) >= 0, "");
   assert (to_index(stack(), (address)from + size) <= stack_length(), "");
 
-  Copy::conjoint_memory_atomic(from, to, size);
+  memcpy(to, from, size);
+  //Copy::conjoint_memory_atomic(from, to, size);
 
   _e_size += size;
 }
@@ -1587,9 +1603,10 @@
     sender_pc = cont.entryPC();
   }
 
-  CodeBlob* sender_cb = ContinuationCodeBlobLookup::find_blob(sender_pc);
+  int slot = 0;
+  CodeBlob* sender_cb = ContinuationCodeBlobLookup::find_blob_and_oopmap(sender_pc, slot);
   return sender_cb != NULL 
-   ? frame(sender_sp, sender_sp, *link_addr, sender_pc, sender_cb)
+   ? frame(sender_sp, sender_sp, *link_addr, sender_pc, sender_cb, slot == -1 ? NULL : sender_cb->oop_map_for_slot(slot, sender_pc))
    : frame(sender_sp, sender_sp, *link_addr, sender_pc);
 }
 
@@ -1701,7 +1718,6 @@
   int _fp_index;
 
   bool _is_last;
-
   bool is_last()  { return _is_last;  } // this is only true after returning from the recursive call
 
 public:
@@ -2033,28 +2049,13 @@
     return result;
   }
 
-  bool cmp(int* a, int* b, int size) {
-    bool result = true;
-    for (int i = 0; i < size; ++i) {
-      if (a[i] != b[i]) {
-        tty->print_cr("%d: %d %d", i, a[i], b[i]);
-        result = false;
-      }
-    }
-    return result;
-  }
-
-  void commit() {
+  void finish(bool empty, frame& f) {
+    hframe orig_top_frame = _mirror.last_frame(); // must be done before committing the changes
+
     assert (_wsp <= _mirror.sp() - to_index(METADATA_SIZE), "wsp: %d sp - to_index(METADATA_SIZE): %d", _wsp, _mirror.sp() - to_index(METADATA_SIZE));
     assert (_wsp == _top.sp() - to_index(METADATA_SIZE), "wsp: %d top sp - to_index(METADATA_SIZE): %d", _wsp, _top.sp() - to_index(METADATA_SIZE));
     _mirror.set_last_frame(_top);
     _mirror.set_refSP(_wref_sp);
-  }
-
-  void finish(bool empty, frame& f) {
-    hframe orig_top_frame = _mirror.last_frame(); // must be done before committing the changes
-
-    commit();
 
     f = entry_frame();
 
@@ -2075,19 +2076,19 @@
       assert (_bottom.sender(_mirror).is_empty(), "");
     } else {
       _bottom.patch_callee(_mirror, orig_top_frame);
-
       assert (_bottom.sender(_mirror) == orig_top_frame, "");
     }
 
-    log_trace(jvmcont)("last h-frame:");
-    if (log_is_enabled(Trace, jvmcont)) _bottom.print(_mirror);
-
-    log_trace(jvmcont)("top_hframe after (freeze):");
-    if (log_is_enabled(Trace, jvmcont)) _mirror.last_frame().print_on(_mirror, tty);
-
-    DEBUG_ONLY(address ret_pc =  return_pc(f, f.is_interpreted_frame());)
-
-    // assert (strcmp(method_name(new_top.method(_mirror)), YIELD_SIG) == 0, "name: %s", method_name(new_top.method(_mirror)));  // not true if yield is not @DontInline
+    if (log_is_enabled(Trace, jvmcont)) {
+      log_trace(jvmcont)("last h-frame:");
+      _bottom.print(_mirror);
+    }
+
+    if (log_is_enabled(Trace, jvmcont)) {
+      log_trace(jvmcont)("top_hframe after (freeze):");
+      _mirror.last_frame().print_on(_mirror, tty);
+    }
+
     assert (_mirror.is_flag(FLAG_LAST_FRAME_INTERPRETED) == _mirror.last_frame().is_interpreted_frame(), "flag: %d is_interpreted: %d", _mirror.is_flag(FLAG_LAST_FRAME_INTERPRETED), _mirror.last_frame().is_interpreted_frame());
   }
 };
@@ -2102,16 +2103,18 @@
   ContMirror cont(thread, oopCont);
   cont.read();
 
-  LogStreamHandle(Trace, jvmcont) st;
-
-  DEBUG_ONLY(log_debug(jvmcont)("Freeze ### #" INTPTR_FORMAT, cont.hash()));
+#ifdef ASSERT
+  log_debug(jvmcont)("Freeze ### #" INTPTR_FORMAT, cont.hash());
   log_trace(jvmcont)("Freeze 0000 sp: " INTPTR_FORMAT " fp: " INTPTR_FORMAT " pc: " INTPTR_FORMAT, p2i(f.sp()), p2i(f.fp()), p2i(f.pc()));
   log_trace(jvmcont)("Freeze 1111 sp: %d fp: 0x%lx pc: " INTPTR_FORMAT, cont.sp(), cont.fp(), p2i(cont.pc()));
+#endif
 
   intptr_t* bottom = cont.entrySP(); // (bottom is highest address; stacks grow down)
   intptr_t* top = f.sp();
 
+#ifdef ASSERT
   log_trace(jvmcont)("QQQ AAAAA bottom: " INTPTR_FORMAT " top: " INTPTR_FORMAT " size: " SIZE_FORMAT, p2i(bottom), p2i(top), pointer_delta(bottom, top, sizeof(address)));
+#endif
 
   if (Continuation::PERFTEST_LEVEL <= 13) return freeze_ok;
 
@@ -2126,7 +2129,7 @@
   if (Continuation::PERFTEST_LEVEL <= 15) return freeze_ok;
 
   fc.finish(empty, f);
-  
+
   cont.write();
 
   // notify JVMTI
@@ -2170,7 +2173,6 @@
 
   log_debug(jvmcont)("~~~~~~~~~ freeze");
   log_trace(jvmcont)("fi->sp: " INTPTR_FORMAT " fi->fp: " INTPTR_FORMAT " fi->pc: " INTPTR_FORMAT, p2i(fi->sp), p2i(fi->fp), p2i(fi->pc));
-  ContinuationCodeBlobLookup lookup;
 
   // set_anchor(thread, fi); // DEBUG
   print_frames(thread);
@@ -2191,6 +2193,12 @@
 
   RegisterMap map(thread, false, false, false);
   map.set_include_argument_oops(false);
+
+  NativePostCallNop* nop = nativePostCallNop_at(fi->pc);
+  if (nop == NULL) {
+    log_info(jvmcont)("no nop at freeze entry");
+  }
+
   // Note: if the doYield stub does not have its own frame, we may need to consider deopt here, especially if yield is inlinable
   frame f = thread->last_frame(); // this is the doYield stub frame. last_frame is set up by the call_VM infrastructure // <---- CodeCache::find_blob is expensive
   // f.print_on(tty);
--- a/src/hotspot/share/runtime/frame.cpp	Thu Nov 29 12:48:23 2018 +0000
+++ b/src/hotspot/share/runtime/frame.cpp	Fri Nov 30 14:43:10 2018 +0100
@@ -192,10 +192,6 @@
 bool frame::is_ignored_frame() const {
   return false;  // FIXME: some LambdaForm frames should be ignored
 }
-bool frame::is_deoptimized_frame() const {
-  assert(_deopt_state != unknown, "not answerable");
-  return _deopt_state == is_deoptimized;
-}
 
 bool frame::is_native_frame() const {
   return (_cb != NULL &&
--- a/src/hotspot/share/runtime/frame.inline.hpp	Thu Nov 29 12:48:23 2018 +0000
+++ b/src/hotspot/share/runtime/frame.inline.hpp	Fri Nov 30 14:43:10 2018 +0100
@@ -46,6 +46,11 @@
   return StubRoutines::returns_to_call_stub(pc());
 }
 
+inline bool frame::is_deoptimized_frame() const {
+  assert(_deopt_state != unknown, "not answerable");
+  return _deopt_state == is_deoptimized;
+}
+
 inline bool frame::is_stub_frame() const {
   return StubRoutines::is_stub_code(pc()) || (_cb != NULL && _cb->is_adapter_blob());
 }