Path: blob/master/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp
40949 views
/*1* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include "precompiled.hpp"24#include "classfile/javaClasses.inline.hpp"25#include "code/compiledIC.hpp"26#include "compiler/compileBroker.hpp"27#include "compiler/compilerThread.hpp"28#include "compiler/oopMap.hpp"29#include "jvmci/jvmciCodeInstaller.hpp"30#include "jvmci/jvmciCompilerToVM.hpp"31#include "jvmci/jvmciRuntime.hpp"32#include "memory/universe.hpp"33#include "oops/compressedOops.inline.hpp"34#include "oops/klass.inline.hpp"35#include "prims/jvmtiExport.hpp"36#include "prims/methodHandles.hpp"37#include "runtime/interfaceSupport.inline.hpp"38#include "runtime/jniHandles.inline.hpp"39#include "runtime/sharedRuntime.hpp"40#include "utilities/align.hpp"4142// frequently used constants43// Allocate them with new so they are never destroyed (otherwise, a44// forced exit could destroy these objects while they are still in45// use).46ConstantOopWriteValue* CodeInstaller::_oop_null_scope_value = new (ResourceObj::C_HEAP, mtJVMCI) ConstantOopWriteValue(NULL);47ConstantIntValue* CodeInstaller::_int_m1_scope_value = new (ResourceObj::C_HEAP, mtJVMCI) ConstantIntValue(-1);48ConstantIntValue* CodeInstaller::_int_0_scope_value = new (ResourceObj::C_HEAP, mtJVMCI) ConstantIntValue((jint)0);49ConstantIntValue* CodeInstaller::_int_1_scope_value = new (ResourceObj::C_HEAP, mtJVMCI) ConstantIntValue(1);50ConstantIntValue* CodeInstaller::_int_2_scope_value = new (ResourceObj::C_HEAP, mtJVMCI) ConstantIntValue(2);51LocationValue* CodeInstaller::_illegal_value = new (ResourceObj::C_HEAP, mtJVMCI) LocationValue(Location());52MarkerValue* CodeInstaller::_virtual_byte_array_marker = new (ResourceObj::C_HEAP, mtJVMCI) MarkerValue();5354VMReg CodeInstaller::getVMRegFromLocation(JVMCIObject location, int total_frame_size, JVMCI_TRAPS) {55if (location.is_null()) {56JVMCI_THROW_NULL(NullPointerException);57}5859JVMCIObject reg = jvmci_env()->get_code_Location_reg(location);60jint offset = jvmci_env()->get_code_Location_offset(location);6162if (reg.is_non_null()) {63// register64jint number = jvmci_env()->get_code_Register_number(reg);65VMReg vmReg = CodeInstaller::get_hotspot_reg(number, JVMCI_CHECK_NULL);66if (offset % 4 == 0) {67return vmReg->next(offset / 4);68} else {69JVMCI_ERROR_NULL("unaligned subregister offset %d in oop map", offset);70}71} else {72// stack slot73if (offset % 4 == 0) {74VMReg vmReg = VMRegImpl::stack2reg(offset / 4);75if (!OopMapValue::legal_vm_reg_name(vmReg)) {76// This restriction only applies to VMRegs that are used in OopMap but77// since that's the only use of VMRegs it's simplest to put this test78// here. This test should also be equivalent legal_vm_reg_name but JVMCI79// clients can use max_oop_map_stack_stack_offset to detect this problem80// directly. The asserts just ensure that the tests are in agreement.81assert(offset > CompilerToVM::Data::max_oop_map_stack_offset(), "illegal VMReg");82JVMCI_ERROR_NULL("stack offset %d is too large to be encoded in OopMap (max %d)",83offset, CompilerToVM::Data::max_oop_map_stack_offset());84}85assert(OopMapValue::legal_vm_reg_name(vmReg), "illegal VMReg");86return vmReg;87} else {88JVMCI_ERROR_NULL("unaligned stack offset %d in oop map", offset);89}90}91}9293// creates a HotSpot oop map out of the byte arrays provided by DebugInfo94OopMap* CodeInstaller::create_oop_map(JVMCIObject debug_info, JVMCI_TRAPS) {95JVMCIObject reference_map = jvmci_env()->get_DebugInfo_referenceMap(debug_info);96if (reference_map.is_null()) {97JVMCI_THROW_NULL(NullPointerException);98}99if (!jvmci_env()->isa_HotSpotReferenceMap(reference_map)) {100JVMCI_ERROR_NULL("unknown reference map: %s", jvmci_env()->klass_name(reference_map));101}102if (!_has_wide_vector && SharedRuntime::is_wide_vector(jvmci_env()->get_HotSpotReferenceMap_maxRegisterSize(reference_map))) {103if (SharedRuntime::polling_page_vectors_safepoint_handler_blob() == NULL) {104JVMCI_ERROR_NULL("JVMCI is producing code using vectors larger than the runtime supports");105}106_has_wide_vector = true;107}108OopMap* map = new OopMap(_total_frame_size, _parameter_count);109JVMCIObjectArray objects = jvmci_env()->get_HotSpotReferenceMap_objects(reference_map);110JVMCIObjectArray derivedBase = jvmci_env()->get_HotSpotReferenceMap_derivedBase(reference_map);111JVMCIPrimitiveArray sizeInBytes = jvmci_env()->get_HotSpotReferenceMap_sizeInBytes(reference_map);112if (objects.is_null() || derivedBase.is_null() || sizeInBytes.is_null()) {113JVMCI_THROW_NULL(NullPointerException);114}115if (JVMCIENV->get_length(objects) != JVMCIENV->get_length(derivedBase) || JVMCIENV->get_length(objects) != JVMCIENV->get_length(sizeInBytes)) {116JVMCI_ERROR_NULL("arrays in reference map have different sizes: %d %d %d", JVMCIENV->get_length(objects), JVMCIENV->get_length(derivedBase), JVMCIENV->get_length(sizeInBytes));117}118for (int i = 0; i < JVMCIENV->get_length(objects); i++) {119JVMCIObject location = JVMCIENV->get_object_at(objects, i);120JVMCIObject baseLocation = JVMCIENV->get_object_at(derivedBase, i);121jint bytes = JVMCIENV->get_int_at(sizeInBytes, i);122123VMReg vmReg = getVMRegFromLocation(location, _total_frame_size, JVMCI_CHECK_NULL);124if (baseLocation.is_non_null()) {125// derived oop126#ifdef _LP64127if (bytes == 8) {128#else129if (bytes == 4) {130#endif131VMReg baseReg = getVMRegFromLocation(baseLocation, _total_frame_size, JVMCI_CHECK_NULL);132map->set_derived_oop(vmReg, baseReg);133} else {134JVMCI_ERROR_NULL("invalid derived oop size in ReferenceMap: %d", bytes);135}136#ifdef _LP64137} else if (bytes == 8) {138// wide oop139map->set_oop(vmReg);140} else if (bytes == 4) {141// narrow oop142map->set_narrowoop(vmReg);143#else144} else if (bytes == 4) {145map->set_oop(vmReg);146#endif147} else {148JVMCI_ERROR_NULL("invalid oop size in ReferenceMap: %d", bytes);149}150}151152JVMCIObject callee_save_info = jvmci_env()->get_DebugInfo_calleeSaveInfo(debug_info);153if (callee_save_info.is_non_null()) {154JVMCIObjectArray registers = jvmci_env()->get_RegisterSaveLayout_registers(callee_save_info);155JVMCIPrimitiveArray slots = jvmci_env()->get_RegisterSaveLayout_slots(callee_save_info);156for (jint i = 0; i < JVMCIENV->get_length(slots); i++) {157JVMCIObject jvmci_reg = JVMCIENV->get_object_at(registers, i);158jint jvmci_reg_number = jvmci_env()->get_code_Register_number(jvmci_reg);159VMReg hotspot_reg = CodeInstaller::get_hotspot_reg(jvmci_reg_number, JVMCI_CHECK_NULL);160// HotSpot stack slots are 4 bytes161jint jvmci_slot = JVMCIENV->get_int_at(slots, i);162jint hotspot_slot = jvmci_slot * VMRegImpl::slots_per_word;163VMReg hotspot_slot_as_reg = VMRegImpl::stack2reg(hotspot_slot);164map->set_callee_saved(hotspot_slot_as_reg, hotspot_reg);165#ifdef _LP64166// (copied from generate_oop_map() in c1_Runtime1_x86.cpp)167VMReg hotspot_slot_hi_as_reg = VMRegImpl::stack2reg(hotspot_slot + 1);168map->set_callee_saved(hotspot_slot_hi_as_reg, hotspot_reg->next());169#endif170}171}172return map;173}174175void* CodeInstaller::record_metadata_reference(CodeSection* section, address dest, JVMCIObject constant, JVMCI_TRAPS) {176/*177* This method needs to return a raw (untyped) pointer, since the value of a pointer to the base178* class is in general not equal to the pointer of the subclass. When patching metaspace pointers,179* the compiler expects a direct pointer to the subclass (Klass* or Method*), not a pointer to the180* base class (Metadata* or MetaspaceObj*).181*/182JVMCIObject obj = jvmci_env()->get_HotSpotMetaspaceConstantImpl_metaspaceObject(constant);183if (jvmci_env()->isa_HotSpotResolvedObjectTypeImpl(obj)) {184Klass* klass = JVMCIENV->asKlass(obj);185assert(!jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant), "unexpected compressed klass pointer %s @ " INTPTR_FORMAT, klass->name()->as_C_string(), p2i(klass));186int index = _oop_recorder->find_index(klass);187section->relocate(dest, metadata_Relocation::spec(index));188JVMCI_event_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());189return klass;190} else if (jvmci_env()->isa_HotSpotResolvedJavaMethodImpl(obj)) {191Method* method = jvmci_env()->asMethod(obj);192assert(!jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant), "unexpected compressed method pointer %s @ " INTPTR_FORMAT, method->name()->as_C_string(), p2i(method));193int index = _oop_recorder->find_index(method);194section->relocate(dest, metadata_Relocation::spec(index));195JVMCI_event_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), method->name()->as_C_string());196return method;197} else {198JVMCI_ERROR_NULL("unexpected metadata reference for constant of type %s", jvmci_env()->klass_name(obj));199}200}201202#ifdef _LP64203narrowKlass CodeInstaller::record_narrow_metadata_reference(CodeSection* section, address dest, JVMCIObject constant, JVMCI_TRAPS) {204JVMCIObject obj = jvmci_env()->get_HotSpotMetaspaceConstantImpl_metaspaceObject(constant);205assert(jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant), "unexpected uncompressed pointer");206207if (!jvmci_env()->isa_HotSpotResolvedObjectTypeImpl(obj)) {208JVMCI_ERROR_0("unexpected compressed pointer of type %s", jvmci_env()->klass_name(obj));209}210211Klass* klass = JVMCIENV->asKlass(obj);212int index = _oop_recorder->find_index(klass);213section->relocate(dest, metadata_Relocation::spec(index));214JVMCI_event_3("narrowKlass[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());215return CompressedKlassPointers::encode(klass);216}217#endif218219Location::Type CodeInstaller::get_oop_type(JVMCIObject value) {220JVMCIObject valueKind = jvmci_env()->get_Value_valueKind(value);221JVMCIObject platformKind = jvmci_env()->get_ValueKind_platformKind(valueKind);222223if (jvmci_env()->equals(platformKind, word_kind())) {224return Location::oop;225} else {226return Location::narrowoop;227}228}229230ScopeValue* CodeInstaller::get_scope_value(JVMCIObject value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, JVMCI_TRAPS) {231second = NULL;232if (value.is_null()) {233JVMCI_THROW_NULL(NullPointerException);234} else if (JVMCIENV->equals(value, jvmci_env()->get_Value_ILLEGAL())) {235if (type != T_ILLEGAL) {236JVMCI_ERROR_NULL("unexpected illegal value, expected %s", basictype_to_str(type));237}238return _illegal_value;239} else if (jvmci_env()->isa_RegisterValue(value)) {240JVMCIObject reg = jvmci_env()->get_RegisterValue_reg(value);241jint number = jvmci_env()->get_code_Register_number(reg);242VMReg hotspotRegister = get_hotspot_reg(number, JVMCI_CHECK_NULL);243if (is_general_purpose_reg(hotspotRegister)) {244Location::Type locationType;245if (type == T_OBJECT) {246locationType = get_oop_type(value);247} else if (type == T_LONG) {248locationType = Location::lng;249} else if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) {250locationType = Location::int_in_long;251} else {252JVMCI_ERROR_NULL("unexpected type %s in cpu register", basictype_to_str(type));253}254ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, hotspotRegister));255if (type == T_LONG) {256second = value;257}258return value;259} else {260Location::Type locationType;261if (type == T_FLOAT) {262// this seems weird, but the same value is used in c1_LinearScan263locationType = Location::normal;264} else if (type == T_DOUBLE) {265locationType = Location::dbl;266} else {267JVMCI_ERROR_NULL("unexpected type %s in floating point register", basictype_to_str(type));268}269ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, hotspotRegister));270if (type == T_DOUBLE) {271second = value;272}273return value;274}275} else if (jvmci_env()->isa_StackSlot(value)) {276jint offset = jvmci_env()->get_StackSlot_offset(value);277if (jvmci_env()->get_StackSlot_addFrameSize(value)) {278offset += _total_frame_size;279}280281Location::Type locationType;282if (type == T_OBJECT) {283locationType = get_oop_type(value);284} else if (type == T_LONG) {285locationType = Location::lng;286} else if (type == T_DOUBLE) {287locationType = Location::dbl;288} else if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) {289locationType = Location::normal;290} else {291JVMCI_ERROR_NULL("unexpected type %s in stack slot", basictype_to_str(type));292}293ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset));294if (type == T_DOUBLE || type == T_LONG) {295second = value;296}297return value;298} else if (jvmci_env()->isa_JavaConstant(value)) {299if (jvmci_env()->isa_PrimitiveConstant(value)) {300if (jvmci_env()->isa_RawConstant(value)) {301jlong prim = jvmci_env()->get_PrimitiveConstant_primitive(value);302return new ConstantLongValue(prim);303} else {304BasicType constantType = jvmci_env()->kindToBasicType(jvmci_env()->get_PrimitiveConstant_kind(value), JVMCI_CHECK_NULL);305if (type != constantType) {306JVMCI_ERROR_NULL("primitive constant type doesn't match, expected %s but got %s", basictype_to_str(type), basictype_to_str(constantType));307}308if (type == T_INT || type == T_FLOAT) {309jint prim = (jint)jvmci_env()->get_PrimitiveConstant_primitive(value);310switch (prim) {311case -1: return _int_m1_scope_value;312case 0: return _int_0_scope_value;313case 1: return _int_1_scope_value;314case 2: return _int_2_scope_value;315default: return new ConstantIntValue(prim);316}317} else if (type == T_LONG || type == T_DOUBLE) {318jlong prim = jvmci_env()->get_PrimitiveConstant_primitive(value);319second = _int_1_scope_value;320return new ConstantLongValue(prim);321} else {322JVMCI_ERROR_NULL("unexpected primitive constant type %s", basictype_to_str(type));323}324}325} else if (jvmci_env()->isa_NullConstant(value) || jvmci_env()->isa_HotSpotCompressedNullConstant(value)) {326if (type == T_OBJECT) {327return _oop_null_scope_value;328} else {329JVMCI_ERROR_NULL("unexpected null constant, expected %s", basictype_to_str(type));330}331} else if (jvmci_env()->isa_HotSpotObjectConstantImpl(value)) {332if (type == T_OBJECT) {333Handle obj = jvmci_env()->asConstant(value, JVMCI_CHECK_NULL);334if (obj == NULL) {335JVMCI_ERROR_NULL("null value must be in NullConstant");336}337return new ConstantOopWriteValue(JNIHandles::make_local(obj()));338} else {339JVMCI_ERROR_NULL("unexpected object constant, expected %s", basictype_to_str(type));340}341}342} else if (jvmci_env()->isa_VirtualObject(value)) {343if (type == T_OBJECT) {344int id = jvmci_env()->get_VirtualObject_id(value);345if (0 <= id && id < objects->length()) {346ScopeValue* object = objects->at(id);347if (object != NULL) {348return object;349}350}351JVMCI_ERROR_NULL("unknown virtual object id %d", id);352} else {353JVMCI_ERROR_NULL("unexpected virtual object, expected %s", basictype_to_str(type));354}355}356357JVMCI_ERROR_NULL("unexpected value in scope: %s", jvmci_env()->klass_name(value))358}359360void CodeInstaller::record_object_value(ObjectValue* sv, JVMCIObject value, GrowableArray<ScopeValue*>* objects, JVMCI_TRAPS) {361JVMCIObject type = jvmci_env()->get_VirtualObject_type(value);362int id = jvmci_env()->get_VirtualObject_id(value);363Klass* klass = JVMCIENV->asKlass(type);364bool isLongArray = klass == Universe::longArrayKlassObj();365bool isByteArray = klass == Universe::byteArrayKlassObj();366367JVMCIObjectArray values = jvmci_env()->get_VirtualObject_values(value);368JVMCIObjectArray slotKinds = jvmci_env()->get_VirtualObject_slotKinds(value);369for (jint i = 0; i < JVMCIENV->get_length(values); i++) {370ScopeValue* cur_second = NULL;371JVMCIObject object = JVMCIENV->get_object_at(values, i);372BasicType type = jvmci_env()->kindToBasicType(JVMCIENV->get_object_at(slotKinds, i), JVMCI_CHECK);373ScopeValue* value;374if (JVMCIENV->equals(object, jvmci_env()->get_Value_ILLEGAL())) {375if (isByteArray && type == T_ILLEGAL) {376/*377* The difference between a virtualized large access and a deferred write is the kind stored in the slotKinds378* of the virtual object: in the virtualization case, the kind is illegal, in the deferred write case, the kind379* is access stack kind (an int).380*/381value = _virtual_byte_array_marker;382} else {383value = _illegal_value;384if (type == T_DOUBLE || type == T_LONG) {385cur_second = _illegal_value;386}387}388} else {389value = get_scope_value(object, type, objects, cur_second, JVMCI_CHECK);390}391392if (isLongArray && cur_second == NULL) {393// we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations.394// add an int 0 constant395cur_second = _int_0_scope_value;396}397398if (isByteArray && cur_second != NULL && (type == T_DOUBLE || type == T_LONG)) {399// we are trying to write a long in a byte Array. We will need to count the illegals to restore the type of400// the thing we put inside.401cur_second = NULL;402}403404if (cur_second != NULL) {405sv->field_values()->append(cur_second);406}407assert(value != NULL, "missing value");408sv->field_values()->append(value);409}410}411412MonitorValue* CodeInstaller::get_monitor_value(JVMCIObject value, GrowableArray<ScopeValue*>* objects, JVMCI_TRAPS) {413if (value.is_null()) {414JVMCI_THROW_NULL(NullPointerException);415}416if (!jvmci_env()->isa_StackLockValue(value)) {417JVMCI_ERROR_NULL("Monitors must be of type StackLockValue, got %s", jvmci_env()->klass_name(value));418}419420ScopeValue* second = NULL;421ScopeValue* owner_value = get_scope_value(jvmci_env()->get_StackLockValue_owner(value), T_OBJECT, objects, second, JVMCI_CHECK_NULL);422assert(second == NULL, "monitor cannot occupy two stack slots");423424ScopeValue* lock_data_value = get_scope_value(jvmci_env()->get_StackLockValue_slot(value), T_LONG, objects, second, JVMCI_CHECK_NULL);425assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots");426assert(lock_data_value->is_location(), "invalid monitor location");427Location lock_data_loc = ((LocationValue*)lock_data_value)->location();428429bool eliminated = false;430if (jvmci_env()->get_StackLockValue_eliminated(value)) {431eliminated = true;432}433434return new MonitorValue(owner_value, lock_data_loc, eliminated);435}436437void CodeInstaller::initialize_dependencies(JVMCIObject compiled_code, OopRecorder* oop_recorder, JVMCI_TRAPS) {438JavaThread* thread = JavaThread::current();439CompilerThread* compilerThread = thread->is_Compiler_thread() ? CompilerThread::cast(thread) : NULL;440_oop_recorder = oop_recorder;441_dependencies = new Dependencies(&_arena, _oop_recorder, compilerThread != NULL ? compilerThread->log() : NULL);442JVMCIObjectArray assumptions = jvmci_env()->get_HotSpotCompiledCode_assumptions(compiled_code);443if (assumptions.is_non_null()) {444int length = JVMCIENV->get_length(assumptions);445for (int i = 0; i < length; ++i) {446JVMCIObject assumption = JVMCIENV->get_object_at(assumptions, i);447if (assumption.is_non_null()) {448if (jvmci_env()->isa_Assumptions_NoFinalizableSubclass(assumption)) {449assumption_NoFinalizableSubclass(assumption);450} else if (jvmci_env()->isa_Assumptions_ConcreteSubtype(assumption)) {451assumption_ConcreteSubtype(assumption);452} else if (jvmci_env()->isa_Assumptions_LeafType(assumption)) {453assumption_LeafType(assumption);454} else if (jvmci_env()->isa_Assumptions_ConcreteMethod(assumption)) {455assumption_ConcreteMethod(assumption);456} else if (jvmci_env()->isa_Assumptions_CallSiteTargetValue(assumption)) {457assumption_CallSiteTargetValue(assumption, JVMCI_CHECK);458} else {459JVMCI_ERROR("unexpected Assumption subclass %s", jvmci_env()->klass_name(assumption));460}461}462}463}464if (JvmtiExport::can_hotswap_or_post_breakpoint()) {465JVMCIObjectArray methods = jvmci_env()->get_HotSpotCompiledCode_methods(compiled_code);466if (methods.is_non_null()) {467int length = JVMCIENV->get_length(methods);468for (int i = 0; i < length; ++i) {469JVMCIObject method_handle = JVMCIENV->get_object_at(methods, i);470Method* method = jvmci_env()->asMethod(method_handle);471_dependencies->assert_evol_method(method);472}473}474}475}476477// constructor used to create a method478JVMCI::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler,479JVMCIObject target,480JVMCIObject compiled_code,481CodeBlob*& cb,482JVMCIObject installed_code,483FailedSpeculation** failed_speculations,484char* speculations,485int speculations_len,486JVMCI_TRAPS) {487488CodeBuffer buffer("JVMCI Compiler CodeBuffer");489OopRecorder* recorder = new OopRecorder(&_arena, true);490initialize_dependencies(compiled_code, recorder, JVMCI_CHECK_OK);491492// Get instructions and constants CodeSections early because we need it.493_instructions = buffer.insts();494_constants = buffer.consts();495496initialize_fields(target, compiled_code, JVMCI_CHECK_OK);497JVMCI::CodeInstallResult result = initialize_buffer(buffer, true, JVMCI_CHECK_OK);498if (result != JVMCI::ok) {499return result;500}501502int stack_slots = _total_frame_size / HeapWordSize; // conversion to words503504if (!jvmci_env()->isa_HotSpotCompiledNmethod(compiled_code)) {505JVMCIObject stubName = jvmci_env()->get_HotSpotCompiledCode_name(compiled_code);506if (stubName.is_null()) {507JVMCI_ERROR_OK("stub should have a name");508}509char* name = strdup(jvmci_env()->as_utf8_string(stubName));510cb = RuntimeStub::new_runtime_stub(name,511&buffer,512_offsets.value(CodeOffsets::Frame_Complete),513stack_slots,514_debug_recorder->_oopmaps,515false);516result = JVMCI::ok;517} else {518JVMCICompileState* compile_state = (JVMCICompileState*) (address) jvmci_env()->get_HotSpotCompiledNmethod_compileState(compiled_code);519if (compile_state != NULL) {520jvmci_env()->set_compile_state(compile_state);521}522523Thread* thread = Thread::current();524525methodHandle method(thread, jvmci_env()->asMethod(jvmci_env()->get_HotSpotCompiledNmethod_method(compiled_code)));526jint entry_bci = jvmci_env()->get_HotSpotCompiledNmethod_entryBCI(compiled_code);527bool has_unsafe_access = jvmci_env()->get_HotSpotCompiledNmethod_hasUnsafeAccess(compiled_code) == JNI_TRUE;528jint id = jvmci_env()->get_HotSpotCompiledNmethod_id(compiled_code);529if (id == -1) {530// Make sure a valid compile_id is associated with every compile531id = CompileBroker::assign_compile_id_unlocked(thread, method, entry_bci);532jvmci_env()->set_HotSpotCompiledNmethod_id(compiled_code, id);533}534if (!jvmci_env()->isa_HotSpotNmethod(installed_code)) {535JVMCI_THROW_MSG_(IllegalArgumentException, "InstalledCode object must be a HotSpotNmethod when installing a HotSpotCompiledNmethod", JVMCI::ok);536}537538JVMCIObject mirror = installed_code;539nmethod* nm = NULL;540result = runtime()->register_method(jvmci_env(), method, nm, entry_bci, &_offsets, _orig_pc_offset, &buffer,541stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, &_implicit_exception_table,542compiler, _debug_recorder, _dependencies, id,543has_unsafe_access, _has_wide_vector, compiled_code, mirror,544failed_speculations, speculations, speculations_len);545cb = nm->as_codeblob_or_null();546if (nm != NULL && compile_state == NULL) {547// This compile didn't come through the CompileBroker so perform the printing here548DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler);549nm->maybe_print_nmethod(directive);550DirectivesStack::release(directive);551}552}553554if (cb != NULL) {555// Make sure the pre-calculated constants section size was correct.556guarantee((cb->code_begin() - cb->content_begin()) >= _constants_size, "%d < %d", (int)(cb->code_begin() - cb->content_begin()), _constants_size);557}558return result;559}560561void CodeInstaller::initialize_fields(JVMCIObject target, JVMCIObject compiled_code, JVMCI_TRAPS) {562if (jvmci_env()->isa_HotSpotCompiledNmethod(compiled_code)) {563JVMCIObject hotspotJavaMethod = jvmci_env()->get_HotSpotCompiledNmethod_method(compiled_code);564Thread* thread = Thread::current();565methodHandle method(thread, jvmci_env()->asMethod(hotspotJavaMethod));566_parameter_count = method->size_of_parameters();567JVMCI_event_2("installing code for %s", method->name_and_sig_as_C_string());568} else {569// Must be a HotSpotCompiledRuntimeStub.570// Only used in OopMap constructor for non-product builds571_parameter_count = 0;572}573_sites_handle = jvmci_env()->get_HotSpotCompiledCode_sites(compiled_code);574575_code_handle = jvmci_env()->get_HotSpotCompiledCode_targetCode(compiled_code);576_code_size = jvmci_env()->get_HotSpotCompiledCode_targetCodeSize(compiled_code);577_total_frame_size = jvmci_env()->get_HotSpotCompiledCode_totalFrameSize(compiled_code);578579JVMCIObject deoptRescueSlot = jvmci_env()->get_HotSpotCompiledCode_deoptRescueSlot(compiled_code);580if (deoptRescueSlot.is_null()) {581_orig_pc_offset = -1;582} else {583_orig_pc_offset = jvmci_env()->get_StackSlot_offset(deoptRescueSlot);584if (jvmci_env()->get_StackSlot_addFrameSize(deoptRescueSlot)) {585_orig_pc_offset += _total_frame_size;586}587if (_orig_pc_offset < 0) {588JVMCI_ERROR("invalid deopt rescue slot: %d", _orig_pc_offset);589}590}591592// Pre-calculate the constants section size. This is required for PC-relative addressing.593_data_section_handle = jvmci_env()->get_HotSpotCompiledCode_dataSection(compiled_code);594if ((_constants->alignment() % jvmci_env()->get_HotSpotCompiledCode_dataSectionAlignment(compiled_code)) != 0) {595JVMCI_ERROR("invalid data section alignment: %d", jvmci_env()->get_HotSpotCompiledCode_dataSectionAlignment(compiled_code));596}597_constants_size = JVMCIENV->get_length(data_section());598599_data_section_patches_handle = jvmci_env()->get_HotSpotCompiledCode_dataSectionPatches(compiled_code);600601#ifndef PRODUCT602_comments_handle = jvmci_env()->get_HotSpotCompiledCode_comments(compiled_code);603#endif604605_next_call_type = INVOKE_INVALID;606607_has_wide_vector = false;608609JVMCIObject arch = jvmci_env()->get_TargetDescription_arch(target);610_word_kind_handle = jvmci_env()->get_Architecture_wordKind(arch);611}612613int CodeInstaller::estimate_stubs_size(JVMCI_TRAPS) {614// Estimate the number of static call stubs that might be emitted.615int static_call_stubs = 0;616int trampoline_stubs = 0;617JVMCIObjectArray sites = this->sites();618for (int i = 0; i < JVMCIENV->get_length(sites); i++) {619JVMCIObject site = JVMCIENV->get_object_at(sites, i);620if (!site.is_null()) {621if (jvmci_env()->isa_site_Mark(site)) {622JVMCIObject id_obj = jvmci_env()->get_site_Mark_id(site);623if (id_obj.is_non_null()) {624if (!jvmci_env()->is_boxing_object(T_INT, id_obj)) {625JVMCI_ERROR_0("expected Integer id, got %s", jvmci_env()->klass_name(id_obj));626}627jint id = jvmci_env()->get_boxed_value(T_INT, id_obj).i;628switch (id) {629case INVOKEINTERFACE:630case INVOKEVIRTUAL:631trampoline_stubs++;632break;633case INVOKESTATIC:634case INVOKESPECIAL:635static_call_stubs++;636trampoline_stubs++;637break;638default:639break;640}641}642}643}644}645int size = static_call_stubs * CompiledStaticCall::to_interp_stub_size();646size += trampoline_stubs * CompiledStaticCall::to_trampoline_stub_size();647return size;648}649650// perform data and call relocation on the CodeBuffer651JVMCI::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, bool check_size, JVMCI_TRAPS) {652HandleMark hm(Thread::current());653JVMCIObjectArray sites = this->sites();654int locs_buffer_size = JVMCIENV->get_length(sites) * (relocInfo::length_limit + sizeof(relocInfo));655656// Allocate enough space in the stub section for the static call657// stubs. Stubs have extra relocs but they are managed by the stub658// section itself so they don't need to be accounted for in the659// locs_buffer above.660int stubs_size = estimate_stubs_size(JVMCI_CHECK_OK);661int total_size = align_up(_code_size, buffer.insts()->alignment()) + align_up(_constants_size, buffer.consts()->alignment()) + align_up(stubs_size, buffer.stubs()->alignment());662663if (check_size && total_size > JVMCINMethodSizeLimit) {664return JVMCI::code_too_large;665}666667buffer.initialize(total_size, locs_buffer_size);668if (buffer.blob() == NULL) {669return JVMCI::cache_full;670}671buffer.initialize_stubs_size(stubs_size);672buffer.initialize_consts_size(_constants_size);673674_debug_recorder = new DebugInformationRecorder(_oop_recorder);675_debug_recorder->set_oopmaps(new OopMapSet());676677buffer.initialize_oop_recorder(_oop_recorder);678679// copy the constant data into the newly created CodeBuffer680address end_data = _constants->start() + _constants_size;681JVMCIENV->copy_bytes_to(data_section(), (jbyte*) _constants->start(), 0, _constants_size);682_constants->set_end(end_data);683684// copy the code into the newly created CodeBuffer685address end_pc = _instructions->start() + _code_size;686guarantee(_instructions->allocates2(end_pc), "initialize should have reserved enough space for all the code");687JVMCIENV->copy_bytes_to(code(), (jbyte*) _instructions->start(), 0, _code_size);688_instructions->set_end(end_pc);689690for (int i = 0; i < JVMCIENV->get_length(data_section_patches()); i++) {691// HandleMark hm(THREAD);692JVMCIObject patch = JVMCIENV->get_object_at(data_section_patches(), i);693if (patch.is_null()) {694JVMCI_THROW_(NullPointerException, JVMCI::ok);695}696JVMCIObject reference = jvmci_env()->get_site_DataPatch_reference(patch);697if (reference.is_null()) {698JVMCI_THROW_(NullPointerException, JVMCI::ok);699}700if (!jvmci_env()->isa_site_ConstantReference(reference)) {701JVMCI_ERROR_OK("invalid patch in data section: %s", jvmci_env()->klass_name(reference));702}703JVMCIObject constant = jvmci_env()->get_site_ConstantReference_constant(reference);704if (constant.is_null()) {705JVMCI_THROW_(NullPointerException, JVMCI::ok);706}707address dest = _constants->start() + jvmci_env()->get_site_Site_pcOffset(patch);708if (jvmci_env()->isa_HotSpotMetaspaceConstantImpl(constant)) {709if (jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant)) {710#ifdef _LP64711*((narrowKlass*) dest) = record_narrow_metadata_reference(_constants, dest, constant, JVMCI_CHECK_OK);712#else713JVMCI_ERROR_OK("unexpected compressed Klass* in 32-bit mode");714#endif715} else {716*((void**) dest) = record_metadata_reference(_constants, dest, constant, JVMCI_CHECK_OK);717}718} else if (jvmci_env()->isa_HotSpotObjectConstantImpl(constant)) {719Handle obj = jvmci_env()->asConstant(constant, JVMCI_CHECK_OK);720jobject value = JNIHandles::make_local(obj());721int oop_index = _oop_recorder->find_index(value);722723if (jvmci_env()->get_HotSpotObjectConstantImpl_compressed(constant)) {724#ifdef _LP64725_constants->relocate(dest, oop_Relocation::spec(oop_index), relocInfo::narrow_oop_in_const);726#else727JVMCI_ERROR_OK("unexpected compressed oop in 32-bit mode");728#endif729} else {730_constants->relocate(dest, oop_Relocation::spec(oop_index));731}732} else {733JVMCI_ERROR_OK("invalid constant in data section: %s", jvmci_env()->klass_name(constant));734}735}736jint last_pc_offset = -1;737for (int i = 0; i < JVMCIENV->get_length(sites); i++) {738// HandleMark hm(THREAD);739JVMCIObject site = JVMCIENV->get_object_at(sites, i);740if (site.is_null()) {741JVMCI_THROW_(NullPointerException, JVMCI::ok);742}743744jint pc_offset = jvmci_env()->get_site_Site_pcOffset(site);745746if (jvmci_env()->isa_site_Call(site)) {747JVMCI_event_4("call at %i", pc_offset);748site_Call(buffer, pc_offset, site, JVMCI_CHECK_OK);749} else if (jvmci_env()->isa_site_Infopoint(site)) {750// three reasons for infopoints denote actual safepoints751JVMCIObject reason = jvmci_env()->get_site_Infopoint_reason(site);752if (JVMCIENV->equals(reason, jvmci_env()->get_site_InfopointReason_SAFEPOINT()) ||753JVMCIENV->equals(reason, jvmci_env()->get_site_InfopointReason_CALL()) ||754JVMCIENV->equals(reason, jvmci_env()->get_site_InfopointReason_IMPLICIT_EXCEPTION())) {755JVMCI_event_4("safepoint at %i", pc_offset);756site_Safepoint(buffer, pc_offset, site, JVMCI_CHECK_OK);757if (_orig_pc_offset < 0) {758JVMCI_ERROR_OK("method contains safepoint, but has no deopt rescue slot");759}760if (JVMCIENV->equals(reason, jvmci_env()->get_site_InfopointReason_IMPLICIT_EXCEPTION())) {761if (jvmci_env()->isa_site_ImplicitExceptionDispatch(site)) {762jint dispatch_offset = jvmci_env()->get_site_ImplicitExceptionDispatch_dispatchOffset(site);763JVMCI_event_4("implicit exception at %i, dispatch to %i", pc_offset, dispatch_offset);764_implicit_exception_table.append(pc_offset, dispatch_offset);765} else {766JVMCI_event_4("implicit exception at %i", pc_offset);767_implicit_exception_table.add_deoptimize(pc_offset);768}769}770} else {771JVMCI_event_4("infopoint at %i", pc_offset);772site_Infopoint(buffer, pc_offset, site, JVMCI_CHECK_OK);773}774} else if (jvmci_env()->isa_site_DataPatch(site)) {775JVMCI_event_4("datapatch at %i", pc_offset);776site_DataPatch(buffer, pc_offset, site, JVMCI_CHECK_OK);777} else if (jvmci_env()->isa_site_Mark(site)) {778JVMCI_event_4("mark at %i", pc_offset);779site_Mark(buffer, pc_offset, site, JVMCI_CHECK_OK);780} else if (jvmci_env()->isa_site_ExceptionHandler(site)) {781JVMCI_event_4("exceptionhandler at %i", pc_offset);782site_ExceptionHandler(pc_offset, site);783} else {784JVMCI_ERROR_OK("unexpected site subclass: %s", jvmci_env()->klass_name(site));785}786last_pc_offset = pc_offset;787788JavaThread* thread = JavaThread::current();789if (SafepointMechanism::should_process(thread)) {790// this is a hacky way to force a safepoint check but nothing else was jumping out at me.791ThreadToNativeFromVM ttnfv(thread);792}793}794795#ifndef PRODUCT796if (comments().is_non_null()) {797for (int i = 0; i < JVMCIENV->get_length(comments()); i++) {798JVMCIObject comment = JVMCIENV->get_object_at(comments(), i);799assert(jvmci_env()->isa_HotSpotCompiledCode_Comment(comment), "cce");800jint offset = jvmci_env()->get_HotSpotCompiledCode_Comment_pcOffset(comment);801const char* text = jvmci_env()->as_utf8_string(jvmci_env()->get_HotSpotCompiledCode_Comment_text(comment));802buffer.block_comment(offset, text);803}804}805#endif806if (_has_auto_box) {807JavaThread* THREAD = JavaThread::current(); // For exception macros.808JVMCI::ensure_box_caches_initialized(CHECK_(JVMCI::ok));809}810return JVMCI::ok;811}812813void CodeInstaller::assumption_NoFinalizableSubclass(JVMCIObject assumption) {814JVMCIObject receiverType_handle = jvmci_env()->get_Assumptions_NoFinalizableSubclass_receiverType(assumption);815Klass* receiverType = jvmci_env()->asKlass(receiverType_handle);816_dependencies->assert_has_no_finalizable_subclasses(receiverType);817}818819void CodeInstaller::assumption_ConcreteSubtype(JVMCIObject assumption) {820JVMCIObject context_handle = jvmci_env()->get_Assumptions_ConcreteSubtype_context(assumption);821JVMCIObject subtype_handle = jvmci_env()->get_Assumptions_ConcreteSubtype_subtype(assumption);822Klass* context = jvmci_env()->asKlass(context_handle);823Klass* subtype = jvmci_env()->asKlass(subtype_handle);824825assert(context->is_abstract(), "");826_dependencies->assert_abstract_with_unique_concrete_subtype(context, subtype);827}828829void CodeInstaller::assumption_LeafType(JVMCIObject assumption) {830JVMCIObject context_handle = jvmci_env()->get_Assumptions_LeafType_context(assumption);831Klass* context = jvmci_env()->asKlass(context_handle);832833_dependencies->assert_leaf_type(context);834}835836void CodeInstaller::assumption_ConcreteMethod(JVMCIObject assumption) {837JVMCIObject impl_handle = jvmci_env()->get_Assumptions_ConcreteMethod_impl(assumption);838JVMCIObject context_handle = jvmci_env()->get_Assumptions_ConcreteMethod_context(assumption);839840Method* impl = jvmci_env()->asMethod(impl_handle);841Klass* context = jvmci_env()->asKlass(context_handle);842843_dependencies->assert_unique_concrete_method(context, impl);844}845846void CodeInstaller::assumption_CallSiteTargetValue(JVMCIObject assumption, JVMCI_TRAPS) {847JVMCIObject callSiteConstant = jvmci_env()->get_Assumptions_CallSiteTargetValue_callSite(assumption);848Handle callSite = jvmci_env()->asConstant(callSiteConstant, JVMCI_CHECK);849JVMCIObject methodConstant = jvmci_env()->get_Assumptions_CallSiteTargetValue_methodHandle(assumption);850Handle methodHandle = jvmci_env()->asConstant(methodConstant, JVMCI_CHECK);851_dependencies->assert_call_site_target_value(callSite(), methodHandle());852}853854void CodeInstaller::site_ExceptionHandler(jint pc_offset, JVMCIObject exc) {855jint handler_offset = jvmci_env()->get_site_ExceptionHandler_handlerPos(exc);856857// Subtable header858_exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0));859860// Subtable entry861_exception_handler_table.add_entry(HandlerTableEntry(-1, handler_offset, 0));862}863864// If deoptimization happens, the interpreter should reexecute these bytecodes.865// This function mainly helps the compilers to set up the reexecute bit.866static bool bytecode_should_reexecute(Bytecodes::Code code) {867switch (code) {868case Bytecodes::_invokedynamic:869case Bytecodes::_invokevirtual:870case Bytecodes::_invokeinterface:871case Bytecodes::_invokespecial:872case Bytecodes::_invokestatic:873return false;874default:875return true;876}877return true;878}879880GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(JVMCIObject debug_info, JVMCI_TRAPS) {881JVMCIObjectArray virtualObjects = jvmci_env()->get_DebugInfo_virtualObjectMapping(debug_info);882if (virtualObjects.is_null()) {883return NULL;884}885GrowableArray<ScopeValue*>* objects = new GrowableArray<ScopeValue*>(JVMCIENV->get_length(virtualObjects), JVMCIENV->get_length(virtualObjects), NULL);886// Create the unique ObjectValues887for (int i = 0; i < JVMCIENV->get_length(virtualObjects); i++) {888// HandleMark hm(THREAD);889JVMCIObject value = JVMCIENV->get_object_at(virtualObjects, i);890int id = jvmci_env()->get_VirtualObject_id(value);891JVMCIObject type = jvmci_env()->get_VirtualObject_type(value);892bool is_auto_box = jvmci_env()->get_VirtualObject_isAutoBox(value);893if (is_auto_box) {894_has_auto_box = true;895}896Klass* klass = jvmci_env()->asKlass(type);897oop javaMirror = klass->java_mirror();898ScopeValue *klass_sv = new ConstantOopWriteValue(JNIHandles::make_local(Thread::current(), javaMirror));899ObjectValue* sv = is_auto_box ? new AutoBoxObjectValue(id, klass_sv) : new ObjectValue(id, klass_sv);900if (id < 0 || id >= objects->length()) {901JVMCI_ERROR_NULL("virtual object id %d out of bounds", id);902}903if (objects->at(id) != NULL) {904JVMCI_ERROR_NULL("duplicate virtual object id %d", id);905}906objects->at_put(id, sv);907}908// All the values which could be referenced by the VirtualObjects909// exist, so now describe all the VirtualObjects themselves.910for (int i = 0; i < JVMCIENV->get_length(virtualObjects); i++) {911// HandleMark hm(THREAD);912JVMCIObject value = JVMCIENV->get_object_at(virtualObjects, i);913int id = jvmci_env()->get_VirtualObject_id(value);914record_object_value(objects->at(id)->as_ObjectValue(), value, objects, JVMCI_CHECK_NULL);915}916_debug_recorder->dump_object_pool(objects);917918return objects;919}920921void CodeInstaller::record_scope(jint pc_offset, JVMCIObject debug_info, ScopeMode scope_mode, bool is_mh_invoke, bool return_oop, JVMCI_TRAPS) {922JVMCIObject position = jvmci_env()->get_DebugInfo_bytecodePosition(debug_info);923if (position.is_null()) {924// Stubs do not record scope info, just oop maps925return;926}927928GrowableArray<ScopeValue*>* objectMapping;929if (scope_mode == CodeInstaller::FullFrame) {930objectMapping = record_virtual_objects(debug_info, JVMCI_CHECK);931} else {932objectMapping = NULL;933}934record_scope(pc_offset, position, scope_mode, objectMapping, is_mh_invoke, return_oop, JVMCI_CHECK);935}936937int CodeInstaller::map_jvmci_bci(int bci) {938if (bci < 0) {939if (bci == jvmci_env()->get_BytecodeFrame_BEFORE_BCI()) {940return BeforeBci;941} else if (bci == jvmci_env()->get_BytecodeFrame_AFTER_BCI()) {942return AfterBci;943} else if (bci == jvmci_env()->get_BytecodeFrame_UNWIND_BCI()) {944return UnwindBci;945} else if (bci == jvmci_env()->get_BytecodeFrame_AFTER_EXCEPTION_BCI()) {946return AfterExceptionBci;947} else if (bci == jvmci_env()->get_BytecodeFrame_UNKNOWN_BCI()) {948return UnknownBci;949} else if (bci == jvmci_env()->get_BytecodeFrame_INVALID_FRAMESTATE_BCI()) {950return InvalidFrameStateBci;951}952ShouldNotReachHere();953}954return bci;955}956957void CodeInstaller::record_scope(jint pc_offset, JVMCIObject position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, bool is_mh_invoke, bool return_oop, JVMCI_TRAPS) {958JVMCIObject frame;959if (scope_mode == CodeInstaller::FullFrame) {960if (!jvmci_env()->isa_BytecodeFrame(position)) {961JVMCI_ERROR("Full frame expected for debug info at %i", pc_offset);962}963frame = position;964}965JVMCIObject caller_frame = jvmci_env()->get_BytecodePosition_caller(position);966if (caller_frame.is_non_null()) {967record_scope(pc_offset, caller_frame, scope_mode, objects, is_mh_invoke, return_oop, JVMCI_CHECK);968}969970JVMCIObject hotspot_method = jvmci_env()->get_BytecodePosition_method(position);971Thread* thread = Thread::current();972methodHandle method(thread, jvmci_env()->asMethod(hotspot_method));973jint bci = map_jvmci_bci(jvmci_env()->get_BytecodePosition_bci(position));974if (bci == jvmci_env()->get_BytecodeFrame_BEFORE_BCI()) {975bci = SynchronizationEntryBCI;976}977978JVMCI_event_2("Recording scope pc_offset=%d bci=%d method=%s", pc_offset, bci, method->name_and_sig_as_C_string());979980bool reexecute = false;981if (frame.is_non_null()) {982if (bci < 0){983reexecute = false;984} else {985Bytecodes::Code code = Bytecodes::java_code_at(method(), method->bcp_from(bci));986reexecute = bytecode_should_reexecute(code);987if (frame.is_non_null()) {988reexecute = (jvmci_env()->get_BytecodeFrame_duringCall(frame) == JNI_FALSE);989}990}991}992993DebugToken* locals_token = NULL;994DebugToken* expressions_token = NULL;995DebugToken* monitors_token = NULL;996bool throw_exception = false;997998if (frame.is_non_null()) {999jint local_count = jvmci_env()->get_BytecodeFrame_numLocals(frame);1000jint expression_count = jvmci_env()->get_BytecodeFrame_numStack(frame);1001jint monitor_count = jvmci_env()->get_BytecodeFrame_numLocks(frame);1002JVMCIObjectArray values = jvmci_env()->get_BytecodeFrame_values(frame);1003JVMCIObjectArray slotKinds = jvmci_env()->get_BytecodeFrame_slotKinds(frame);10041005if (values.is_null() || slotKinds.is_null()) {1006JVMCI_THROW(NullPointerException);1007}1008if (local_count + expression_count + monitor_count != JVMCIENV->get_length(values)) {1009JVMCI_ERROR("unexpected values length %d in scope (%d locals, %d expressions, %d monitors)", JVMCIENV->get_length(values), local_count, expression_count, monitor_count);1010}1011if (local_count + expression_count != JVMCIENV->get_length(slotKinds)) {1012JVMCI_ERROR("unexpected slotKinds length %d in scope (%d locals, %d expressions)", JVMCIENV->get_length(slotKinds), local_count, expression_count);1013}10141015GrowableArray<ScopeValue*>* locals = local_count > 0 ? new GrowableArray<ScopeValue*> (local_count) : NULL;1016GrowableArray<ScopeValue*>* expressions = expression_count > 0 ? new GrowableArray<ScopeValue*> (expression_count) : NULL;1017GrowableArray<MonitorValue*>* monitors = monitor_count > 0 ? new GrowableArray<MonitorValue*> (monitor_count) : NULL;10181019JVMCI_event_2("Scope at bci %d with %d values", bci, JVMCIENV->get_length(values));1020JVMCI_event_2("%d locals %d expressions, %d monitors", local_count, expression_count, monitor_count);10211022for (jint i = 0; i < JVMCIENV->get_length(values); i++) {1023// HandleMark hm(THREAD);1024ScopeValue* second = NULL;1025JVMCIObject value = JVMCIENV->get_object_at(values, i);1026if (i < local_count) {1027BasicType type = jvmci_env()->kindToBasicType(JVMCIENV->get_object_at(slotKinds, i), JVMCI_CHECK);1028ScopeValue* first = get_scope_value(value, type, objects, second, JVMCI_CHECK);1029if (second != NULL) {1030locals->append(second);1031}1032locals->append(first);1033} else if (i < local_count + expression_count) {1034BasicType type = jvmci_env()->kindToBasicType(JVMCIENV->get_object_at(slotKinds, i), JVMCI_CHECK);1035ScopeValue* first = get_scope_value(value, type, objects, second, JVMCI_CHECK);1036if (second != NULL) {1037expressions->append(second);1038}1039expressions->append(first);1040} else {1041MonitorValue *monitor = get_monitor_value(value, objects, JVMCI_CHECK);1042monitors->append(monitor);1043}1044if (second != NULL) {1045i++;1046if (i >= JVMCIENV->get_length(values) || !JVMCIENV->equals(JVMCIENV->get_object_at(values, i), jvmci_env()->get_Value_ILLEGAL())) {1047JVMCI_ERROR("double-slot value not followed by Value.ILLEGAL");1048}1049}1050}10511052locals_token = _debug_recorder->create_scope_values(locals);1053expressions_token = _debug_recorder->create_scope_values(expressions);1054monitors_token = _debug_recorder->create_monitor_values(monitors);10551056throw_exception = jvmci_env()->get_BytecodeFrame_rethrowException(frame) == JNI_TRUE;1057}10581059// has_ea_local_in_scope and arg_escape should be added to JVMCI1060const bool is_opt_native = false;1061const bool has_ea_local_in_scope = false;1062const bool arg_escape = false;1063_debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, is_mh_invoke, is_opt_native, return_oop,1064has_ea_local_in_scope, arg_escape,1065locals_token, expressions_token, monitors_token);1066}10671068void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS) {1069JVMCIObject debug_info = jvmci_env()->get_site_Infopoint_debugInfo(site);1070if (debug_info.is_null()) {1071JVMCI_ERROR("debug info expected at safepoint at %i", pc_offset);1072}10731074// address instruction = _instructions->start() + pc_offset;1075// jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();1076OopMap *map = create_oop_map(debug_info, JVMCI_CHECK);1077_debug_recorder->add_safepoint(pc_offset, map);1078record_scope(pc_offset, debug_info, CodeInstaller::FullFrame, JVMCI_CHECK);1079_debug_recorder->end_safepoint(pc_offset);1080}10811082void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS) {1083JVMCIObject debug_info = jvmci_env()->get_site_Infopoint_debugInfo(site);1084if (debug_info.is_null()) {1085JVMCI_ERROR("debug info expected at infopoint at %i", pc_offset);1086}10871088// We'd like to check that pc_offset is greater than the1089// last pc recorded with _debug_recorder (raising an exception if not)1090// but DebugInformationRecorder doesn't have sufficient public API.10911092_debug_recorder->add_non_safepoint(pc_offset);1093record_scope(pc_offset, debug_info, CodeInstaller::BytecodePosition, JVMCI_CHECK);1094_debug_recorder->end_non_safepoint(pc_offset);1095}10961097void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS) {1098JVMCIObject target = jvmci_env()->get_site_Call_target(site);1099JVMCIObject hotspot_method; // JavaMethod1100JVMCIObject foreign_call;11011102if (jvmci_env()->isa_HotSpotForeignCallTarget(target)) {1103foreign_call = target;1104} else {1105hotspot_method = target;1106}11071108JVMCIObject debug_info = jvmci_env()->get_site_Infopoint_debugInfo(site);11091110assert(hotspot_method.is_non_null() ^ foreign_call.is_non_null(), "Call site needs exactly one type");11111112NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);1113jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method, JVMCI_CHECK);11141115if (debug_info.is_non_null()) {1116OopMap *map = create_oop_map(debug_info, JVMCI_CHECK);1117_debug_recorder->add_safepoint(next_pc_offset, map);11181119if (hotspot_method.is_non_null()) {1120Method *method = jvmci_env()->asMethod(hotspot_method);1121vmIntrinsics::ID iid = method->intrinsic_id();1122bool is_mh_invoke = false;1123if (jvmci_env()->get_site_Call_direct(site)) {1124is_mh_invoke = !method->is_static() && (iid == vmIntrinsics::_compiledLambdaForm ||1125(MethodHandles::is_signature_polymorphic(iid) && MethodHandles::is_signature_polymorphic_intrinsic(iid)));1126}1127bool return_oop = method->is_returning_oop();1128record_scope(next_pc_offset, debug_info, CodeInstaller::FullFrame, is_mh_invoke, return_oop, JVMCI_CHECK);1129} else {1130record_scope(next_pc_offset, debug_info, CodeInstaller::FullFrame, JVMCI_CHECK);1131}1132}11331134if (foreign_call.is_non_null()) {1135jlong foreign_call_destination = jvmci_env()->get_HotSpotForeignCallTarget_address(foreign_call);1136CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination, JVMCI_CHECK);1137} else { // method != NULL1138if (debug_info.is_null()) {1139JVMCI_ERROR("debug info expected at call at %i", pc_offset);1140}11411142JVMCI_event_3("method call");1143CodeInstaller::pd_relocate_JavaMethod(buffer, hotspot_method, pc_offset, JVMCI_CHECK);1144if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) {1145// Need a static call stub for transitions from compiled to interpreted.1146CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset);1147}1148}11491150_next_call_type = INVOKE_INVALID;11511152if (debug_info.is_non_null()) {1153_debug_recorder->end_safepoint(next_pc_offset);1154}1155}11561157void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS) {1158JVMCIObject reference = jvmci_env()->get_site_DataPatch_reference(site);1159if (reference.is_null()) {1160JVMCI_THROW(NullPointerException);1161} else if (jvmci_env()->isa_site_ConstantReference(reference)) {1162JVMCIObject constant = jvmci_env()->get_site_ConstantReference_constant(reference);1163if (constant.is_null()) {1164JVMCI_THROW(NullPointerException);1165} else if (jvmci_env()->isa_DirectHotSpotObjectConstantImpl(constant)) {1166if (!JVMCIENV->is_hotspot()) {1167JVMCIObject string = JVMCIENV->call_HotSpotJVMCIRuntime_callToString(constant, JVMCI_CHECK);1168const char* to_string = JVMCIENV->as_utf8_string(string);1169JVMCI_THROW_MSG(IllegalArgumentException, err_msg("Direct object constant reached the backend: %s", to_string));1170}1171pd_patch_OopConstant(pc_offset, constant, JVMCI_CHECK);1172} else if (jvmci_env()->isa_IndirectHotSpotObjectConstantImpl(constant)) {1173pd_patch_OopConstant(pc_offset, constant, JVMCI_CHECK);1174} else if (jvmci_env()->isa_HotSpotMetaspaceConstantImpl(constant)) {1175pd_patch_MetaspaceConstant(pc_offset, constant, JVMCI_CHECK);1176} else {1177JVMCI_ERROR("unknown constant type in data patch: %s", jvmci_env()->klass_name(constant));1178}1179} else if (jvmci_env()->isa_site_DataSectionReference(reference)) {1180int data_offset = jvmci_env()->get_site_DataSectionReference_offset(reference);1181if (0 <= data_offset && data_offset < _constants_size) {1182pd_patch_DataSectionReference(pc_offset, data_offset, JVMCI_CHECK);1183} else {1184JVMCI_ERROR("data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size);1185}1186} else {1187JVMCI_ERROR("unknown data patch type: %s", jvmci_env()->klass_name(reference));1188}1189}11901191void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS) {1192JVMCIObject id_obj = jvmci_env()->get_site_Mark_id(site);11931194if (id_obj.is_non_null()) {1195if (!jvmci_env()->is_boxing_object(T_INT, id_obj)) {1196JVMCI_ERROR("expected Integer id, got %s", jvmci_env()->klass_name(id_obj));1197}1198jint id = jvmci_env()->get_boxed_value(T_INT, id_obj).i;11991200address pc = _instructions->start() + pc_offset;12011202switch (id) {1203case UNVERIFIED_ENTRY:1204_offsets.set_value(CodeOffsets::Entry, pc_offset);1205break;1206case VERIFIED_ENTRY:1207_offsets.set_value(CodeOffsets::Verified_Entry, pc_offset);1208break;1209case OSR_ENTRY:1210_offsets.set_value(CodeOffsets::OSR_Entry, pc_offset);1211break;1212case EXCEPTION_HANDLER_ENTRY:1213_offsets.set_value(CodeOffsets::Exceptions, pc_offset);1214break;1215case DEOPT_HANDLER_ENTRY:1216_offsets.set_value(CodeOffsets::Deopt, pc_offset);1217break;1218case DEOPT_MH_HANDLER_ENTRY:1219_offsets.set_value(CodeOffsets::DeoptMH, pc_offset);1220break;1221case FRAME_COMPLETE:1222_offsets.set_value(CodeOffsets::Frame_Complete, pc_offset);1223break;1224case INVOKEVIRTUAL:1225case INVOKEINTERFACE:1226case INLINE_INVOKE:1227case INVOKESTATIC:1228case INVOKESPECIAL:1229_next_call_type = (MarkId) id;1230_invoke_mark_pc = pc;1231break;1232case POLL_NEAR:1233case POLL_FAR:1234case POLL_RETURN_NEAR:1235case POLL_RETURN_FAR:1236pd_relocate_poll(pc, id, JVMCI_CHECK);1237break;1238case CARD_TABLE_SHIFT:1239case CARD_TABLE_ADDRESS:1240case HEAP_TOP_ADDRESS:1241case HEAP_END_ADDRESS:1242case NARROW_KLASS_BASE_ADDRESS:1243case NARROW_OOP_BASE_ADDRESS:1244case CRC_TABLE_ADDRESS:1245case LOG_OF_HEAP_REGION_GRAIN_BYTES:1246case INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED:1247case VERIFY_OOPS:1248case VERIFY_OOP_BITS:1249case VERIFY_OOP_MASK:1250case VERIFY_OOP_COUNT_ADDRESS:1251break;1252default:1253JVMCI_ERROR("invalid mark id: %d", id);1254break;1255}1256}1257}125812591260