/*
 * Copyright (c) 2011, 2025, 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 "classfile/javaClasses.inline.hpp"
#include "code/compiledIC.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compilerThread.hpp"
#include "compiler/oopMap.hpp"
#include "gc/shared/barrierSetNMethod.hpp"
#include "jvmci/jvmciCodeInstaller.hpp"
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "memory/universe.hpp"
#include "oops/compressedKlass.inline.hpp"
#include "oops/klass.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/arguments.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/align.hpp"

// frequently used constants
// Allocate them with new so they are never destroyed (otherwise, a
// forced exit could destroy these objects while they are still in
// use).
ConstantOopWriteValue* CodeInstaller::_oop_null_scope_value = new (mtJVMCI) ConstantOopWriteValue(nullptr);
ConstantIntValue*      CodeInstaller::_int_m1_scope_value = new (mtJVMCI) ConstantIntValue(-1);
ConstantIntValue*      CodeInstaller::_int_0_scope_value =  new (mtJVMCI) ConstantIntValue((jint)0);
ConstantIntValue*      CodeInstaller::_int_1_scope_value =  new (mtJVMCI) ConstantIntValue(1);
ConstantIntValue*      CodeInstaller::_int_2_scope_value =  new (mtJVMCI) ConstantIntValue(2);
LocationValue*         CodeInstaller::_illegal_value = new (mtJVMCI) LocationValue(Location());
MarkerValue*           CodeInstaller::_virtual_byte_array_marker = new (mtJVMCI) MarkerValue();

static bool is_set(u1 flags, u1 bit) {
  return flags & bit;
}

oop HotSpotCompiledCodeStream::get_oop(int id, JVMCI_TRAPS) const {
  if (_object_pool.is_null()) {
    JVMCI_ERROR_NULL("object pool is null%s", context());
  }
  if (!_object_pool.is_null() && 0 <= id && id < _object_pool->length()) {
    return _object_pool->obj_at(id);
  }
  JVMCI_ERROR_NULL("unknown direct object id %d%s", id, context());
}

u4 HotSpotCompiledCodeStream::offset() const {
  u4 res = 0;
  for (Chunk* c = _head; c != nullptr; c = c->next()) {
    if (c == _chunk) {
      res += _pos - c->data();
      break;
    } else {
      res += c->size();
    }
  }
  return res;
}

bool HotSpotCompiledCodeStream::available() const {
  u4 rem = _chunk->data_end() - _pos;
  for (Chunk* c = _chunk->next(); c != nullptr; c = c->next()) {
    rem += c->size();
  }
  return rem;
}

void HotSpotCompiledCodeStream::dump_buffer(outputStream* st) const {
  st->print_cr("HotSpotCompiledCode stream for %s:", code_desc());
  int chunk_index = 0;
  for (Chunk* c = _head; c != nullptr; c = c->next()) {
    const u1* data     = c->data();
    const u1* data_end = c->data_end();

    int to_dump = data_end - data;
    st->print_cr("# chunk %d, %d bytes", chunk_index, to_dump);
    st->print_data((void*) data, to_dump, true, false);
    chunk_index++;
  }
}

void HotSpotCompiledCodeStream::dump_buffer_tail(int len, outputStream* st) const {
  const u1* start;
  int avail = _pos - _chunk->data();
  if (len >= avail) {
    len = avail;
    start = _chunk->data();
  } else {
    start = _pos - len;

    // Ensure start is 16-byte aligned wrt chunk start
    int start_offset = start - _chunk->data();
    start -= (start_offset % 16);
    len = _pos - start;
  }

  st->print_cr("Last %d bytes up to current read position " INTPTR_FORMAT " in HotSpotCompiledCode stream for %s:", len, p2i(_pos), code_desc());
  st->print_data((void*) start, len, true, false);
}

const char* HotSpotCompiledCodeStream::context() const {
  stringStream st;
  st.cr();
  st.print_cr("at " INTPTR_FORMAT " in HotSpotCompiledCode stream", p2i(_pos));
  dump_buffer_tail(100, &st);
  return st.as_string();
}

void HotSpotCompiledCodeStream::before_read(u1 size) {
  if (_pos + size > _chunk->data_end()) {
    Chunk* next = _chunk->next();
    if (next == nullptr || size > next->size()) {
      dump_buffer();
      fatal("%s: reading %d bytes overflows buffer at " INTPTR_FORMAT, code_desc(), size, p2i(_pos));
    }
    _chunk = next;
    _pos = _chunk->data();
  }
}

// Reads a size followed by an ascii string from the stream and
// checks that they match `expect_size` and `expect_name` respectively. This
// implements a rudimentary type checking of the stream between the stream producer
// (Java) and the consumer (C++).
void HotSpotCompiledCodeStream::check_data(u2 expect_size, const char* expect_name) {
  u2 actual_size = get_u1();
  u2 ascii_len = get_u1();
  const char* actual_name = (const char*) _pos;
  char* end = (char*) _pos + ascii_len;
  _pos = (const u1*) end;
  if (strlen(expect_name) != ascii_len || strncmp(expect_name, actual_name, ascii_len) != 0) {
    dump_buffer();
    fatal("%s: expected \"%s\" at " INTPTR_FORMAT ", got \"%.*s\" (len: %d)",
        code_desc(), expect_name, p2i(actual_name), ascii_len, actual_name, ascii_len);
  }
  if (actual_size != expect_size) {
    dump_buffer();
    fatal("%s: expected \"%s\" at " INTPTR_FORMAT " to have size %u, got %u",
        code_desc(), expect_name, p2i(actual_name), expect_size, actual_size);
  }
}

const char* HotSpotCompiledCodeStream::read_utf8(const char* name, JVMCI_TRAPS) {
  jint utf_len = read_s4(name);
  if (utf_len == -1) {
    return nullptr;
  }
  guarantee(utf_len >= 0, "bad utf_len: %d", utf_len);

  const char* utf = (const char*) _pos;
  char* end = (char*) _pos + utf_len;
  _pos = (const u1*) (end + 1);
  if (*end != '\0') {
    JVMCI_ERROR_NULL("UTF8 string at " INTPTR_FORMAT " of length %d missing 0 terminator: \"%.*s\"%s",
        p2i(utf), utf_len, utf_len, utf, context());
  }
  return utf;
}

Method* HotSpotCompiledCodeStream::read_method(const char* name) {
  return (Method*) read_u8(name);
}

Klass* HotSpotCompiledCodeStream::read_klass(const char* name) {
  return (Klass*) read_u8(name);
}

ScopeValue* HotSpotCompiledCodeStream::virtual_object_at(int id, JVMCI_TRAPS) const {
  if (_virtual_objects == nullptr) {
    JVMCI_ERROR_NULL("virtual object id %d read outside scope of decoding DebugInfo%s", id, context());
  }
  if (id < 0 || id >= _virtual_objects->length()) {
    JVMCI_ERROR_NULL("invalid virtual object id %d%s", id, context());
  }
  return _virtual_objects->at(id);
}

#ifndef PRODUCT
void CodeInstaller::verify_bci_constants(JVMCIEnv* env) {
#define CHECK_IN_SYNC(name) do { \
  int expect = env->get_BytecodeFrame_ ## name ##_BCI(); \
  int actual = name##_BCI; \
  if (expect != actual) fatal("CodeInstaller::" #name "_BCI(%d) != BytecodeFrame." #name "_BCI(%d)", expect, actual); \
} while(0)

  CHECK_IN_SYNC(UNWIND);
  CHECK_IN_SYNC(BEFORE);
  CHECK_IN_SYNC(AFTER);
  CHECK_IN_SYNC(AFTER_EXCEPTION);
  CHECK_IN_SYNC(UNKNOWN);
  CHECK_IN_SYNC(INVALID_FRAMESTATE);
#undef CHECK_IN_SYNC
}
#endif

VMReg CodeInstaller::getVMRegFromLocation(HotSpotCompiledCodeStream* stream, int total_frame_size, JVMCI_TRAPS) {
  u2 reg = stream->read_u2("register");
  u2 offset = stream->read_u2("offset");

  if (reg != NO_REGISTER) {
    VMReg vmReg = CodeInstaller::get_hotspot_reg(reg, JVMCI_CHECK_NULL);
    if (offset % 4 == 0) {
      return vmReg->next(offset / 4);
    } else {
      JVMCI_ERROR_NULL("unaligned subregister offset %d in oop map%s", offset, stream->context());
    }
  } else {
    if (offset % 4 == 0) {
      VMReg vmReg = VMRegImpl::stack2reg(offset / 4);
      if (!OopMapValue::legal_vm_reg_name(vmReg)) {
        // This restriction only applies to VMRegs that are used in OopMap but
        // since that's the only use of VMRegs it's simplest to put this test
        // here.  This test should also be equivalent legal_vm_reg_name but JVMCI
        // clients can use max_oop_map_stack_stack_offset to detect this problem
        // directly.  The asserts just ensure that the tests are in agreement.
        assert(offset > CompilerToVM::Data::max_oop_map_stack_offset(), "illegal VMReg");
        JVMCI_ERROR_NULL("stack offset %d is too large to be encoded in OopMap (max %d)%s",
                         offset, CompilerToVM::Data::max_oop_map_stack_offset(), stream->context());
      }
      assert(OopMapValue::legal_vm_reg_name(vmReg), "illegal VMReg");
      return vmReg;
    } else {
      JVMCI_ERROR_NULL("unaligned stack offset %d in oop map%s", offset, stream->context());
    }
  }
}

OopMap* CodeInstaller::create_oop_map(HotSpotCompiledCodeStream* stream, u1 debug_info_flags, JVMCI_TRAPS) {
  assert(is_set(debug_info_flags, DI_HAS_REFERENCE_MAP), "must be");
  u2 max_register_size = stream->read_u2("maxRegisterSize");
  if (!_has_wide_vector && SharedRuntime::is_wide_vector(max_register_size)) {
    if (SharedRuntime::polling_page_vectors_safepoint_handler_blob() == nullptr) {
      JVMCI_ERROR_NULL("JVMCI is producing code using vectors larger than the runtime supports%s", stream->context());
    }
    _has_wide_vector = true;
  }
  u2 length = stream->read_u2("referenceMap:length");

  OopMap* map = new OopMap(_total_frame_size, _parameter_count);
  for (int i = 0; i < length; i++) {
    bool has_derived = stream->read_bool("hasDerived");
    u2 bytes = stream->read_u2("sizeInBytes");
    VMReg vmReg = getVMRegFromLocation(stream, _total_frame_size, JVMCI_CHECK_NULL);
    if (has_derived) {
      // derived oop
      if (bytes == LP64_ONLY(8) NOT_LP64(4)) {
        VMReg baseReg = getVMRegFromLocation(stream, _total_frame_size, JVMCI_CHECK_NULL);
        map->set_derived_oop(vmReg, baseReg);
      } else {
        JVMCI_ERROR_NULL("invalid derived oop size in ReferenceMap: %d%s", bytes, stream->context());
      }
#ifdef _LP64
    } else if (bytes == 8) {
      // wide oop
      map->set_oop(vmReg);
    } else if (bytes == 4) {
      // narrow oop
      map->set_narrowoop(vmReg);
#else
    } else if (bytes == 4) {
      map->set_oop(vmReg);
#endif
    } else {
      JVMCI_ERROR_NULL("invalid oop size in ReferenceMap: %d%s", bytes, stream->context());
    }
  }

  if (is_set(debug_info_flags, DI_HAS_CALLEE_SAVE_INFO)) {
    length = stream->read_u2("calleeSaveInfo:length");
    for (jint i = 0; i < length; i++) {
      u2 jvmci_reg_number = stream->read_u2("register");
      VMReg hotspot_reg = CodeInstaller::get_hotspot_reg(jvmci_reg_number, JVMCI_CHECK_NULL);
      // HotSpot stack slots are 4 bytes
      u2 jvmci_slot = stream->read_u2("slot");
      jint hotspot_slot = jvmci_slot * VMRegImpl::slots_per_word;
      VMReg hotspot_slot_as_reg = VMRegImpl::stack2reg(hotspot_slot);
      map->set_callee_saved(hotspot_slot_as_reg, hotspot_reg);
#ifdef _LP64
      // (copied from generate_oop_map() in c1_Runtime1_x86.cpp)
      VMReg hotspot_slot_hi_as_reg = VMRegImpl::stack2reg(hotspot_slot + 1);
      map->set_callee_saved(hotspot_slot_hi_as_reg, hotspot_reg->next());
#endif
    }
  }
  return map;
}

void* CodeInstaller::record_metadata_reference(CodeSection* section, address dest, HotSpotCompiledCodeStream* stream, u1 tag, JVMCI_TRAPS) {
  /*
   * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base
   * class is in general not equal to the pointer of the subclass. When patching metaspace pointers,
   * the compiler expects a direct pointer to the subclass (Klass* or Method*), not a pointer to the
   * base class (Metadata* or MetaspaceObj*).
   */
  if (tag == PATCH_KLASS) {
    Klass* klass = stream->read_klass("patch:klass");
    int index = _oop_recorder->find_index(klass);
    section->relocate(dest, metadata_Relocation::spec(index));
    JVMCI_event_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());
    return klass;
  } else if (tag == PATCH_METHOD) {
    Method* method = stream->read_method("patch:method");
    int index = _oop_recorder->find_index(method);
    section->relocate(dest, metadata_Relocation::spec(index));
    JVMCI_event_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), method->name()->as_C_string());
    return method;
  } else {
    JVMCI_ERROR_NULL("unexpected metadata reference tag: %d%s", tag, stream->context());
  }
}

