1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef CPU_X86_CONTINUATION_X86_INLINE_HPP
  26 #define CPU_X86_CONTINUATION_X86_INLINE_HPP
  27 
  28 #include "compiler/oopMapStubGenerator.hpp"
  29 #include "runtime/frame.hpp"
  30 #include "runtime/frame.inline.hpp"
  31 
  32 template<bool indirect>
  33 static void set_anchor(JavaThread* thread, const FrameInfo* fi) {
  34   JavaFrameAnchor* anchor = thread->frame_anchor();
  35   anchor->set_last_Java_sp((intptr_t*)fi->sp);
  36   anchor->set_last_Java_fp(indirect ? *(intptr_t**)fi->fp : (intptr_t*)fi->fp); // there is an indirection in fi->fp in the FrameInfo created by Freeze::setup_jump
  37   anchor->set_last_Java_pc(fi->pc);
  38 
  39   assert (thread->has_last_Java_frame(), "");
  40   assert(thread->last_frame().cb() != NULL, "");
  41   log_develop_trace(jvmcont)("set_anchor:");
  42   print_vframe(thread->last_frame());
  43 }
  44 
  45 // unused
  46 // static void set_anchor(JavaThread* thread, const frame& f) {
  47 //   JavaFrameAnchor* anchor = thread->frame_anchor();
  48 //   anchor->set_last_Java_sp(f.unextended_sp());
  49 //   anchor->set_last_Java_fp(f.fp());
  50 //   anchor->set_last_Java_pc(f.pc());
  51 
  52 //   assert (thread->has_last_Java_frame(), "");
  53 //   assert(thread->last_frame().cb() != NULL, "");
  54 //   log_develop_trace(jvmcont)("set_anchor:");
  55 //   print_vframe(thread->last_frame());
  56 // }
  57 
  58 #ifdef CONT_DOUBLE_NOP
  59 
  60 template<typename FrameT>
  61 __COLD NOINLINE static CachedCompiledMetadata patch_nop(NativePostCallNop* nop, const FrameT& f) {
  62   f.get_cb();
  63   f.oop_map();
  64   assert(f.cb() != NULL && f.cb()->is_compiled() && f.oop_map() != NULL, "");
  65   int fsize   = Compiled::size(f);
  66   int oops    = Compiled::num_oops(f);
  67   int argsize = Compiled::stack_argsize(f);
  68 
  69   CachedCompiledMetadata md(fsize, oops, argsize);
  70   if (!md.empty() && !f.cb()->as_compiled_method()->has_monitors()) {
  71     nop->patch(md.int1(), 1); 
  72     assert(nop->is_mode2(), "");
  73   } else {
  74     // TODO R prevent repeated attempts to patch ???
  75   }
  76   return md;
  77 }
  78 
  79 template<typename FrameT>
  80 __COLD NOINLINE void ContinuationHelper::patch_freeze_stub(const FrameT& f, address freeze_stub) {
  81   assert(f.cb() != NULL && f.cb()->is_compiled() && f.oop_map() != NULL, "");
  82   NativePostCallNop* nop = nativePostCallNop_unsafe_at(f.pc());
  83   if (freeze_stub != NULL && nop->is_mode2()) {
  84     intptr_t ptr = nop->int2_data();
  85     if (ptr == 1) {
  86       nop->patch_int2(OopMapStubGenerator::stub_to_offset((address)freeze_stub));
  87     }
  88   }
  89 }
  90 
  91 inline CachedCompiledMetadata ContinuationHelper::cached_metadata(address pc) {
  92   NativePostCallNop* nop = nativePostCallNop_unsafe_at(pc);
  93   if (LIKELY(nop->is_mode2())) {
  94     return CachedCompiledMetadata(nop->int1_data());
  95   } else {
  96     return CachedCompiledMetadata(0);
  97   }
  98 }
  99 
 100 template<op_mode mode, typename FrameT>
 101 inline CachedCompiledMetadata ContinuationHelper::cached_metadata(const FrameT& f) {
 102   if (mode == mode_preempt) return CachedCompiledMetadata(0);
 103 
 104   NativePostCallNop* nop = nativePostCallNop_unsafe_at(f.pc());
 105   assert (!nop->is_mode2() || slow_get_cb(f)->is_compiled(), "");
 106   if (LIKELY(nop->is_mode2())) {
 107     // tty->print_cr(">>> PATCHED 33 -- %d", !md.empty());
 108     return CachedCompiledMetadata(nop->int1_data());
 109   } else {
 110     return patch_nop(nop, f);
 111   }
 112 }
 113 #endif
 114 
 115 template<op_mode mode, typename FrameT>
 116 FreezeFnT ContinuationHelper::freeze_stub(const FrameT& f) {
 117   // static int __counter = 0;
 118 #ifdef CONT_DOUBLE_NOP
 119   if (mode != mode_preempt) {
 120     NativePostCallNop* nop = nativePostCallNop_unsafe_at(f.pc());
 121     uint32_t ptr = nop->int2_data();
 122     if (LIKELY(ptr > (uint32_t)1)) {
 123       return (FreezeFnT)OopMapStubGenerator::offset_to_stub(ptr);
 124     }
 125     assert (ptr == 0 || ptr == 1, "");
 126     if (f.cb() == NULL) return NULL; // f.get_cb();
 127 
 128     // __counter++;
 129     // if (__counter % 100 == 0) tty->print_cr(">>>> freeze_stub %d %d", ptr, __counter);
 130     // if (mode == mode_fast) { 
 131     //   tty->print_cr(">>>> freeze_stub"); f.print_on(tty); tty->print_cr("<<<< freeze_stub"); 
 132     //   assert(false, "");
 133     // }
 134   }
 135 #endif
 136 
 137   FreezeFnT f_fn = (FreezeFnT)f.oop_map()->freeze_stub();
 138   if ((void*)f_fn == (void*)f.oop_map()) {
 139     f_fn = NULL; // need CompressedOops for now ????
 140   }
 141 #ifdef CONT_DOUBLE_NOP
 142   // we currently patch explicitly, based on ConfigT etc.
 143   // if (LIKELY(nop != NULL && f_fn != NULL && !nop->is_mode2())) {
 144   //   nop->patch_int2(OopMapStubGenerator::stub_to_offset((address)f_fn));
 145   // }
 146 #endif
 147   return f_fn;
 148 }
 149 
 150 template<op_mode mode, typename FrameT>
 151 ThawFnT ContinuationHelper::thaw_stub(const FrameT& f) {
 152 #ifdef CONT_DOUBLE_NOP
 153   if (mode != mode_preempt) {
 154     NativePostCallNop* nop = nativePostCallNop_unsafe_at(f.pc());
 155     uint32_t ptr = nop->int2_data();
 156     if (LIKELY(ptr > (uint32_t)1)) {
 157       address freeze_stub = OopMapStubGenerator::offset_to_stub(ptr);
 158       address thaw_stub = OopMapStubGenerator::thaw_stub(freeze_stub);
 159       if (f.cb() == NULL) { // TODO PERF: this is only necessary for new_frame called from thaw, because we need cb for deopt info
 160         CodeBlob* cb = OopMapStubGenerator::code_blob(thaw_stub);
 161         assert (cb == slow_get_cb(f), "");
 162         const_cast<FrameT&>(f).set_cb(cb);
 163       }
 164       assert (f.cb() != NULL, "");
 165       return (ThawFnT)thaw_stub;
 166     }
 167     assert (ptr == 0 || ptr == 1, "");
 168     if (f.cb() == NULL) return NULL; // f.get_cb();
 169   }
 170 #endif
 171   ThawFnT t_fn = (ThawFnT)f.oop_map()->thaw_stub();
 172   if ((void*)t_fn == (void*)f.oop_map()) {
 173     t_fn = NULL; // need CompressedOops for now ????
 174   }
 175   return t_fn;
 176 }
 177 
 178 inline bool hframe::operator==(const hframe& other) const {
 179     return  HFrameBase::operator==(other) && _fp == other._fp;
 180 }
 181 
 182 intptr_t* hframe::interpreted_link_address(intptr_t fp, const ContMirror& cont) {
 183   return cont.stack_address((int)fp + (frame::link_offset << LogElemsPerWord));
 184 }
 185 
 186 template<typename FKind>
 187 inline address* hframe::return_pc_address() const {
 188   assert (FKind::interpreted, "");
 189   return (address*)&interpreted_link_address()[frame::return_addr_offset];
 190 }
 191 
 192 const CodeBlob* hframe::get_cb() const {
 193   if (_cb_imd == NULL) {
 194     int slot;
 195     _cb_imd = CodeCache::find_blob_and_oopmap(_pc, slot);
 196     if (_oop_map == NULL && slot >= 0) {
 197       _oop_map = ((CodeBlob*)_cb_imd)->oop_map_for_slot(slot, _pc);
 198     }
 199   }
 200   return (CodeBlob*)_cb_imd;
 201 }
 202 
 203 const ImmutableOopMap* hframe::get_oop_map() const {
 204   if (_cb_imd == NULL) return NULL;
 205   if (((CodeBlob*)_cb_imd)->oop_maps() != NULL) {
 206     NativePostCallNop* nop = nativePostCallNop_at(_pc);
 207     if (nop != NULL &&
 208 #ifdef CONT_DOUBLE_NOP
 209       !nop->is_mode2() &&
 210 #endif
 211       nop->displacement() != 0
 212     ) {
 213       int slot = ((nop->displacement() >> 24) & 0xff);
 214       // tty->print_cr("hframe::get_oop_map slot: %d", slot);
 215       return ((CodeBlob*)_cb_imd)->oop_map_for_slot(slot, _pc);
 216     }
 217     const ImmutableOopMap* oop_map = OopMapSet::find_map(cb(), pc());
 218     return oop_map;
 219   }
 220   return NULL;
 221 }
 222 
 223 intptr_t* hframe::interpreter_frame_metadata_at(int offset) const {
 224   return interpreted_link_address() + offset;
 225 }
 226 
 227 inline void hframe::patch_interpreter_metadata_offset(int offset, intptr_t value) {
 228   *interpreter_frame_metadata_at(offset) = value;
 229 }
 230 
 231 inline void hframe::patch_interpreted_link(intptr_t value) {
 232   intptr_t* la = interpreted_link_address();
 233   log_develop_trace(jvmcont)("patch_interpreted_link patching link at %ld to %ld", _fp, value);
 234   *la = value;
 235 }
 236 
 237 inline void hframe::patch_interpreted_link_relative(intptr_t fp) {
 238   intptr_t* la = interpreted_link_address();
 239   intptr_t new_value = fp - _fp;
 240   log_develop_trace(jvmcont)("patch_interpreted_link_relative patching link at %ld to %ld", _fp, new_value);
 241   // assert (new_value == cont.stack_index(fp) - link_index(cont), "res: %d index delta: %d", new_value, cont.stack_index(fp) - link_index(cont));
 242   *la = new_value;
 243 }
 244 
 245 inline void hframe::patch_sender_sp_relative(intptr_t* value) {
 246   assert (_is_interpreted, "");
 247   intptr_t* fp_address = interpreted_link_address();
 248   intptr_t* la = &fp_address[frame::interpreter_frame_sender_sp_offset];
 249   *la = ContMirror::to_index((address)value - (address)fp_address); // all relative indices are relative to fp
 250 }
 251 
 252 void hframe::interpreted_frame_oop_map(InterpreterOopMap* mask) const {
 253   assert (_is_interpreted, "");
 254   Method* m = method<Interpreted>();
 255   int bci = m->bci_from(*(address*)interpreter_frame_metadata_at(frame::interpreter_frame_bcp_offset));
 256   m->mask_for(bci, mask);
 257 }
 258 
 259 int hframe::interpreted_frame_num_monitors() const {
 260   assert (_is_interpreted, "");
 261   return (frame::interpreter_frame_monitor_block_bottom_offset - *(int*)interpreter_frame_metadata_at(frame::interpreter_frame_monitor_block_top_offset)/elemsPerWord)/BasicObjectLock::size();
 262 }
 263 
 264 #ifdef ASSERT
 265   int hframe::interpreted_frame_top_index() const {
 266     InterpreterOopMap mask;
 267     interpreted_frame_oop_map(&mask);
 268     int top_offset = *(int*)interpreter_frame_metadata_at(frame::interpreter_frame_initial_sp_offset);
 269     int expression_stack_size = mask.expression_stack_size();
 270     int index = _fp + top_offset - (expression_stack_size << LogElemsPerWord);
 271     return index;
 272   }
 273 #endif
 274 
 275 template<typename FKind>
 276 int hframe::frame_bottom_index() const {
 277   assert (FKind::is_instance(*this), "");
 278   if (FKind::interpreted) {
 279     int bottom_offset = *(int*)interpreter_frame_metadata_at(frame::interpreter_frame_locals_offset) + (1*elemsPerWord); // exclusive, so we add 1 word
 280     return _fp + bottom_offset;
 281   } else {
 282     return _sp + (cb()->frame_size() << LogElemsPerWord);
 283   }
 284 }
 285 
 286 address hframe::interpreter_frame_bcp() const {
 287   address bcp;
 288   bcp = (address)*interpreter_frame_metadata_at(frame::interpreter_frame_bcp_offset);
 289   bcp = method<Interpreted>()->bcp_from(bcp);
 290   return bcp;
 291 }
 292 
 293 intptr_t* hframe::interpreter_frame_local_at(int index) const {
 294   intptr_t* fp = interpreted_link_address();
 295   const int n = Interpreter::local_offset_in_bytes(index)/wordSize;
 296   intptr_t* locals = (intptr_t*)((address)fp + ContMirror::to_bytes(*(intptr_t*)(fp + frame::interpreter_frame_locals_offset)));
 297   intptr_t* loc = &(locals[n]); // derelativize
 298 
 299   // tty->print_cr("interpreter_frame_local_at: %d (%p, %ld, %ld) fp: %ld sp: %d, n: %d fp: %p", index, loc, loc - cont.stack_address(_sp), loc - fp, _fp, _sp, n, fp);  
 300   return loc;
 301 }
 302 
 303 intptr_t* hframe::interpreter_frame_expression_stack_at(int offset) const {
 304   intptr_t* fp = interpreted_link_address();
 305   intptr_t* monitor_end = (intptr_t*)((address)fp + ContMirror::to_bytes(*(intptr_t*)(fp + frame::interpreter_frame_monitor_block_top_offset))); // derelativize
 306   intptr_t* expression_stack = monitor_end-1;
 307 
 308   const int i = offset * frame::interpreter_frame_expression_stack_direction();
 309   const int n = i * Interpreter::stackElementWords;
 310   return &(expression_stack[n]);
 311 }
 312 
 313 inline int hframe::callee_link_index() const {
 314   return _sp - (frame::sender_sp_offset << LogElemsPerWord);
 315 }
 316 
 317 inline void hframe::patch_callee_link(intptr_t value, const ContMirror& cont) const {
 318   *cont.stack_address(callee_link_index()) = value;
 319 }
 320 
 321 inline void hframe::patch_callee_link_relative(intptr_t fp, const ContMirror& cont) const {
 322   int index = callee_link_index();
 323   intptr_t* la = cont.stack_address(index);
 324   intptr_t new_value = fp - index;
 325   // assert (new_value == cont.stack_index(fp) - link_index(cont), "res: %d index delta: %d", new_value, cont.stack_index(fp) - link_index(cont));
 326   *la = new_value;
 327 }
 328 
 329 inline int hframe::pc_index() const {
 330   return _sp - (frame::return_addr_offset << LogElemsPerWord);
 331 }
 332 
 333 inline address hframe::real_pc(const ContMirror& cont) const {
 334   return *(address*)cont.stack_address(pc_index());
 335 }
 336 
 337 template<typename FKind, op_mode mode>
 338 hframe hframe::sender(const ContMirror& cont, int num_oops) const {
 339   // tty->print_cr(">> sender of:");
 340   // print_on(cont, tty);
 341 
 342   int sender_ref_sp = _ref_sp + num_oops;
 343 
 344 #ifdef CONT_DOUBLE_NOP
 345   CachedCompiledMetadata md;
 346   if (mode == mode_fast && LIKELY(!(md = ContinuationHelper::cached_metadata<mode>(*this)).empty())) {
 347     int sender_sp = _sp + (md.size_words() << LogElemsPerWord);
 348     assert (sender_sp > _sp, "");
 349     if (sender_sp >= cont.stack_length())
 350       return hframe();
 351 
 352     int link_index = sender_sp - (frame::sender_sp_offset << LogElemsPerWord);
 353     intptr_t sender_fp = *cont.stack_address(link_index);
 354     address sender_pc  = (address)*cont.stack_address(link_index + (frame::return_addr_offset << LogElemsPerWord));
 355     assert (mode != mode_fast || !Interpreter::contains(sender_pc), "");
 356     return hframe(sender_sp, sender_ref_sp, sender_fp, sender_pc, NULL, false);
 357   }
 358 #endif
 359 
 360   int sender_sp = frame_bottom_index<FKind>();
 361   assert (sender_sp > _sp, "");
 362 
 363   if (sender_sp >= cont.stack_length())
 364     return hframe(sender_sp, sender_ref_sp, 0, NULL, NULL, false); // hframe()
 365 
 366   int link_index = FKind::interpreted ? _fp
 367                                       : sender_sp - (frame::sender_sp_offset << LogElemsPerWord);
 368 
 369   intptr_t sender_fp = *cont.stack_address(link_index);
 370   address sender_pc  = FKind::interpreted ? return_pc<Interpreted>()
 371                                           : (address)*cont.stack_address(sender_sp - (frame::return_addr_offset << LogElemsPerWord));
 372 
 373   assert (mode != mode_fast || !Interpreter::contains(sender_pc), "");
 374   bool is_sender_interpreted = mode == mode_fast ? false : Interpreter::contains(sender_pc); 
 375 
 376   void* sender_md;
 377   if (mode != mode_fast && is_sender_interpreted) {
 378     sender_fp += link_index;
 379     sender_md = cont.stack_address(sender_fp + (frame::link_offset << LogElemsPerWord));
 380     sender_sp += FKind::interpreted ? 0 : compiled_frame_stack_argsize() >> LogBytesPerElement;
 381     // log_develop_trace(jvmcont)("real_fp: %d sender_fp: %ld", link_index, sender_fp);
 382   } else {
 383     sender_md = ContinuationCodeBlobLookup::find_blob(sender_pc);
 384     sender_pc = hframe::deopt_original_pc(cont, sender_pc, (CodeBlob*)sender_md, sender_sp); // TODO PERF: unnecessary in the long term solution of unrolling deopted frames on freeze
 385     // a stub can only appear as the topmost frame; all senders must be compiled/interpreted Java frames so we can call deopt_original_pc, which assumes a compiled Java frame
 386   }
 387   return hframe(sender_sp, sender_ref_sp, sender_fp, sender_pc, sender_md, is_sender_interpreted);
 388 }
 389 
 390 inline frame hframe::to_frame(ContMirror& cont, address pc, bool deopt) const {
 391   return frame(_sp, _ref_sp, _fp, pc,
 392               (!_is_interpreted && _cb_imd != NULL) ? cb() : (CodeBlob*)(_cb_imd = CodeCache::find_blob(_pc)),
 393               deopt);
 394 }
 395 
 396 void hframe::print_on(outputStream* st) const {
 397   if (is_empty()) {
 398     st->print_cr("\tempty");
 399   } else if (Interpreter::contains(pc())) { // in fast mode we cannot rely on _is_interpreted
 400     st->print_cr("\tInterpreted sp: %d fp: %ld pc: " INTPTR_FORMAT " ref_sp: %d (is_interpreted: %d) link address: " INTPTR_FORMAT, _sp, _fp, p2i(_pc), _ref_sp, _is_interpreted, p2i(interpreted_link_address()));
 401   } else {
 402     st->print_cr("\tCompiled sp: %d fp: 0x%lx pc: "  INTPTR_FORMAT " ref_sp: %d (is_interpreted: %d)", _sp, _fp, p2i(_pc), _ref_sp, _is_interpreted);
 403   }
 404 }
 405 
 406 void hframe::print_on(const ContMirror& cont, outputStream* st) const {
 407   print_on(st);
 408   if (is_empty())
 409     return;
 410 
 411   if (Interpreter::contains(pc())) { // in fast mode we cannot rely on _is_interpreted
 412     intptr_t* fp = cont.stack_address((int)_fp); // interpreted_link_address();
 413     Method** method_addr = (Method**)(fp + frame::interpreter_frame_method_offset);
 414     Method* method = *method_addr;
 415     st->print_cr("\tmethod: " INTPTR_FORMAT " (at " INTPTR_FORMAT ")", p2i(method), p2i(method_addr));
 416     st->print("\tmethod: "); method->print_short_name(st); st->cr();
 417     st->print_cr("\tlink: %ld", *(intptr_t*) fp);
 418     st->print_cr("\tissp: %ld",             *(intptr_t*) (fp + frame::interpreter_frame_sender_sp_offset));
 419     st->print_cr("\tlast_sp: %ld",          *(intptr_t*) (fp + frame::interpreter_frame_last_sp_offset));
 420     st->print_cr("\tinitial_sp: %ld",       *(intptr_t*) (fp + frame::interpreter_frame_initial_sp_offset));
 421     // st->print_cr("\tmon_block_top: %ld",    *(intptr_t*) (fp + frame::interpreter_frame_monitor_block_top_offset));
 422     // st->print_cr("\tmon_block_bottom: %ld", *(intptr_t*) (fp + frame::interpreter_frame_monitor_block_bottom_offset));
 423     st->print_cr("\tlocals: %ld",           *(intptr_t*) (fp + frame::interpreter_frame_locals_offset));
 424     st->print_cr("\tcache: " INTPTR_FORMAT, p2i(*(void**)(fp + frame::interpreter_frame_cache_offset)));
 425     st->print_cr("\tbcp: " INTPTR_FORMAT,   p2i(*(void**)(fp + frame::interpreter_frame_bcp_offset)));
 426     st->print_cr("\tbci: %d",               method->bci_from(*(address*)(fp + frame::interpreter_frame_bcp_offset)));
 427     st->print_cr("\tmirror: " INTPTR_FORMAT, p2i(*(void**)(fp + frame::interpreter_frame_mirror_offset)));
 428     // st->print("\tmirror: "); os::print_location(st, *(intptr_t*)(fp + frame::interpreter_frame_mirror_offset), true);
 429   } else {
 430     if (_sp > 0) st->print_cr("\treal_pc: " INTPTR_FORMAT, p2i(real_pc(cont)));
 431     st->print_cr("\tcb: " INTPTR_FORMAT, p2i(cb()));
 432     if (cb() != NULL) {
 433       st->print("\tcb: "); cb()->print_value_on(st); st->cr();
 434       st->print_cr("\tcb.frame_size: %d", cb()->frame_size());
 435     }
 436   }
 437   // if (link_address() != NULL) {
 438   //   st->print_cr("\tlink: 0x%lx %ld (at: " INTPTR_FORMAT ")", link(), link(), p2i(link_address()));
 439   //   st->print_cr("\treturn_pc: " INTPTR_FORMAT " (at " INTPTR_FORMAT ")", p2i(CHOOSE2(_is_interpreted, return_pc)), p2i(CHOOSE2(_is_interpreted, return_pc_address)));
 440   // } else {
 441   //   st->print_cr("\tlink address: NULL");
 442   // }
 443 }
 444 
 445 /////
 446 
 447 inline void ContMirror::set_last_frame_pd(const hframe& f) {
 448   set_fp(f.fp());
 449 }
 450 
 451 /*
 452  * Here mode_preempt makes the fewest assumptions
 453  */
 454 template<op_mode mode /* = mode_slow*/> // TODO: add default when switching to C++11+
 455 const hframe ContMirror::last_frame() {
 456   if (is_empty()) return hframe();
 457 
 458   assert (mode != mode_fast || !Interpreter::contains(_pc), "");
 459   assert (Interpreter::contains(_pc) == is_flag(FLAG_LAST_FRAME_INTERPRETED), "");
 460 
 461   if (mode == mode_fast || !is_flag(FLAG_LAST_FRAME_INTERPRETED)) {
 462     CodeBlob* cb;
 463   #ifdef CONT_DOUBLE_NOP
 464     if (mode != mode_preempt && LIKELY(!ContinuationHelper::cached_metadata(_pc).empty()))
 465       cb = NULL;
 466     else
 467   #endif
 468       cb = ContinuationCodeBlobLookup::find_blob(_pc);
 469 
 470     return hframe(_sp, _ref_sp, _fp, _pc, cb, false);
 471   } else {
 472     return hframe(_sp, _ref_sp, _fp, _pc, hframe::interpreted_link_address(_fp, *this), true);
 473   }
 474 }
 475 
 476 hframe ContMirror::from_frame(const frame& f) {
 477   void* md = f.is_interpreted_frame() ? (void*)hframe::interpreted_link_address((intptr_t)f.fp(), *this) : (void*)f.cb();
 478   return hframe(f.cont_sp(), f.cont_ref_sp(), (intptr_t)f.fp(), f.pc(), md, f.is_interpreted_frame());
 479 }
 480 
 481 ///////
 482 
 483 #ifdef ASSERT
 484 template<typename FKind>
 485 static intptr_t* slow_real_fp(const frame& f) {
 486   assert (FKind::is_instance(f), "");
 487   return FKind::interpreted ? f.fp() : f.unextended_sp() + slow_get_cb(f)->frame_size();
 488 }
 489 
 490 template<typename FKind> // TODO: maybe do the same CRTP trick with Interpreted and Compiled as with hframe
 491 static intptr_t** slow_link_address(const frame& f) {
 492   assert (FKind::is_instance(f), "");
 493   return FKind::interpreted
 494             ? (intptr_t**)(f.fp() + frame::link_offset)
 495             : (intptr_t**)(slow_real_fp<FKind>(f) - frame::sender_sp_offset);
 496 }
 497 
 498 template<typename FKind>
 499 static address* slow_return_pc_address(const frame& f) {
 500   return (address*)(slow_real_fp<FKind>(f) - 1);
 501 }
 502 #endif
 503 
 504 inline intptr_t** Frame::callee_link_address(const frame& f) {
 505   return (intptr_t**)(f.sp() - frame::sender_sp_offset);
 506 }
 507 
 508 static void patch_callee_link(const frame& f, intptr_t* fp) {
 509   *Frame::callee_link_address(f) = fp;
 510   log_trace(jvmcont)("patched link at " INTPTR_FORMAT ": " INTPTR_FORMAT, p2i(Frame::callee_link_address(f)), p2i(fp));
 511 }
 512 
 513 template <typename RegisterMapT>
 514 inline intptr_t** Frame::map_link_address(const RegisterMapT* map) {
 515   return (intptr_t**)map->location(rbp->as_VMReg());
 516 }
 517 
 518 static inline intptr_t* noninterpreted_real_fp(intptr_t* unextended_sp, int size_in_words) {
 519   return unextended_sp + size_in_words;
 520 }
 521 
 522 template<typename FKind>
 523 static inline intptr_t* real_fp(const frame& f) {
 524   assert (FKind::is_instance(f), "");
 525   assert (FKind::interpreted || f.cb() != NULL, "");
 526 
 527   return FKind::interpreted ? f.fp() : f.unextended_sp() + f.cb()->frame_size();
 528 }
 529 
 530 static inline intptr_t** noninterpreted_link_address(intptr_t* unextended_sp, int size_in_words) {
 531   return (intptr_t**)(noninterpreted_real_fp(unextended_sp, size_in_words) - frame::sender_sp_offset);
 532 }
 533 
 534 template<typename FKind> // TODO: maybe do the same CRTP trick with Interpreted and Compiled as with hframe
 535 static inline intptr_t** link_address(const frame& f) {
 536   assert (FKind::is_instance(f), "");
 537   return FKind::interpreted
 538             ? (intptr_t**)(f.fp() + frame::link_offset)
 539             : (intptr_t**)(real_fp<FKind>(f) - frame::sender_sp_offset);
 540 }
 541 
 542 template<typename FKind>
 543 static void patch_link(frame& f, intptr_t* fp) {
 544   assert (FKind::interpreted, "");
 545   *link_address<FKind>(f) = fp;
 546   log_trace(jvmcont)("patched link at " INTPTR_FORMAT ": " INTPTR_FORMAT, p2i(link_address<FKind>(f)), p2i(fp));
 547 }
 548 
 549 // static inline intptr_t** link_address_stub(const frame& f) {
 550 //   assert (!f.is_java_frame(), "");
 551 //   return (intptr_t**)(f.fp() - frame::sender_sp_offset);
 552 // }
 553 
 554 static inline intptr_t** link_address(const frame& f) {
 555   return f.is_interpreted_frame() ? link_address<Interpreted>(f) : link_address<NonInterpretedUnknown>(f);
 556 }
 557 
 558 inline address* Interpreted::return_pc_address(const frame& f) {
 559   return (address*)(f.fp() + frame::return_addr_offset);
 560 }
 561 
 562 void Interpreted::patch_sender_sp(frame& f, intptr_t* sp) {
 563   assert (f.is_interpreted_frame(), "");
 564   *(intptr_t**)(f.fp() + frame::interpreter_frame_sender_sp_offset) = sp;
 565   log_trace(jvmcont)("patched sender_sp: " INTPTR_FORMAT, p2i(sp));
 566 }
 567 
 568 inline address* Frame::return_pc_address(const frame& f) {
 569   return (address*)(f.real_fp() - 1);
 570 }
 571 
 572 // inline address* Frame::pc_address(const frame& f) {
 573 //   return (address*)(f.sp() - frame::return_addr_offset);
 574 // }
 575 
 576 inline address Frame::real_pc(const frame& f) {
 577   address* pc_addr = &(((address*) f.sp())[-1]);
 578   return *pc_addr;
 579 }
 580 
 581 inline void Frame::patch_pc(const frame& f, address pc) {
 582   address* pc_addr = &(((address*) f.sp())[-1]);
 583   *pc_addr = pc;
 584 }
 585 
 586 inline intptr_t* Interpreted::frame_top(const frame& f, InterpreterOopMap* mask) { // inclusive; this will be copied with the frame
 587   intptr_t* res = *(intptr_t**)f.addr_at(frame::interpreter_frame_initial_sp_offset) - expression_stack_size(f, mask);
 588   assert (res == (intptr_t*)f.interpreter_frame_monitor_end() - expression_stack_size(f, mask), "");
 589   assert (res >= f.unextended_sp(), "");
 590   return res;
 591   // Not true, but using unextended_sp might work
 592   // assert (res == f.unextended_sp(), "res: " INTPTR_FORMAT " unextended_sp: " INTPTR_FORMAT, p2i(res), p2i(f.unextended_sp() + 1));
 593 }
 594 
 595 inline intptr_t* Interpreted::frame_bottom(const frame& f) { // exclusive; this will not be copied with the frame
 596     return *(intptr_t**)f.addr_at(frame::interpreter_frame_locals_offset) + 1; // exclusive, so we add 1 word
 597 }
 598 
 599 
 600 /////////
 601 
 602 static inline intptr_t** callee_link_address(const frame& f) {
 603   return (intptr_t**)(f.sp() - frame::sender_sp_offset);
 604 }
 605 
 606 template<typename FKind, typename RegisterMapT>
 607 inline void ContinuationHelper::update_register_map(RegisterMapT* map, const frame& f) {
 608   frame::update_map_with_saved_link(map, link_address<FKind>(f));
 609 }
 610 
 611 template<typename RegisterMapT>
 612 inline void ContinuationHelper::update_register_map(RegisterMapT* map, intptr_t** link_address) {
 613   frame::update_map_with_saved_link(map, link_address);
 614 }
 615 
 616 template<typename RegisterMapT>
 617 inline void ContinuationHelper::update_register_map_with_callee(RegisterMapT* map, const frame& f) {
 618   frame::update_map_with_saved_link(map, callee_link_address(f));
 619 }
 620 
 621 void ContinuationHelper::update_register_map(RegisterMap* map, const hframe& caller, const ContMirror& cont) {
 622   // we save the link _index_ in the oop map; it is read and converted back in Continuation::reg_to_location
 623   int link_index = caller.callee_link_index();
 624   log_develop_trace(jvmcont)("ContinuationHelper::update_register_map: frame::update_map_with_saved_link: %d", link_index);
 625   intptr_t link_index0 = link_index;
 626   frame::update_map_with_saved_link(map, reinterpret_cast<intptr_t**>(link_index0));
 627 }
 628 
 629 void ContinuationHelper::update_register_map_from_last_vstack_frame(RegisterMap* map) {
 630   // we need to return the link address for the entry frame; it is saved in the bottom-most thawed frame
 631   intptr_t** fp = (intptr_t**)(map->last_vstack_fp());
 632   log_develop_trace(jvmcont)("ContinuationHelper::update_register_map_from_last_vstack_frame: frame::update_map_with_saved_link: " INTPTR_FORMAT, p2i(fp));
 633   frame::update_map_with_saved_link(map, fp);
 634 }
 635 
 636 inline frame ContinuationHelper::frame_with(frame& f, intptr_t* sp, address pc, intptr_t* fp) {
 637   return frame(sp, f.unextended_sp(), fp, pc, CodeCache::find_blob(pc));
 638 }
 639 
 640 inline void ContinuationHelper::set_last_vstack_frame(RegisterMap* map, const frame& hf) {
 641   log_develop_trace(jvmcont)("setting map->last_vstack_fp: " INTPTR_FORMAT, p2i(hf.real_fp()));
 642   map->set_last_vstack_fp(link_address(hf));
 643 }
 644 
 645 inline void ContinuationHelper::clear_last_vstack_frame(RegisterMap* map) {
 646   log_develop_trace(jvmcont)("clearing map->last_vstack_fp");
 647   map->set_last_vstack_fp(NULL);
 648 }
 649 
 650 template<typename FKind> // the callee's type
 651 inline void ContinuationHelper::to_frame_info_pd(const frame& f, const frame& callee, FrameInfo* fi) {
 652   // we have an indirection for fp, because the link at the entry frame may hold a sender's oop, and it can be relocated
 653   // at a safpoint on the VM->Java transition, so we point at an address where the GC would find it
 654   assert (callee_link_address(f) == slow_link_address<FKind>(callee), "");
 655   fi->fp = (intptr_t*)callee_link_address(f); // f.fp();
 656 }
 657 
 658 inline void ContinuationHelper::to_frame_info_pd(const frame& f, FrameInfo* fi) {
 659   fi->fp = f.fp();
 660 }
 661 
 662 template<bool indirect>
 663 inline frame ContinuationHelper::to_frame(FrameInfo* fi) {
 664   address pc = fi->pc;
 665   int slot;
 666   CodeBlob* cb = ContinuationCodeBlobLookup::find_blob_and_oopmap(pc, slot);
 667   return frame(fi->sp, fi->sp, 
 668     indirect ? *(intptr_t**)fi->fp : fi->fp, 
 669     pc, cb, slot == -1 ? NULL : cb->oop_map_for_slot(slot, pc));
 670 }
 671 
 672 // creates the yield stub frame faster than JavaThread::last_frame
 673 inline frame ContinuationHelper::last_frame(JavaThread* thread) {
 674   JavaFrameAnchor* anchor = thread->frame_anchor();
 675   assert (anchor->last_Java_sp() != NULL, "");
 676   assert (anchor->last_Java_pc() != NULL, "");
 677 
 678   assert (StubRoutines::cont_doYield_stub()->contains(anchor->last_Java_pc()), "must be");
 679   assert (StubRoutines::cont_doYield_stub()->oop_maps()->count() == 1, "must be");
 680 
 681   return frame(anchor->last_Java_sp(), anchor->last_Java_sp(), anchor->last_Java_fp(), anchor->last_Java_pc(), NULL, NULL, true);
 682   // return frame(anchor->last_Java_sp(), anchor->last_Java_sp(), anchor->last_Java_fp(), anchor->last_Java_pc(), 
 683   //   StubRoutines::cont_doYield_stub(), StubRoutines::cont_doYield_stub()->oop_map_for_slot(0, anchor->last_Java_pc()), true);
 684 }
 685 
 686 template<typename FKind, op_mode mode>
 687 static inline frame sender_for_compiled_frame(const frame& f) {
 688 #ifdef CONT_DOUBLE_NOP
 689   CachedCompiledMetadata md;
 690   // tty->print_cr(">>> sender fast: %d !FKind::stub: %d", fast, !FKind::stub);
 691   if (mode == mode_fast && !FKind::stub && LIKELY(!(md = ContinuationHelper::cached_metadata<mode>(f)).empty())) {
 692     intptr_t* sender_sp = f.unextended_sp() + md.size_words();
 693     intptr_t** link_addr = (intptr_t**)(sender_sp - frame::sender_sp_offset);
 694     address sender_pc = (address) *(sender_sp-1);
 695 
 696     assert(sender_sp != f.sp(), "must have changed");
 697     return frame(sender_sp, sender_sp, *link_addr, sender_pc, NULL, NULL, true); // no deopt check TODO PERF: use a faster constructor that doesn't write cb (shows up in profile)
 698   }
 699   // tty->print_cr(">>> slow sender1");
 700 #endif
 701 
 702   assert (mode == mode_preempt || !FKind::stub || StubRoutines::cont_doYield_stub()->contains(f.pc()), "must be");
 703   assert (mode == mode_preempt || !FKind::stub || slow_get_cb(f)->frame_size() == 5, "must be");
 704   intptr_t** link_addr = (mode != mode_preempt && FKind::stub) ? noninterpreted_link_address(f.unextended_sp(), 5) : link_address<FKind>(f);
 705 
 706   intptr_t* sender_sp = (intptr_t*)(link_addr + frame::sender_sp_offset); //  f.unextended_sp() + (fsize/wordSize); // 
 707   address sender_pc = (address) *(sender_sp-1);
 708   assert(sender_sp != f.sp(), "must have changed");
 709 
 710 #ifdef CONT_DOUBLE_NOP
 711   if (mode == mode_fast) {
 712     assert (!Interpreter::contains(sender_pc), "");
 713     return frame(sender_sp, sender_sp, *link_addr, sender_pc, NULL, NULL, true); // no deopt check
 714   }
 715 #endif
 716 
 717   // tty->print_cr("33333 fast: %d stub: %d", fast, FKind::stub); if (fast) f.print_on(tty);
 718   int slot = 0;
 719   CodeBlob* sender_cb = ContinuationCodeBlobLookup::find_blob_and_oopmap(sender_pc, slot);
 720   if (mode == mode_fast) {
 721     assert (!Interpreter::contains(sender_pc), "");
 722     assert (sender_cb != NULL, "");
 723     return frame(sender_sp, sender_sp, *link_addr, sender_pc, sender_cb, slot == -1 ? NULL : sender_cb->oop_map_for_slot(slot, sender_pc), true); // no deopt check TODO PERF: use a faster constructor that doesn't write cb (shows up in profile)
 724   } else {
 725     return sender_cb != NULL
 726       ? frame(sender_sp, sender_sp, *link_addr, sender_pc, sender_cb, slot == -1 ? NULL : sender_cb->oop_map_for_slot(slot, sender_pc))
 727       : frame(sender_sp, sender_sp, *link_addr, sender_pc);
 728   }
 729 }
 730 
 731 static inline frame sender_for_interpreted_frame(const frame& f) {
 732   return frame(f.sender_sp(), f.interpreter_frame_sender_sp(), f.link(), f.sender_pc());
 733 }
 734 
 735 // inline void Freeze<ConfigT, mode>::update_register_map_stub(RegisterMap* map, const frame& f) {
 736 //   update_register_map(map, link_address_stub(f));
 737 // }
 738 
 739 template <typename ConfigT, op_mode mode>
 740 template<typename FKind>
 741 inline frame Freeze<ConfigT, mode>::sender(const frame& f) {
 742   assert (FKind::is_instance(f), "");
 743   if (FKind::interpreted) {
 744     return sender_for_interpreted_frame(f);
 745   } else {
 746     return sender_for_compiled_frame<FKind, mode>(f);
 747   }
 748 }
 749 
 750 static inline int callee_link_index(const hframe& f) {
 751   return f.sp() - (frame::sender_sp_offset << LogElemsPerWord);
 752 }
 753 
 754 template <typename ConfigT, op_mode mode>
 755 template<bool cont_empty>
 756 hframe Freeze<ConfigT, mode>::new_bottom_hframe(int sp, int ref_sp, address pc, bool interpreted) {
 757   intptr_t fp = _cont.fp();
 758   assert (!cont_empty || fp == 0, "");
 759   void* imd = NULL;
 760   DEBUG_ONLY(imd = interpreted ? hframe::interpreted_link_address(fp, _cont) : NULL);
 761   return hframe(sp, ref_sp, fp, pc, imd, interpreted);
 762 }
 763 
 764 template <typename ConfigT, op_mode mode>
 765 template<typename FKind> hframe Freeze<ConfigT, mode>::new_hframe(const frame& f, intptr_t* vsp, const hframe& caller, int fsize, int num_oops, int argsize) {
 766   assert (FKind::is_instance(f), "");
 767   assert (f.sp() <= vsp, "");
 768   assert (mode != mode_fast || f.sp() == f.unextended_sp(), "");
 769 
 770   int sp = caller.sp() - ContMirror::to_index(fsize);
 771   // int sp = mode == mode_fast ? usp : usp - ((vsp - f.sp()) << LogElemsPerWord);
 772   int ref_sp = caller.ref_sp() - num_oops;
 773   if (mode != mode_fast && caller.is_interpreted_frame()) { // must be done after computing sp above
 774     const_cast<hframe&>(caller).set_sp(caller.sp() - (argsize >> LogBytesPerElement));
 775   }
 776   intptr_t fp;
 777   void* cb_imd;
 778   if (FKind::interpreted) {
 779     fp = sp + ((f.fp() - vsp) << LogElemsPerWord);
 780     cb_imd = hframe::interpreted_link_address(fp, _cont);
 781   } else {
 782     fp = (intptr_t)f.fp();
 783     cb_imd = f.cb();
 784   }
 785 
 786   return hframe(sp, ref_sp, fp, f.pc(), cb_imd, FKind::interpreted);
 787 }
 788 
 789 template <typename ConfigT, op_mode mode>
 790 template <typename FKind, bool top, bool bottom>
 791 inline void Freeze<ConfigT, mode>::patch_pd(const frame& f, hframe& hf, const hframe& caller) {
 792   if (!FKind::interpreted) {
 793     if (_fp_oop_info._has_fp_oop) {
 794       hf.set_fp(_fp_oop_info._fp_index); // TODO PERF non-temporal store
 795     }
 796   } else {
 797     assert (!_fp_oop_info._has_fp_oop, "only compiled frames");
 798   }
 799 
 800   assert (!FKind::interpreted || hf.interpreted_link_address() == _cont.stack_address(hf.fp()), "");
 801   assert (mode != mode_fast || bottom || !Interpreter::contains(caller.pc()), "");
 802   assert (!bottom || caller.is_interpreted_frame() == _cont.is_flag(FLAG_LAST_FRAME_INTERPRETED), "");
 803 
 804   if ((mode != mode_fast || bottom) && caller.is_interpreted_frame()) {
 805     FKind::interpreted ? hf.patch_interpreted_link_relative(caller.fp())
 806                        : caller.patch_callee_link_relative(caller.fp(), _cont); // TODO PERF non-temporal store
 807   } else {
 808     assert (!Interpreter::contains(caller.pc()), "");
 809     // TODO PERF non-temporal store
 810     FKind::interpreted ? hf.patch_interpreted_link(caller.fp())
 811                        : caller.patch_callee_link(caller.fp(), _cont); // caller.fp() already contains _fp_oop_info._fp_index if appropriate, as it was patched when patch is called on the caller
 812   }
 813   if (FKind::interpreted) {
 814     assert (mode != mode_fast, "");
 815     if (bottom && _cont.is_empty()) { // dynamic test, but we don't care because we're interpreted
 816       hf.patch_interpreter_metadata_offset(frame::interpreter_frame_sender_sp_offset, 0);
 817     } else {
 818       hf.patch_sender_sp_relative(_cont.stack_address(caller.sp()));
 819     }
 820   }
 821 }
 822 
 823 template <typename ConfigT, op_mode mode>
 824 template <bool bottom>
 825 inline void Freeze<ConfigT, mode>::align(const hframe& caller, int argsize) {
 826   assert (mode != mode_fast || bottom || !Interpreter::contains(caller.pc()), "");
 827   if ((mode != mode_fast || bottom) && caller.is_interpreted_frame()) {
 828     assert (argsize >= 0, "");
 829     // See Thaw::align
 830     _cont.add_size((SP_WIGGLE + ((argsize /* / 2*/) >> LogBytesPerWord)) * sizeof(intptr_t));
 831   }
 832 }
 833 
 834 template <typename ConfigT, op_mode mode>
 835 inline void Freeze<ConfigT, mode>::relativize_interpreted_frame_metadata(const frame& f, intptr_t* vsp, const hframe& hf) {
 836   intptr_t* vfp = f.fp();
 837   intptr_t* hfp = _cont.stack_address(hf.fp());
 838   assert (hfp == _cont.stack_address(hf.sp()) + (vfp - vsp), "");
 839 
 840   assert ((*(vfp + frame::interpreter_frame_last_sp_offset) != 0) || (f.unextended_sp() == f.sp()), "");
 841 
 842   if (*(vfp + frame::interpreter_frame_last_sp_offset) == 0) {
 843     *(hfp + frame::interpreter_frame_last_sp_offset) = 0;
 844   } else {
 845     ContMirror::relativize(vfp, hfp, frame::interpreter_frame_last_sp_offset);
 846   }
 847   ContMirror::relativize(vfp, hfp, frame::interpreter_frame_initial_sp_offset); // == block_top == block_bottom
 848   ContMirror::relativize(vfp, hfp, frame::interpreter_frame_locals_offset);
 849 }
 850 
 851 template <typename ConfigT, op_mode mode>
 852 inline frame Thaw<ConfigT, mode>::new_entry_frame() {
 853   // if (Interpreter::contains(_cont.entryPC())) _cont.set_entrySP(_cont.entrySP() - 1);
 854   return frame(_cont.entrySP(), _cont.entryFP(), _cont.entryPC()); // TODO PERF: This finds code blob and computes deopt state
 855 }
 856 
 857 template <typename ConfigT, op_mode mode>
 858 template<typename FKind> frame Thaw<ConfigT, mode>::new_frame(const hframe& hf, intptr_t* vsp) {
 859   assert (FKind::is_instance(hf), "");
 860 
 861   if (FKind::interpreted) {
 862     // intptr_t* sp = vsp - ((hsp - hf.sp()) >> LogElemsPerWord);
 863     int hsp = hf.sp();
 864     intptr_t* fp = vsp + ((hf.fp() - hsp) >> LogElemsPerWord);
 865     return frame(vsp, vsp, fp, hf.pc());
 866   } else {
 867     intptr_t* fp = (intptr_t*)hf.fp();
 868   #ifdef CONT_DOUBLE_NOP
 869     hf.get_cb();
 870   #endif
 871     assert (hf.cb() != NULL && hf.oop_map() != NULL, "");
 872     return frame(vsp, vsp, fp, hf.pc(), hf.cb(), hf.oop_map()); // TODO PERF : this computes deopt state; is it necessary?
 873   }
 874 }
 875 
 876 template <typename ConfigT, op_mode mode>
 877 inline intptr_t** Thaw<ConfigT, mode>::frame_callee_info_address(frame& f) {
 878   return f.fp_addr(); // we write into the frame object, not the frame on the stack
 879 }
 880 
 881 template <typename ConfigT, op_mode mode>
 882 template<typename FKind, bool top, bool bottom>
 883 inline intptr_t* Thaw<ConfigT, mode>::align(const hframe& hf, intptr_t* vsp, frame& caller) {
 884   assert (FKind::is_instance(hf), "");
 885   assert (mode != mode_fast || bottom, "");
 886 
 887   if (!FKind::interpreted && !FKind::stub) {
 888     int addedWords = 0;
 889     assert (_cont.is_flag(FLAG_LAST_FRAME_INTERPRETED) == Interpreter::contains(_cont.pc()), "");
 890     if (((bottom || mode != mode_fast) && caller.is_interpreted_frame()) 
 891         || (bottom && _cont.is_flag(FLAG_LAST_FRAME_INTERPRETED))) {
 892 
 893       // Deoptimization likes ample room between interpreted frames and compiled frames. 
 894       // This is due to caller_adjustment calculation in Deoptimization::fetch_unroll_info_helper.
 895       // An attempt to simplify that calculation and make more room during deopt has failed some tests.
 896 
 897       addedWords = (SP_WIGGLE-1); // We subtract 1 for alignment, which we may add later
 898 
 899       // SharedRuntime::gen_i2c_adapter makes room that's twice as big as required for the stack-passed arguments by counting slots but subtracting words from rsp 
 900       assert (VMRegImpl::stack_slot_size == 4, "");
 901       int argsize = hf.compiled_frame_stack_argsize();
 902       assert (argsize >= 0, "");
 903       addedWords += (argsize /* / 2*/) >> LogBytesPerWord; // Not sure why dividing by 2 is not big enough.
 904 
 905       if (!bottom || _cont.is_flag(FLAG_LAST_FRAME_INTERPRETED)) {
 906         _cont.sub_size((1 + addedWords) * sizeof(intptr_t)); // we add one whether or not we've aligned because we add it in freeze_interpreted_frame
 907       } 
 908       if (!bottom || caller.is_interpreted_frame()) {
 909         log_develop_trace(jvmcont)("Aligning compiled frame 0: " INTPTR_FORMAT " -> " INTPTR_FORMAT, p2i(vsp), p2i(vsp - addedWords));
 910         vsp -= addedWords;
 911       } else {
 912         addedWords = 0;
 913       }
 914     }
 915   #ifdef _LP64
 916     if ((intptr_t)vsp % 16 != 0) {
 917       log_develop_trace(jvmcont)("Aligning compiled frame 1: " INTPTR_FORMAT " -> " INTPTR_FORMAT, p2i(vsp), p2i(vsp - 1));
 918       assert(caller.is_interpreted_frame() 
 919         || (bottom && !FKind::stub && hf.compiled_frame_stack_argsize() % 16 != 0), "");
 920       addedWords++;
 921       vsp--;
 922     }
 923     assert((intptr_t)vsp % 16 == 0, "");
 924   #endif
 925 
 926    log_develop_trace(jvmcont)("Aligning sender sp: " INTPTR_FORMAT " -> " INTPTR_FORMAT, p2i(caller.sp()), p2i(caller.sp() - addedWords));
 927     caller.set_sp(caller.sp() - addedWords);
 928   }
 929 
 930   return vsp;
 931 }
 932 
 933 template <typename ConfigT, op_mode mode>
 934 template<typename FKind, bool top, bool bottom>
 935 inline void Thaw<ConfigT, mode>::patch_pd(frame& f, const frame& caller) {
 936   assert (!bottom || caller.fp() == _cont.entryFP(), "caller.fp: " INTPTR_FORMAT " entryFP: " INTPTR_FORMAT, p2i(caller.fp()), p2i(_cont.entryFP()));
 937   assert (FKind::interpreted || slow_link_address<FKind>(f) == Frame::callee_link_address(caller), "");
 938   FKind::interpreted ? patch_link<FKind>(f, caller.fp())
 939                      : patch_callee_link(caller, caller.fp());
 940 }
 941 
 942 template <typename ConfigT, op_mode mode>
 943 inline void Thaw<ConfigT, mode>::derelativize_interpreted_frame_metadata(const hframe& hf, const frame& f) {
 944   intptr_t* vfp = f.fp();
 945 
 946   intptr_t* hfp = _cont.stack_address(hf.fp());
 947   if (*(hfp + frame::interpreter_frame_last_sp_offset) == 0) {
 948       *(vfp + frame::interpreter_frame_last_sp_offset) = 0;
 949   } else {
 950     ContMirror::derelativize(vfp, frame::interpreter_frame_last_sp_offset);
 951   }
 952   ContMirror::derelativize(vfp, frame::interpreter_frame_initial_sp_offset);
 953   ContMirror::derelativize(vfp, frame::interpreter_frame_locals_offset);
 954 }
 955 
 956 ////////
 957 
 958 // Java frames don't have callee saved registers (except for rbp), so we can use a smaller RegisterMap
 959 class SmallRegisterMap {
 960   static const VMReg my_reg; // = rbp->as_VMReg();
 961 
 962 public:
 963   // as_RegisterMap is used when we didn't want to templatize and abstract over RegisterMap type to support SmallRegisterMap
 964   // Consider enhancing SmallRegisterMap to support those cases
 965   const RegisterMap* as_RegisterMap() const { return NULL; }
 966   RegisterMap* as_RegisterMap() { return NULL; }
 967   
 968 private:
 969   intptr_t*   _rbp;
 970 
 971 #ifdef ASSERT
 972   JavaThread* _thread;
 973 #endif
 974   // bool        _update_map;              // Tells if the register map need to be updated when traversing the stack
 975   // bool        _validate_oops;           // whether to perform valid oop checks in asserts -- used only in the map use for continuation freeze/thaw
 976   // bool        _walk_cont;               // whether to walk frames on a continuation stack
 977 public:
 978   SmallRegisterMap(JavaThread *thread, bool update_map = true, bool walk_cont = false, bool validate_oops = true) 
 979    DEBUG_ONLY(: _thread(thread)) /*, _update_map(update_map), _validate_oops(validate_oops) */ {
 980      _rbp = NULL;
 981   }
 982   SmallRegisterMap(const SmallRegisterMap* map) 
 983     DEBUG_ONLY(: _thread(map->thread())) /*, _update_map(map->update_map()), _validate_oops(map->validate_oops()) */ {
 984     _rbp = map->_rbp;
 985   }
 986   SmallRegisterMap(const RegisterMap* map) 
 987     DEBUG_ONLY(: _thread(map->thread())) /* , _update_map(map->update_map()), _validate_oops(map->validate_oops()) */ {
 988     _rbp = (intptr_t*)map->location(my_reg);
 989   }
 990 
 991   address location(VMReg reg) const {
 992     assert (reg == my_reg || reg == my_reg->next(), "Reg: %s", reg->name());
 993     return (address)_rbp;
 994   }
 995 
 996   void set_location(VMReg reg, address loc) {
 997     assert(!validate_oops() || update_map(), "updating map that does not need updating");
 998     assert (reg == my_reg || reg == my_reg->next(), "Reg: %s", reg->name());
 999     // tty->print_cr(">>> set location %s(%ld) loc: %p", reg->name(), reg->value(), loc);
1000     _rbp = (intptr_t*)loc;
1001   }
1002 
1003   JavaThread* thread() const {
1004   #ifdef ASSERT
1005     return _thread;
1006   #else
1007     guarantee (false, ""); 
1008     return NULL; 
1009   #endif
1010   }
1011   bool update_map()    const { return false; }
1012   bool validate_oops() const { return false; }
1013   bool walk_cont()     const { return false; }
1014   bool include_argument_oops() const { return false; }
1015   void set_include_argument_oops(bool f)  {}
1016   bool in_cont()      const { return false; }
1017 
1018 #ifdef ASSERT
1019   // void set_skip_missing(bool value) { _skip_missing = value; }
1020   bool should_skip_missing() const  { return false; }
1021 
1022   VMReg find_register_spilled_here(void* p) {
1023     return _rbp == (intptr_t*)p ? my_reg : NULL;
1024   }
1025 #endif
1026 
1027 #ifndef PRODUCT
1028   void print() const { print_on(tty); }
1029   
1030   void print_on(outputStream* st) const {
1031     st->print_cr("Register map");
1032 
1033     VMReg r = my_reg;
1034 
1035     intptr_t* src = (intptr_t*) location(r);
1036     if (src != NULL) {
1037       r->print_on(st);
1038       st->print(" [" INTPTR_FORMAT "] = ", p2i(src));
1039       if (((uintptr_t)src & (sizeof(*src)-1)) != 0) {
1040         st->print_cr("<misaligned>");
1041       } else {
1042         st->print_cr(INTPTR_FORMAT, *src);
1043       }
1044     }
1045   }
1046 
1047 #endif
1048 };
1049 
1050 const VMReg SmallRegisterMap::my_reg = rbp->as_VMReg();
1051 
1052 /// DEBUGGING
1053 
1054 static void print_vframe(frame f, const RegisterMap* map, outputStream* st) {
1055   if (st != NULL && !log_is_enabled(Trace, jvmcont)) return;
1056   if (st == NULL) st = tty;
1057 
1058   st->print_cr("\tfp: " INTPTR_FORMAT " real_fp: " INTPTR_FORMAT ", sp: " INTPTR_FORMAT " pc: " INTPTR_FORMAT " usp: " INTPTR_FORMAT, p2i(f.fp()), p2i(f.real_fp()), p2i(f.sp()), p2i(f.pc()), p2i(f.unextended_sp()));
1059 
1060   f.print_on(st);
1061 
1062   // st->print("\tpc: "); os::print_location(st, *(intptr_t*)f.pc());
1063   intptr_t* fp = f.fp();
1064   st->print("\tcb: ");
1065   if (f.cb() == NULL) {
1066     st->print_cr("NULL");
1067     return;
1068   }
1069   f.cb()->print_value_on(st); st->cr();
1070   if (f.is_interpreted_frame()) {
1071     Method* method = f.interpreter_frame_method();
1072     st->print_cr("\tinterpreted");
1073     st->print("\tMethod (at: " INTPTR_FORMAT "): ", p2i(fp + frame::interpreter_frame_method_offset)); method->print_short_name(st); st->cr();
1074     st->print_cr("\tcode_size: %d",         method->code_size());
1075     // st->print_cr("base: " INTPTR_FORMAT " end: " INTPTR_FORMAT, p2i(method->constMethod()->code_base()), p2i(method->constMethod()->code_end()));
1076     intptr_t** link_address = (intptr_t**)(fp + frame::link_offset);
1077     st->print_cr("\tlink: " INTPTR_FORMAT " (at: " INTPTR_FORMAT ")",    p2i(*link_address), p2i(link_address));
1078     st->print_cr("\treturn_pc: " INTPTR_FORMAT,        p2i(*(void**)(fp + frame::return_addr_offset)));
1079     st->print_cr("\tssp: " INTPTR_FORMAT,              p2i((void*)  (fp + frame::sender_sp_offset)));
1080     st->print_cr("\tissp: " INTPTR_FORMAT,             p2i(*(void**)(fp + frame::interpreter_frame_sender_sp_offset)));
1081     st->print_cr("\tlast_sp: " INTPTR_FORMAT,          p2i(*(void**)(fp + frame::interpreter_frame_last_sp_offset)));
1082     st->print_cr("\tinitial_sp: " INTPTR_FORMAT,       p2i(*(void**)(fp + frame::interpreter_frame_initial_sp_offset)));
1083     // st->print_cr("\tmon_block_top: " INTPTR_FORMAT,    p2i(*(void**)(fp + frame::interpreter_frame_monitor_block_top_offset)));
1084     // st->print_cr("\tmon_block_bottom: " INTPTR_FORMAT, p2i(*(void**)(fp + frame::interpreter_frame_monitor_block_bottom_offset)));
1085     st->print_cr("\tlocals: " INTPTR_FORMAT,           p2i(*(void**)(fp + frame::interpreter_frame_locals_offset)));
1086     st->print_cr("\texpression_stack_size: %d", f.interpreter_frame_expression_stack_size());
1087     // st->print_cr("\tcomputed expression_stack_size: %d", interpreter_frame_expression_stack_size(f));
1088     st->print_cr("\tcache: " INTPTR_FORMAT,            p2i(*(void**)(fp + frame::interpreter_frame_cache_offset)));
1089     st->print_cr("\tbcp: " INTPTR_FORMAT,              p2i(*(void**)(fp + frame::interpreter_frame_bcp_offset)));
1090     st->print_cr("\tbci: %d",               method->bci_from(*(address*)(fp + frame::interpreter_frame_bcp_offset)));
1091     st->print_cr("\tmirror: " INTPTR_FORMAT,           p2i(*(void**)(fp + frame::interpreter_frame_mirror_offset)));
1092     // st->print("\tmirror: "); os::print_location(st, *(intptr_t*)(fp + frame::interpreter_frame_mirror_offset), true);
1093     st->print("\treturn_pc: "); os::print_location(st, *(intptr_t*)(fp + frame::return_addr_offset));
1094   } else {
1095     st->print_cr("\tcompiled/C");
1096     if (f.is_compiled_frame())
1097       st->print_cr("\torig_pc: " INTPTR_FORMAT,    p2i(f.cb()->as_nmethod()->get_original_pc(&f)));
1098     // st->print_cr("\torig_pc_address: " INTPTR_FORMAT, p2i(f.cb()->as_nmethod()->orig_pc_addr(&f)));
1099     // st->print_cr("\tlink: " INTPTR_FORMAT,       p2i((void*)f.at(frame::link_offset)));
1100     // st->print_cr("\treturn_pc: " INTPTR_FORMAT,  p2i(*(void**)(fp + frame::return_addr_offset)));
1101     // st->print_cr("\tssp: " INTPTR_FORMAT,        p2i(*(void**)(fp + frame::sender_sp_offset)));
1102     st->print_cr("\tcb.size: %d",    f.cb()->frame_size());
1103     intptr_t** link_address = (intptr_t**)(f.real_fp() - frame::sender_sp_offset);
1104     st->print_cr("\tlink: " INTPTR_FORMAT " (at: " INTPTR_FORMAT ")", p2i(*link_address), p2i(link_address));
1105     st->print_cr("\t'real' return_pc: " INTPTR_FORMAT,  p2i(*(void**)(f.real_fp() - 1)));
1106     st->print("\t'real' return_pc: "); os::print_location(st, *(intptr_t*)(f.real_fp() - 1));
1107     // st->print("\treturn_pc: "); os::print_location(st, *(intptr_t*)(fp + frame::return_addr_offset));
1108   }
1109   st->print_cr("-------");
1110 }
1111 
1112 #endif // CPU_X86_CONTINUATION_X86_INLINE_HPP