#ifdef _LP64
narrowKlass CodeInstaller::record_narrow_metadata_reference(CodeSection* section, address dest, HotSpotCompiledCodeStream* stream, u1 tag, JVMCI_TRAPS) {
  if (tag != PATCH_NARROW_KLASS) {
    JVMCI_ERROR_0("unexpected compressed pointer tag %d%s", tag, stream->context());
  }
  Klass* klass = stream->read_klass("patch:klass");
  int index = _oop_recorder->find_index(klass);
  section->relocate(dest, metadata_Relocation::spec(index));
  JVMCI_event_3("narrowKlass[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());
  guarantee(CompressedKlassPointers::is_encodable(klass), "klass cannot be compressed: %s", klass->external_name());
  return CompressedKlassPointers::encode(klass);
}
#endif

ScopeValue* CodeInstaller::to_primitive_value(HotSpotCompiledCodeStream* stream, jlong raw, BasicType type, ScopeValue* &second, JVMCI_TRAPS) {
  if (type == T_INT || type == T_FLOAT) {
    jint prim = (jint) raw;
    switch (prim) {
      case -1: return _int_m1_scope_value;
      case  0: return _int_0_scope_value;
      case  1: return _int_1_scope_value;
      case  2: return _int_2_scope_value;
      default: return new ConstantIntValue(prim);
    }
  } else if (type == T_LONG || type == T_DOUBLE) {
    jlong prim = raw;
    second = _int_1_scope_value;
    return new ConstantLongValue(prim);
  } else {
    JVMCI_ERROR_NULL("unexpected primitive constant type %s%s", basictype_to_str(type), stream->context());
  }
}

Handle CodeInstaller::read_oop(HotSpotCompiledCodeStream* stream, u1 tag, JVMCI_TRAPS) {
  oop obj;
  if (tag == OBJECT_ID) {
    obj = stream->get_oop(stream->read_u1("id"), JVMCI_CHECK_(Handle()));
  } else if (tag == OBJECT_ID2) {
    obj = stream->get_oop(stream->read_u2("id:2"), JVMCI_CHECK_(Handle()));
  } else if (tag == JOBJECT) {
    jlong object_handle = stream->read_u8("jobject");
    obj = jvmci_env()->resolve_oop_handle(object_handle);
  } else {
    JVMCI_ERROR_(Handle(), "unexpected oop tag: %d", tag)
  }
  if (obj == nullptr) {
    JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly null", Handle());
  } else {
    guarantee(oopDesc::is_oop_or_null(obj), "invalid oop: " INTPTR_FORMAT, p2i((oopDesc*) obj));
  }
  return Handle(stream->thread(), obj);
}

ScopeValue* CodeInstaller::get_scope_value(HotSpotCompiledCodeStream* stream, u1 tag, BasicType type, ScopeValue* &second, JVMCI_TRAPS) {
  second = nullptr;
  bool stack_slot_is_s2 = true;
  switch (tag) {
    case ILLEGAL: {
      if (type != T_ILLEGAL) {
        JVMCI_ERROR_NULL("unexpected illegal value, expected %s%s", basictype_to_str(type), stream->context());
      }
      return _illegal_value;
    }
    case REGISTER_PRIMITIVE:
    case REGISTER_NARROW_OOP:
    case REGISTER_OOP:
    case REGISTER_VECTOR: {
      u2 number = stream->read_u2("register");
      VMReg hotspotRegister = get_hotspot_reg(number, JVMCI_CHECK_NULL);
      if (is_general_purpose_reg(hotspotRegister)) {
        Location::Type locationType;
        if (type == T_OBJECT) {
          locationType = tag == REGISTER_NARROW_OOP ? Location::narrowoop : Location::oop;
        } else if (type == T_LONG) {
          locationType = Location::lng;
        } else if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) {
          locationType = Location::int_in_long;
        } else {
          JVMCI_ERROR_NULL("unexpected type %s in CPU register%s", basictype_to_str(type), stream->context());
        }
        ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, hotspotRegister));
        if (type == T_LONG) {
          second = value;
        }
        return value;
      } else {
        Location::Type locationType;
        if (type == T_FLOAT) {
          // this seems weird, but the same value is used in c1_LinearScan
          locationType = Location::normal;
        } else if (type == T_DOUBLE) {
          locationType = Location::dbl;
        } else if (type == T_OBJECT && tag == REGISTER_VECTOR) {
          locationType = Location::vector;
        } else {
          JVMCI_ERROR_NULL("unexpected type %s in floating point register%s", basictype_to_str(type), stream->context());
        }
        ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, hotspotRegister));
        if (type == T_DOUBLE) {
          second = value;
        }
        return value;
      }
    }
    case STACK_SLOT4_PRIMITIVE:
    case STACK_SLOT4_NARROW_OOP:
    case STACK_SLOT4_OOP:
    case STACK_SLOT4_VECTOR:
      stack_slot_is_s2 = false;
      // fall through
    case STACK_SLOT_PRIMITIVE:
    case STACK_SLOT_NARROW_OOP:
    case STACK_SLOT_OOP:
    case STACK_SLOT_VECTOR: {
      jint offset = stack_slot_is_s2 ? (jshort) stream->read_s2("offset") : stream->read_s4("offset4");
      if (stream->read_bool("addRawFrameSize")) {
        offset += _total_frame_size;
      }
      Location::Type locationType;
      if (type == T_OBJECT) {
        locationType = tag == STACK_SLOT_VECTOR ? Location::vector : tag == STACK_SLOT_NARROW_OOP ? Location::narrowoop : Location::oop;
      } else if (type == T_LONG) {
        locationType = Location::lng;
      } else if (type == T_DOUBLE) {
        locationType = Location::dbl;
      } else if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) {
        locationType = Location::normal;
      } else {
        JVMCI_ERROR_NULL("unexpected type %s in stack slot%s", basictype_to_str(type), stream->context());
      }
      ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset));
      if (type == T_DOUBLE || type == T_LONG) {
        second = value;
      }
      return value;
    }
    case NULL_CONSTANT:      { return _oop_null_scope_value; }
    case RAW_CONSTANT:       { return new ConstantLongValue(stream->read_u8("primitive")); }
    case PRIMITIVE_0:        { ScopeValue* v = to_primitive_value(stream, 0, type, second, JVMCI_CHECK_NULL); return v; }
    case PRIMITIVE4:         { ScopeValue* v = to_primitive_value(stream, stream->read_s4("primitive4"), type, second, JVMCI_CHECK_NULL); return v; }
    case PRIMITIVE8:         { ScopeValue* v = to_primitive_value(stream, stream->read_s8("primitive8"), type, second, JVMCI_CHECK_NULL); return v; }
    case VIRTUAL_OBJECT_ID:  { ScopeValue* v = stream->virtual_object_at(stream->read_u1("id"),   JVMCI_CHECK_NULL); return v; }
    case VIRTUAL_OBJECT_ID2: { ScopeValue* v = stream->virtual_object_at(stream->read_u2("id:2"), JVMCI_CHECK_NULL); return v; }

    case OBJECT_ID:
    case OBJECT_ID2:
    case JOBJECT: {
      Handle obj = read_oop(stream, tag, JVMCI_CHECK_NULL);
      return new ConstantOopWriteValue(JNIHandles::make_local(obj()));
    }
    default: {
      JVMCI_ERROR_NULL("unexpected tag in scope: %d%s", tag, stream->context())
    }
  }
}

void CodeInstaller::record_object_value(ObjectValue* sv, HotSpotCompiledCodeStream* stream, JVMCI_TRAPS) {
  oop javaMirror = JNIHandles::resolve(sv->klass()->as_ConstantOopWriteValue()->value());
  Klass* klass = java_lang_Class::as_Klass(javaMirror);
  bool isLongArray = klass == Universe::longArrayKlass();
  bool isByteArray = klass == Universe::byteArrayKlass();

  u2 length = stream->read_u2("values:length");
  for (jint i = 0; i < length; i++) {
    ScopeValue* cur_second = nullptr;
    BasicType type = (BasicType) stream->read_u1("basicType");
    ScopeValue* value;
    u1 tag = stream->read_u1("tag");
    if (tag == ILLEGAL) {
      if (isByteArray && type == T_ILLEGAL) {
        /*
         * The difference between a virtualized large access and a deferred write is the kind stored in the slotKinds
         * of the virtual object: in the virtualization case, the kind is illegal, in the deferred write case, the kind
         * is access stack kind (an int).
         */
        value = _virtual_byte_array_marker;
      } else {
        value = _illegal_value;
        if (type == T_DOUBLE || type == T_LONG) {
            cur_second = _illegal_value;
        }
      }
    } else {
      value = get_scope_value(stream, tag, type, cur_second, JVMCI_CHECK);
    }

    if (isLongArray && cur_second == nullptr) {
      // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations.
      // add an int 0 constant
      cur_second = _int_0_scope_value;
    }

    if (isByteArray && cur_second != nullptr && (type == T_DOUBLE || type == T_LONG)) {
      // we are trying to write a long in a byte Array. We will need to count the illegals to restore the type of
      // the thing we put inside.
      cur_second = nullptr;
    }

    if (cur_second != nullptr) {
      sv->field_values()->append(cur_second);
    }
    assert(value != nullptr, "missing value");
    sv->field_values()->append(value);
  }
}

GrowableArray<ScopeValue*>* CodeInstaller::read_local_or_stack_values(HotSpotCompiledCodeStream* stream, u1 frame_flags, bool is_locals, JVMCI_TRAPS) {
  u2 length;
  if (is_locals) {
    if (!is_set(frame_flags, DIF_HAS_LOCALS)) {
      return nullptr;
    }
    length = stream->read_u2("numLocals");
  } else {
    if (!is_set(frame_flags, DIF_HAS_STACK)) {
      return nullptr;
    }
    length = stream->read_u2("numStack");
  }
  GrowableArray<ScopeValue*>* values = new GrowableArray<ScopeValue*> (length);
  for (int i = 0; i < length; i++) {
    ScopeValue* second = nullptr;
    BasicType type = (BasicType) stream->read_u1("basicType");
    u1 tag = stream->read_u1("tag");
    ScopeValue* first = get_scope_value(stream, tag, type, second, JVMCI_CHECK_NULL);
    if (second != nullptr) {
      if (i == length) {
        JVMCI_ERROR_NULL("double-slot value not followed by Value.ILLEGAL%s", stream->context());
      }
      i++;
      stream->read_u1("basicType");
      tag = stream->read_u1("tag");
      if (tag != ILLEGAL) {
        JVMCI_ERROR_NULL("double-slot value not followed by Value.ILLEGAL%s", stream->context());
      }
      values->append(second);
    }
    values->append(first);
  }
  return values;
}

GrowableArray<MonitorValue*>* CodeInstaller::read_monitor_values(HotSpotCompiledCodeStream* stream, u1 frame_flags, JVMCI_TRAPS) {
  if (!is_set(frame_flags, DIF_HAS_LOCKS)) {
    return nullptr;
  }
  if (!_has_monitors) {
    _has_monitors = true;
  }
  u2 length = stream->read_u2("numLocks");
  GrowableArray<MonitorValue*>* monitors = new GrowableArray<MonitorValue*>(length);
  for (int i = 0; i < length; i++) {
    bool eliminated = stream->read_bool("isEliminated");
    ScopeValue* second = nullptr;
    ScopeValue* owner_value = get_scope_value(stream, stream->read_u1("tag"), T_OBJECT, second, JVMCI_CHECK_NULL);
    assert(second == nullptr, "monitor cannot occupy two stack slots");

    ScopeValue* lock_data_value = get_scope_value(stream, stream->read_u1("tag"), T_LONG, second, JVMCI_CHECK_NULL);
    assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots");
    assert(lock_data_value->is_location(), "invalid monitor location");
    Location lock_data_loc = ((LocationValue*) lock_data_value)->location();

    monitors->append(new MonitorValue(owner_value, lock_data_loc, eliminated));
  }
  return monitors;
}

void CodeInstaller::initialize_dependencies(HotSpotCompiledCodeStream* stream, u1 code_flags, OopRecorder* oop_recorder, JVMCI_TRAPS) {
  JavaThread* thread = stream->thread();
  CompilerThread* compilerThread = thread->is_Compiler_thread() ? CompilerThread::cast(thread) : nullptr;
  _oop_recorder = oop_recorder;
  _dependencies = new Dependencies(&_arena, _oop_recorder, compilerThread != nullptr ? compilerThread->log() : nullptr);
  if (is_set(code_flags, HCC_HAS_ASSUMPTIONS)) {
    u2 length = stream->read_u2("assumptions:length");
    for (int i = 0; i < length; ++i) {
      u1 tag = stream->read_u1("tag");
      switch (tag) {
        case NO_FINALIZABLE_SUBCLASS: {
          Klass* receiver_type = stream->read_klass("receiverType");
          _dependencies->assert_has_no_finalizable_subclasses(receiver_type);
          break;
        }
        case CONCRETE_SUBTYPE: {
          Klass* context = stream->read_klass("context");
          Klass* subtype = stream->read_klass("subtype");
          assert(context->is_abstract(), "must be");
          _dependencies->assert_abstract_with_unique_concrete_subtype(context, subtype);
          break;
        }
        case LEAF_TYPE: {
          Klass* context = stream->read_klass("context");
          _dependencies->assert_leaf_type(context);
          break;
        }
        case CONCRETE_METHOD: {
          Klass* context = stream->read_klass("context");
          Method* impl = stream->read_method("impl");
          _dependencies->assert_unique_concrete_method(context, impl);
          break;
        }
        case CALLSITE_TARGET_VALUE: {
          u1 obj_tag = stream->read_u1("tag");
          Handle callSite = read_oop(stream, obj_tag, JVMCI_CHECK);
          obj_tag = stream->read_u1("tag");
          Handle methodHandle = read_oop(stream, obj_tag, JVMCI_CHECK);
          _dependencies->assert_call_site_target_value(callSite(), methodHandle());
          break;
        }
        default: {
          JVMCI_ERROR("unexpected assumption tag %d%s", tag, stream->context());
        }
      }
    }
  }
  if (is_set(code_flags, HCC_HAS_METHODS)) {
    u2 length = stream->read_u2("methods:length");
    for (int i = 0; i < length; ++i) {
      Method* method = stream->read_method("method");
      if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
        _dependencies->assert_evol_method(method);
      }
    }
  }
}

JVMCI::CodeInstallResult CodeInstaller::install_runtime_stub(CodeBlob*& cb,
                                                             const char* name,
                                                             CodeBuffer* buffer,
                                                             int stack_slots,
                                                             JVMCI_TRAPS) {
  if (name == nullptr) {
    JVMCI_ERROR_OK("stub should have a name");
  }

  name = os::strdup(name);
  GrowableArray<RuntimeStub*> *stubs_to_free = nullptr;
#ifdef ASSERT
  const char* val = Arguments::PropertyList_get_value(Arguments::system_properties(), "test.jvmci.forceRuntimeStubAllocFail");
  if (val != nullptr && strstr(name , val) != nullptr) {
    stubs_to_free = new GrowableArray<RuntimeStub*>();
    JVMCI_event_1("forcing allocation of %s in code cache to fail", name);
  }
#endif

  do {
    RuntimeStub* stub = RuntimeStub::new_runtime_stub(name,
                                       buffer,
                                       _offsets.value(CodeOffsets::Frame_Complete),
                                       stack_slots,
                                       _debug_recorder->_oopmaps,
                                       /* caller_must_gc_arguments */ false,
                                       /* alloc_fail_is_fatal */ false);
    cb = stub;
    if (stub == nullptr) {
      // Allocation failed
#ifdef ASSERT
      if (stubs_to_free != nullptr) {
        JVMCI_event_1("allocation of %s in code cache failed, freeing %d stubs", name, stubs_to_free->length());
        for (GrowableArrayIterator<RuntimeStub*> iter = stubs_to_free->begin(); iter != stubs_to_free->end(); ++iter) {
          RuntimeStub::free(*iter);
        }
      }
#endif
      return JVMCI::cache_full;
    }
    if (stubs_to_free == nullptr) {
      return JVMCI::ok;
    }
    stubs_to_free->append(stub);
  } while (true);
}

JVMCI::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler,
    jlong compiled_code_buffer,
    bool with_type_info,
    JVMCIObject compiled_code,
    objArrayHandle object_pool,
    CodeBlob*& cb,
    JVMCINMethodHandle& nmethod_handle,
    JVMCIObject installed_code,
    FailedSpeculation** failed_speculations,
    char* speculations,
    int speculations_len,
    JVMCI_TRAPS) {

  JavaThread* thread = JavaThread::current();
  HotSpotCompiledCodeStream* stream = new HotSpotCompiledCodeStream(thread, (const u1*) compiled_code_buffer, with_type_info, object_pool);

  u1 code_flags = stream->read_u1("code:flags");
  bool is_nmethod = is_set(code_flags, HCC_IS_NMETHOD);
  const char* name = stream->read_utf8("name", JVMCI_CHECK_OK);

  methodHandle method;
  jint entry_bci = -1;
  JVMCICompileState* compile_state = nullptr;
  bool has_unsafe_access = false;
  bool has_scoped_access = false;
  jint id = -1;

  if (is_nmethod) {
    method = methodHandle(thread, stream->read_method("method"));
    entry_bci = is_nmethod ? stream->read_s4("entryBCI") : -1;
    compile_state = (JVMCICompileState*) stream->read_u8("compileState");
    has_unsafe_access = stream->read_bool("hasUnsafeAccess");
    has_scoped_access = stream->read_bool("hasScopedAccess");
    id = stream->read_s4("id");
  }
  stream->set_code_desc(name, method);

  CodeBuffer buffer("JVMCI Compiler CodeBuffer");
  OopRecorder* recorder = new OopRecorder(&_arena, true);
  initialize_dependencies(stream, code_flags, recorder, JVMCI_CHECK_OK);

  // Get instructions and constants CodeSections early because we need it.
  _instructions = buffer.insts();
  _constants = buffer.consts();

  initialize_fields(stream, code_flags, method, buffer, JVMCI_CHECK_OK);
  JVMCI::CodeInstallResult result = initialize_buffer(compiled_code, buffer, stream, code_flags, JVMCI_CHECK_OK);

  u4 available = stream->available();
  if (result == JVMCI::ok && available != 0) {
    JVMCI_ERROR_OK("%d bytes remaining in stream%s", available, stream->context());
  }

  if (result != JVMCI::ok) {
    return result;
  }

  int stack_slots = _total_frame_size / HeapWordSize; // conversion to words

  if (!is_nmethod) {
    return install_runtime_stub(cb, name, &buffer, stack_slots, JVMCI_CHECK_OK);
  } else {
    if (compile_state != nullptr) {
      jvmci_env()->set_compile_state(compile_state);
    }

    if (id == -1) {
      // Make sure a valid compile_id is associated with every compile
      id = CompileBroker::assign_compile_id_unlocked(thread, method, entry_bci);
      jvmci_env()->set_HotSpotCompiledNmethod_id(compiled_code, id);
    }
    if (!jvmci_env()->isa_HotSpotNmethod(installed_code)) {
      JVMCI_THROW_MSG_(IllegalArgumentException, "InstalledCode object must be a HotSpotNmethod when installing a HotSpotCompiledNmethod", JVMCI::ok);
    }

    // Enforce that compiled methods have an nmethod barrier.
    if (_nmethod_entry_patch_offset == -1) {
      JVMCI_THROW_MSG_(IllegalArgumentException, "nmethod entry barrier is missing", JVMCI::ok);
    }

    JVMCIObject mirror = installed_code;
    nmethod* nm = nullptr; // nm is an out parameter of register_method
    result = runtime()->register_method(jvmci_env(),
                                        method,
                                        nm,
                                        entry_bci,
                                        &_offsets,
                                        _orig_pc_offset,
                                        &buffer,
                                        stack_slots,
                                        _debug_recorder->_oopmaps,
                                        &_exception_handler_table,
                                        &_implicit_exception_table,
                                        compiler,
                                        _debug_recorder,
                                        _dependencies,
                                        id,
                                        _has_monitors,
                                        has_unsafe_access,
                                        has_scoped_access,
                                        _has_wide_vector,
                                        compiled_code,
                                        mirror,
                                        failed_speculations,
                                        speculations,
                                        speculations_len,
                                        _nmethod_entry_patch_offset);
    if (result == JVMCI::ok) {
      guarantee(nm != nullptr, "successful compile must produce an nmethod");
      nmethod_handle.set_nmethod(nm);
      cb = nm;
      if (compile_state == nullptr) {
        // This compile didn't come through the CompileBroker so perform the printing here
        DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler);
        nm->maybe_print_nmethod(directive);
        DirectivesStack::release(directive);

        // Since this compilation didn't pass through the broker it wasn't logged yet.
        if (PrintCompilation) {
          ttyLocker ttyl;
          if (name != nullptr) {
            stringStream st;
            st.print_cr("(hosted JVMCI compilation: %s)", name);
            CompileTask::print(tty, nm, st.as_string());
          } else {
            CompileTask::print(tty, nm, "(hosted JVMCI compilation)");
          }
        }
      }

      BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();

      // an empty error buffer for use by the verify_barrier code
      err_msg msg("");
      if (!bs_nm->verify_barrier(nm, msg)) {
        JVMCI_THROW_MSG_(IllegalArgumentException, err_msg("nmethod entry barrier is malformed: %s", msg.buffer()), JVMCI::ok);
      }
    }
  }

  if (cb != nullptr) {
    // Make sure the pre-calculated constants section size was correct.
    guarantee((cb->code_begin() - cb->content_begin()) >= _constants_size, "%d < %d", (int)(cb->code_begin() - cb->content_begin()), _constants_size);
  }
  return result;
}

void CodeInstaller::initialize_fields(HotSpotCompiledCodeStream* stream, u1 code_flags, methodHandle& method, CodeBuffer& buffer, JVMCI_TRAPS) {
  if (!method.is_null()) {
    _parameter_count = method->size_of_parameters();
    JVMCI_event_2("installing code for %s", method->name_and_sig_as_C_string());
  } else {
    // Must be a HotSpotCompiledCode for a stub.
    // Only used in OopMap constructor for non-product builds
    _parameter_count = 0;
  }
  _sites_count = stream->read_s4("sites:length");
  _code_size = stream->read_s4("targetCodeSize");
  _total_frame_size = stream->read_s4("totalFrameSize");
  if (!is_set(code_flags, HCC_HAS_DEOPT_RESCUE_SLOT)) {
    _orig_pc_offset = -1;
  } else {
    _orig_pc_offset = stream->read_s4("offset");
    if (stream->read_bool("addRawFrameSize")) {
      _orig_pc_offset += _total_frame_size;
    }
    if (_orig_pc_offset < 0) {
      JVMCI_ERROR("invalid deopt rescue slot: %d%s", _orig_pc_offset, stream->context());
    }
  }

  // Pre-calculate the constants section size.  This is required for PC-relative addressing.
  u4 data_section_size = stream->read_u4("dataSectionSize");
  u1 data_section_alignment = stream->read_u1("dataSectionAlignment");
  buffer.set_const_section_alignment(data_section_alignment);
  if ((_constants->alignment() % data_section_alignment) != 0) {
    JVMCI_ERROR("invalid data section alignment: %d [constants alignment: %d]%s",
        data_section_alignment, _constants->alignment(), stream->context());
  }
  _constants_size = data_section_size;
  _next_call_type = INVOKE_INVALID;
  _has_monitors = false;
  _has_wide_vector = false;
  _nmethod_entry_patch_offset = -1;
}

u1 CodeInstaller::as_read_oop_tag(HotSpotCompiledCodeStream* stream, u1 patch_object_tag, JVMCI_TRAPS) {
  switch (patch_object_tag) {
    case PATCH_OBJECT_ID:
    case PATCH_NARROW_OBJECT_ID: {
      return OBJECT_ID;
    }
    case PATCH_OBJECT_ID2:
    case PATCH_NARROW_OBJECT_ID2: {
      return OBJECT_ID2;
    }
    case PATCH_NARROW_JOBJECT:
    case PATCH_JOBJECT: {
      return JOBJECT;
    }
    default: {
      JVMCI_ERROR_0("unknown object patch tag: %d%s", patch_object_tag, stream->context());
    }
  }
}

int CodeInstaller::estimate_stubs_size(HotSpotCompiledCodeStream* stream, JVMCI_TRAPS) {
  // Estimate the number of static call stubs that might be emitted.
  u2 static_call_stubs = stream->read_u2("numStaticCallStubs");
  u2 trampoline_stubs = stream->read_u2("numTrampolineStubs");
  int size = static_call_stubs * CompiledDirectCall::to_interp_stub_size();
  size += trampoline_stubs * CompiledDirectCall::to_trampoline_stub_size();
  return size;
}

// perform data and call relocation on the CodeBuffer
JVMCI::CodeInstallResult CodeInstaller::initialize_buffer(JVMCIObject compiled_code, CodeBuffer& buffer, HotSpotCompiledCodeStream* stream, u1 code_flags, JVMCI_TRAPS) {
  JavaThread* thread = stream->thread();
  HandleMark hm(thread);
  int locs_buffer_size = _sites_count * (relocInfo::length_limit + sizeof(relocInfo));


  // Allocate enough space in the stub section for the static call
  // stubs.  Stubs have extra relocs but they are managed by the stub
  // section itself so they don't need to be accounted for in the
  // locs_buffer above.
  int stubs_size = estimate_stubs_size(stream, JVMCI_CHECK_OK);

  assert((CodeBuffer::SECT_INSTS == CodeBuffer::SECT_STUBS - 1) &&
         (CodeBuffer::SECT_CONSTS == CodeBuffer::SECT_INSTS - 1), "sections order: consts, insts, stubs");
  // buffer content: [constants + code_align] + [code + stubs_align] + [stubs]
  int total_size = align_up(_constants_size, buffer.insts()->alignment()) +
                   align_up(_code_size, buffer.stubs()->alignment()) +
                   stubs_size;

  if (total_size > JVMCINMethodSizeLimit) {
    return JVMCI::code_too_large;
  }

  buffer.initialize(total_size, locs_buffer_size);
  if (buffer.blob() == nullptr) {
    return JVMCI::cache_full;
  }
  buffer.initialize_stubs_size(stubs_size);
  buffer.initialize_consts_size(_constants_size);

  _debug_recorder = new DebugInformationRecorder(_oop_recorder);
  _debug_recorder->set_oopmaps(new OopMapSet());

  buffer.initialize_oop_recorder(_oop_recorder);

  // copy the constant data into the newly created CodeBuffer
  address end_data = _constants->start() + _constants_size;
  JVMCIObject data_section = jvmci_env()->get_HotSpotCompiledCode_dataSection(compiled_code);
  JVMCIENV->copy_bytes_to(data_section, (jbyte*) _constants->start(), 0, _constants_size);
  _constants->set_end(end_data);

  // copy the code into the newly created CodeBuffer
  address end_pc = _instructions->start() + _code_size;
  guarantee(_instructions->allocates2(end_pc), "initialize should have reserved enough space for all the code");

  JVMCIPrimitiveArray code = jvmci_env()->get_HotSpotCompiledCode_targetCode(compiled_code);
  JVMCIENV->copy_bytes_to(code, (jbyte*) _instructions->start(), 0, _code_size);
  _instructions->set_end(end_pc);


  u2 length = stream->read_u2("dataSectionPatches:length");
  for (int i = 0; i < length; i++) {
    address dest = _constants->start() + stream->read_u4("patch:pcOffset");
    u1 tag = stream->read_u1("tag");

    switch (tag) {
      case PATCH_METHOD:
      case PATCH_KLASS: {
        *((void**) dest) = record_metadata_reference(_constants, dest, stream, tag, JVMCI_CHECK_OK);
        break;
      }
      case PATCH_NARROW_KLASS: {
#ifdef _LP64
        *((narrowKlass*) dest) = record_narrow_metadata_reference(_constants, dest, stream, tag, JVMCI_CHECK_OK);
#else
        JVMCI_ERROR_OK("unexpected compressed Klass* in 32-bit mode");
#endif
        break;
      }
      case PATCH_OBJECT_ID:
      case PATCH_OBJECT_ID2:
      case PATCH_NARROW_OBJECT_ID:
      case PATCH_NARROW_OBJECT_ID2:
      case PATCH_JOBJECT:
      case PATCH_NARROW_JOBJECT: {
        bool narrow = tag == PATCH_NARROW_OBJECT_ID || tag == PATCH_NARROW_OBJECT_ID2  || tag == PATCH_NARROW_JOBJECT;
        u1 read_tag = as_read_oop_tag(stream, tag, JVMCI_CHECK_OK);
        record_oop_patch(stream, dest, read_tag, narrow, JVMCI_CHECK_OK);
        break;
      }
      default: {
        JVMCI_ERROR_OK("invalid constant tag: %d%s", tag, stream->context());
        break;
      }
    }
  }

  jint last_pc_offset = -1;
  for (int i = 0; i < _sites_count; i++) {
    u4 pc_offset = stream->read_s4("site:pcOffset");
    u1 tag = stream->read_u1("tag");
    switch (tag) {
      case SITE_FOREIGN_CALL:
      case SITE_FOREIGN_CALL_NO_DEBUG_INFO:
      case SITE_CALL: {
        site_Call(buffer, tag, pc_offset, stream, JVMCI_CHECK_OK);
        break;
      }
      case SITE_SAFEPOINT:
      case SITE_IMPLICIT_EXCEPTION:
      case SITE_IMPLICIT_EXCEPTION_DISPATCH: {
        site_Safepoint(buffer, pc_offset, stream, tag, JVMCI_CHECK_OK);
        break;
      }
      case SITE_INFOPOINT: {
        site_Infopoint(buffer, pc_offset, stream, JVMCI_CHECK_OK);
        break;
      }
      case SITE_MARK: {
        site_Mark(buffer, pc_offset, stream, JVMCI_CHECK_OK);
        break;
      }
      case SITE_DATA_PATCH: {
        site_DataPatch(buffer, pc_offset, stream, JVMCI_CHECK_OK);
        break;
      }
      case SITE_EXCEPTION_HANDLER: {
        site_ExceptionHandler(pc_offset, stream);
        break;
      }
      default: {
        JVMCI_ERROR_OK("unexpected site tag at " INTPTR_FORMAT ": %d", p2i(stream->pos() - 1), tag);
      }
    }

    last_pc_offset = pc_offset;

    if ((i % 32 == 0) && SafepointMechanism::should_process(thread)) {
      // Force a safepoint to mitigate pause time installing large code
      ThreadToNativeFromVM ttnfv(thread);
    }
  }

  if (is_set(code_flags, HCC_HAS_COMMENTS)) {
    u2 length = stream->read_u2("comments:length");
    for (int i = 0; i < length; i++) {
      u4 pc_offset = stream->read_u4("comment:pcOffset");
      const char* text = stream->read_utf8("comment:text", JVMCI_CHECK_OK);
#ifndef PRODUCT
      buffer.block_comment(pc_offset, text);
#endif
    }
  }
  if (_has_auto_box) {
    JavaThread* THREAD = thread; // For exception macros.
    JVMCI::ensure_box_caches_initialized(CHECK_(JVMCI::ok));
  }
  return JVMCI::ok;
}

void CodeInstaller::record_oop_patch(HotSpotCompiledCodeStream* stream, address dest, u1 read_tag, bool narrow, JVMCI_TRAPS) {
  Handle obj = read_oop(stream, read_tag, JVMCI_CHECK);
  jobject value = JNIHandles::make_local(obj());
  int oop_index = _oop_recorder->find_index(value);
  if (narrow) {
#ifdef _LP64
    _constants->relocate(dest, oop_Relocation::spec(oop_index), relocInfo::narrow_oop_in_const);
#else
    JVMCI_ERROR("unexpected compressed oop in 32-bit mode");
#endif
  } else {
    _constants->relocate(dest, oop_Relocation::spec(oop_index));
  }
}

void CodeInstaller::site_ExceptionHandler(jint pc_offset, HotSpotCompiledCodeStream* stream) {
  u4 handler_offset = stream->read_u4("site:handlerPos");

  // Subtable header
  _exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0));

  // Subtable entry
  _exception_handler_table.add_entry(HandlerTableEntry(-1, handler_offset, 0));
}

void CodeInstaller::read_virtual_objects(HotSpotCompiledCodeStream* stream, JVMCI_TRAPS) {
  u2 length = stream->read_u2("virtualObjects:length");
  if (length == 0) {
    return;
  }
  GrowableArray<ScopeValue*> *objects = new GrowableArray<ScopeValue*>(length, length, nullptr);
  stream->set_virtual_objects(objects);
  // Create the unique ObjectValues
  JavaThread* thread = stream->thread();
  for (int id = 0; id < length; id++) {
    Klass* klass = stream->read_klass("type");
    bool is_auto_box = stream->read_bool("isAutoBox");
    if (is_auto_box) {
      _has_auto_box = true;
    }
    oop javaMirror = klass->java_mirror();
    ScopeValue *klass_sv = new ConstantOopWriteValue(JNIHandles::make_local(javaMirror));
    ObjectValue* sv = is_auto_box ? new AutoBoxObjectValue(id, klass_sv) : new ObjectValue(id, klass_sv);
    objects->at_put(id, sv);
  }
  // All the values which could be referenced by the VirtualObjects
  // exist, so now describe all the VirtualObjects themselves.
  for (int id = 0; id < length; id++) {
    record_object_value(objects->at(id)->as_ObjectValue(), stream, JVMCI_CHECK);
  }
  _debug_recorder->dump_object_pool(objects);

  stream->set_virtual_objects(objects);
}

int CodeInstaller::map_jvmci_bci(int bci) {
  if (bci < 0) {
    switch (bci) {
      case BEFORE_BCI: return BeforeBci;
      case AFTER_BCI: return AfterBci;
      case UNWIND_BCI: return UnwindBci;
      case AFTER_EXCEPTION_BCI: return AfterExceptionBci;
      case UNKNOWN_BCI: return UnknownBci;
      case INVALID_FRAMESTATE_BCI: return InvalidFrameStateBci;
    }
    ShouldNotReachHere();
  }
  return bci;
}

void CodeInstaller::record_scope(jint pc_offset, HotSpotCompiledCodeStream* stream, u1 debug_info_flags, bool full_info, bool is_mh_invoke, bool return_oop, JVMCI_TRAPS) {
  if (full_info) {
    read_virtual_objects(stream, JVMCI_CHECK);
  }
  if (is_set(debug_info_flags, DI_HAS_FRAMES)) {
    u2 depth = stream->read_u2("depth");
    for (int i = 0; i < depth; i++) {
      Thread* thread = Thread::current();
      methodHandle method(thread, stream->read_method("method"));
      jint bci = map_jvmci_bci(stream->read_s4("bci"));
      if (bci == BEFORE_BCI) {
        bci = SynchronizationEntryBCI;
      }

      JVMCI_event_2("Recording scope pc_offset=%d bci=%d method=%s", pc_offset, bci, method->name_and_sig_as_C_string());

      bool reexecute = false;
      bool rethrow_exception = false;

      DebugToken* locals_token = nullptr;
      DebugToken* stack_token = nullptr;
      DebugToken* monitors_token = nullptr;

      if (full_info) {
        u1 frame_flags = stream->read_u1("flags");
        rethrow_exception = is_set(frame_flags, DIF_RETHROW_EXCEPTION);

        if (bci >= 0) {
          reexecute = !is_set(frame_flags, DIF_DURING_CALL);
        }

        GrowableArray<ScopeValue*>* locals = read_local_or_stack_values(stream, frame_flags, true, JVMCI_CHECK);
        GrowableArray<ScopeValue*>* stack = read_local_or_stack_values(stream, frame_flags, false, JVMCI_CHECK);
        GrowableArray<MonitorValue*>* monitors = read_monitor_values(stream, frame_flags, JVMCI_CHECK);

        locals_token = _debug_recorder->create_scope_values(locals);
        stack_token = _debug_recorder->create_scope_values(stack);
        monitors_token = _debug_recorder->create_monitor_values(monitors);
      }

      // has_ea_local_in_scope and arg_escape should be added to JVMCI
      const bool has_ea_local_in_scope = false;
      const bool arg_escape            = false;
      _debug_recorder->describe_scope(pc_offset, method, nullptr, bci, reexecute, rethrow_exception, is_mh_invoke, return_oop,
                                      has_ea_local_in_scope, arg_escape,
                                      locals_token, stack_token, monitors_token);
    }
  }
  if (full_info) {
    // Clear the virtual objects as they are specific to one DebugInfo
    stream->set_virtual_objects(nullptr);
  }
}

void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, HotSpotCompiledCodeStream* stream, u1 tag, JVMCI_TRAPS) {
  u1 flags = stream->read_u1("debugInfo:flags");
  OopMap *map = create_oop_map(stream, flags, JVMCI_CHECK);
  _debug_recorder->add_safepoint(pc_offset, map);
  record_scope(pc_offset, stream, flags, true, JVMCI_CHECK);
  _debug_recorder->end_safepoint(pc_offset);
  if (_orig_pc_offset < 0) {
    JVMCI_ERROR("method contains safepoint, but has no deopt rescue slot");
  }
  if (tag == SITE_IMPLICIT_EXCEPTION_DISPATCH) {
    jint dispatch_offset = stream->read_s4("dispatchOffset");
    _implicit_exception_table.append(pc_offset, dispatch_offset);
  } else if (tag == SITE_IMPLICIT_EXCEPTION) {
    _implicit_exception_table.add_deoptimize(pc_offset);
  }
}

void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, HotSpotCompiledCodeStream* stream, JVMCI_TRAPS) {
  u1 flags = stream->read_u1("debugInfo:flags");
  _debug_recorder->add_non_safepoint(pc_offset);
  record_scope(pc_offset, stream, flags, false, JVMCI_CHECK);
  _debug_recorder->end_non_safepoint(pc_offset);
}

void CodeInstaller::site_Call(CodeBuffer& buffer, u1 tag, jint pc_offset, HotSpotCompiledCodeStream* stream, JVMCI_TRAPS) {
  JavaThread* thread = stream->thread();
  jlong target = stream->read_u8("target");
  methodHandle method;
  bool direct_call = false;
  if (tag == SITE_CALL) {
    method = methodHandle(thread, (Method*) target);
    assert(Method::is_valid_method(method()), "invalid method");
    direct_call = stream->read_bool("direct");
    if (method.is_null()) {
      JVMCI_THROW(NullPointerException);
    }
  }

  NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
  jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, JVMCI_CHECK);

  if (tag != SITE_FOREIGN_CALL_NO_DEBUG_INFO) {
    u1 flags = stream->read_u1("debugInfo:flags");
    OopMap *map = create_oop_map(stream, flags, JVMCI_CHECK);
    _debug_recorder->add_safepoint(next_pc_offset, map);

    if (!method.is_null()) {
      vmIntrinsics::ID iid = method->intrinsic_id();
      bool is_mh_invoke = false;
      if (direct_call) {
        is_mh_invoke = !method->is_static() && (iid == vmIntrinsics::_compiledLambdaForm ||
                (MethodHandles::is_signature_polymorphic(iid) && MethodHandles::is_signature_polymorphic_intrinsic(iid)));
      }
      bool return_oop = method->is_returning_oop();
      record_scope(next_pc_offset, stream, flags, true, is_mh_invoke, return_oop, JVMCI_CHECK);
    } else {
      record_scope(next_pc_offset, stream, flags, true, JVMCI_CHECK);
    }
  }

  if (tag != SITE_CALL) {
    jlong foreign_call_destination = target;
    CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination, JVMCI_CHECK);
  } else {
    CodeInstaller::pd_relocate_JavaMethod(buffer, method, pc_offset, JVMCI_CHECK);
    if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) {
      // Need a static call stub for transitions from compiled to interpreted.
      MacroAssembler masm(&buffer);
      if (CompiledDirectCall::emit_to_interp_stub(&masm, _instructions->start() + pc_offset) == nullptr) {
        JVMCI_ERROR("could not emit to_interp stub - code cache is full");
      }
    }
  }

  _next_call_type = INVOKE_INVALID;

  if (tag != SITE_FOREIGN_CALL_NO_DEBUG_INFO) {
    _debug_recorder->end_safepoint(next_pc_offset);
  }
}

void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, HotSpotCompiledCodeStream* stream, JVMCI_TRAPS) {
  u1 tag = stream->read_u1("tag");
  switch (tag) {
    case PATCH_OBJECT_ID:
    case PATCH_OBJECT_ID2:
    case PATCH_NARROW_OBJECT_ID:
    case PATCH_NARROW_OBJECT_ID2:
    case PATCH_JOBJECT:
    case PATCH_NARROW_JOBJECT: {
      bool narrow = tag == PATCH_NARROW_OBJECT_ID || tag == PATCH_NARROW_OBJECT_ID2  || tag == PATCH_NARROW_JOBJECT;
      u1 read_tag = as_read_oop_tag(stream, tag, JVMCI_CHECK);
      Handle obj = read_oop(stream, read_tag, JVMCI_CHECK);
      pd_patch_OopConstant(pc_offset, obj, narrow, JVMCI_CHECK);
      break;
    }
    case PATCH_METHOD:
    case PATCH_KLASS:
    case PATCH_NARROW_KLASS: {
      pd_patch_MetaspaceConstant(pc_offset, stream, tag, JVMCI_CHECK);
      break;
    }
    case PATCH_DATA_SECTION_REFERENCE: {
      int data_offset = stream->read_u4("data:offset");
      if (0 <= data_offset && data_offset < _constants_size) {
        if (!is_aligned(data_offset, CompilerToVM::Data::get_data_section_item_alignment())) {
          JVMCI_ERROR("data offset 0x%x is not %d-byte aligned%s", data_offset, relocInfo::addr_unit(), stream->context());
        }
        pd_patch_DataSectionReference(pc_offset, data_offset, JVMCI_CHECK);
      } else {
        JVMCI_ERROR("data offset 0x%x points outside data section (size 0x%x)%s", data_offset, _constants_size, stream->context());
      }
      break;
    }
    default: {
      JVMCI_ERROR("unknown data patch tag: %d%s", tag, stream->context());
    }
  }
}

void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, HotSpotCompiledCodeStream* stream, JVMCI_TRAPS) {
  u1 id = stream->read_u1("mark:id");
  address pc = _instructions->start() + pc_offset;

  if (pd_relocate(pc, id)) {
    return;
  }

  switch (id) {
    case UNVERIFIED_ENTRY:
      _offsets.set_value(CodeOffsets::Entry, pc_offset);
      break;
    case VERIFIED_ENTRY:
      _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset);
      break;
    case OSR_ENTRY:
      _offsets.set_value(CodeOffsets::OSR_Entry, pc_offset);
      break;
    case EXCEPTION_HANDLER_ENTRY:
      _offsets.set_value(CodeOffsets::Exceptions, pc_offset);
      break;
    case DEOPT_HANDLER_ENTRY:
      _offsets.set_value(CodeOffsets::Deopt, pc_offset);
      break;
    case DEOPT_MH_HANDLER_ENTRY:
      _offsets.set_value(CodeOffsets::DeoptMH, pc_offset);
      break;
    case FRAME_COMPLETE:
      _offsets.set_value(CodeOffsets::Frame_Complete, pc_offset);
      break;
    case ENTRY_BARRIER_PATCH:
      _nmethod_entry_patch_offset = pc_offset;
      break;
    case INVOKEVIRTUAL:
    case INVOKEINTERFACE:
    case INLINE_INVOKE:
    case INVOKESTATIC:
    case INVOKESPECIAL:
      _next_call_type = (MarkId) id;
      _invoke_mark_pc = pc;
      break;
    case CARD_TABLE_SHIFT:
    case CARD_TABLE_ADDRESS:
    case HEAP_TOP_ADDRESS:
    case HEAP_END_ADDRESS:
    case NARROW_KLASS_BASE_ADDRESS:
    case NARROW_OOP_BASE_ADDRESS:
    case CRC_TABLE_ADDRESS:
    case LOG_OF_HEAP_REGION_GRAIN_BYTES:
    case INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED:
    case VERIFY_OOPS:
    case VERIFY_OOP_BITS:
    case VERIFY_OOP_MASK:
    case VERIFY_OOP_COUNT_ADDRESS:
      break;

    default:
      JVMCI_ERROR("invalid mark id: %d%s", id, stream->context());
      break;
  }
}
