2015-10-08 12:49:30 -10:00
/*
2019-01-31 10:31:39 +01:00
* Copyright ( c ) 2011 , 2019 , Oracle and / or its affiliates . All rights reserved .
2015-10-08 12:49:30 -10:00
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
# include "precompiled.hpp"
# include "code/compiledIC.hpp"
# include "compiler/compileBroker.hpp"
# include "jvmci/jvmciCodeInstaller.hpp"
# include "jvmci/jvmciCompilerToVM.hpp"
# include "jvmci/jvmciRuntime.hpp"
2019-05-09 14:28:30 +02:00
# include "memory/universe.hpp"
2019-05-09 14:26:03 +02:00
# include "oops/compressedOops.inline.hpp"
2018-03-16 09:12:13 -04:00
# include "runtime/interfaceSupport.inline.hpp"
2018-03-01 16:51:22 -05:00
# include "runtime/jniHandles.inline.hpp"
2018-03-15 21:29:36 +01:00
# include "runtime/sharedRuntime.hpp"
2017-07-05 11:33:17 +02:00
# include "utilities/align.hpp"
2015-10-08 12:49:30 -10:00
// 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).
2019-05-01 12:31:29 -07:00
ConstantOopWriteValue * CodeInstaller : : _oop_null_scope_value = new ( ResourceObj : : C_HEAP , mtJVMCI ) ConstantOopWriteValue ( NULL ) ;
ConstantIntValue * CodeInstaller : : _int_m1_scope_value = new ( ResourceObj : : C_HEAP , mtJVMCI ) ConstantIntValue ( - 1 ) ;
ConstantIntValue * CodeInstaller : : _int_0_scope_value = new ( ResourceObj : : C_HEAP , mtJVMCI ) ConstantIntValue ( ( jint ) 0 ) ;
ConstantIntValue * CodeInstaller : : _int_1_scope_value = new ( ResourceObj : : C_HEAP , mtJVMCI ) ConstantIntValue ( 1 ) ;
ConstantIntValue * CodeInstaller : : _int_2_scope_value = new ( ResourceObj : : C_HEAP , mtJVMCI ) ConstantIntValue ( 2 ) ;
LocationValue * CodeInstaller : : _illegal_value = new ( ResourceObj : : C_HEAP , mtJVMCI ) LocationValue ( Location ( ) ) ;
VMReg CodeInstaller : : getVMRegFromLocation ( JVMCIObject location , int total_frame_size , JVMCI_TRAPS ) {
2015-11-06 10:06:51 -10:00
if ( location . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_NULL ( NullPointerException ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
JVMCIObject reg = jvmci_env ( ) - > get_code_Location_reg ( location ) ;
jint offset = jvmci_env ( ) - > get_code_Location_offset ( location ) ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
if ( reg . is_non_null ( ) ) {
2015-10-08 12:49:30 -10:00
// register
2019-05-01 12:31:29 -07:00
jint number = jvmci_env ( ) - > get_code_Register_number ( reg ) ;
VMReg vmReg = CodeInstaller : : get_hotspot_reg ( number , JVMCI_CHECK_NULL ) ;
2015-11-06 10:06:51 -10:00
if ( offset % 4 = = 0 ) {
return vmReg - > next ( offset / 4 ) ;
} else {
JVMCI_ERROR_NULL ( " unaligned subregister offset %d in oop map " , offset ) ;
}
2015-10-08 12:49:30 -10:00
} else {
// stack slot
2015-11-06 10:06:51 -10:00
if ( offset % 4 = = 0 ) {
2016-06-22 22:39:32 +00:00
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) " ,
offset , CompilerToVM : : Data : : max_oop_map_stack_offset ( ) ) ;
}
assert ( OopMapValue : : legal_vm_reg_name ( vmReg ) , " illegal VMReg " ) ;
return vmReg ;
2015-11-06 10:06:51 -10:00
} else {
JVMCI_ERROR_NULL ( " unaligned stack offset %d in oop map " , offset ) ;
}
2015-10-08 12:49:30 -10:00
}
}
// creates a HotSpot oop map out of the byte arrays provided by DebugInfo
2019-05-01 12:31:29 -07:00
OopMap * CodeInstaller : : create_oop_map ( JVMCIObject debug_info , JVMCI_TRAPS ) {
JVMCIObject reference_map = jvmci_env ( ) - > get_DebugInfo_referenceMap ( debug_info ) ;
2015-11-06 10:06:51 -10:00
if ( reference_map . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_NULL ( NullPointerException ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
if ( ! jvmci_env ( ) - > isa_HotSpotReferenceMap ( reference_map ) ) {
JVMCI_ERROR_NULL ( " unknown reference map: %s " , jvmci_env ( ) - > klass_name ( reference_map ) ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
if ( ! _has_wide_vector & & SharedRuntime : : is_wide_vector ( jvmci_env ( ) - > get_HotSpotReferenceMap_maxRegisterSize ( reference_map ) ) ) {
2018-02-23 21:38:12 +01:00
if ( SharedRuntime : : polling_page_vectors_safepoint_handler_blob ( ) = = NULL ) {
JVMCI_ERROR_NULL ( " JVMCI is producing code using vectors larger than the runtime supports " ) ;
}
2015-10-08 12:49:30 -10:00
_has_wide_vector = true ;
}
OopMap * map = new OopMap ( _total_frame_size , _parameter_count ) ;
2019-05-01 12:31:29 -07:00
JVMCIObjectArray objects = jvmci_env ( ) - > get_HotSpotReferenceMap_objects ( reference_map ) ;
JVMCIObjectArray derivedBase = jvmci_env ( ) - > get_HotSpotReferenceMap_derivedBase ( reference_map ) ;
JVMCIPrimitiveArray sizeInBytes = jvmci_env ( ) - > get_HotSpotReferenceMap_sizeInBytes ( reference_map ) ;
2015-11-06 10:06:51 -10:00
if ( objects . is_null ( ) | | derivedBase . is_null ( ) | | sizeInBytes . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_NULL ( NullPointerException ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
if ( JVMCIENV - > get_length ( objects ) ! = JVMCIENV - > get_length ( derivedBase ) | | JVMCIENV - > get_length ( objects ) ! = JVMCIENV - > get_length ( sizeInBytes ) ) {
JVMCI_ERROR_NULL ( " arrays in reference map have different sizes: %d %d %d " , JVMCIENV - > get_length ( objects ) , JVMCIENV - > get_length ( derivedBase ) , JVMCIENV - > get_length ( sizeInBytes ) ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
for ( int i = 0 ; i < JVMCIENV - > get_length ( objects ) ; i + + ) {
JVMCIObject location = JVMCIENV - > get_object_at ( objects , i ) ;
JVMCIObject baseLocation = JVMCIENV - > get_object_at ( derivedBase , i ) ;
jint bytes = JVMCIENV - > get_int_at ( sizeInBytes , i ) ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
VMReg vmReg = getVMRegFromLocation ( location , _total_frame_size , JVMCI_CHECK_NULL ) ;
if ( baseLocation . is_non_null ( ) ) {
2015-10-08 12:49:30 -10:00
// derived oop
2015-11-06 10:06:51 -10:00
# ifdef _LP64
if ( bytes = = 8 ) {
# else
if ( bytes = = 4 ) {
# endif
2019-05-01 12:31:29 -07:00
VMReg baseReg = getVMRegFromLocation ( baseLocation , _total_frame_size , JVMCI_CHECK_NULL ) ;
2015-11-06 10:06:51 -10:00
map - > set_derived_oop ( vmReg , baseReg ) ;
} else {
JVMCI_ERROR_NULL ( " invalid derived oop size in ReferenceMap: %d " , bytes ) ;
}
# ifdef _LP64
2015-10-08 12:49:30 -10:00
} else if ( bytes = = 8 ) {
// wide oop
map - > set_oop ( vmReg ) ;
2015-11-06 10:06:51 -10:00
} else if ( bytes = = 4 ) {
2015-10-08 12:49:30 -10:00
// narrow oop
map - > set_narrowoop ( vmReg ) ;
2015-11-06 10:06:51 -10:00
# else
} else if ( bytes = = 4 ) {
map - > set_oop ( vmReg ) ;
# endif
} else {
JVMCI_ERROR_NULL ( " invalid oop size in ReferenceMap: %d " , bytes ) ;
2015-10-08 12:49:30 -10:00
}
}
2019-05-01 12:31:29 -07:00
JVMCIObject callee_save_info = jvmci_env ( ) - > get_DebugInfo_calleeSaveInfo ( debug_info ) ;
if ( callee_save_info . is_non_null ( ) ) {
JVMCIObjectArray registers = jvmci_env ( ) - > get_RegisterSaveLayout_registers ( callee_save_info ) ;
JVMCIPrimitiveArray slots = jvmci_env ( ) - > get_RegisterSaveLayout_slots ( callee_save_info ) ;
for ( jint i = 0 ; i < JVMCIENV - > get_length ( slots ) ; i + + ) {
JVMCIObject jvmci_reg = JVMCIENV - > get_object_at ( registers , i ) ;
jint jvmci_reg_number = jvmci_env ( ) - > get_code_Register_number ( jvmci_reg ) ;
VMReg hotspot_reg = CodeInstaller : : get_hotspot_reg ( jvmci_reg_number , JVMCI_CHECK_NULL ) ;
2015-10-08 12:49:30 -10:00
// HotSpot stack slots are 4 bytes
2019-05-01 12:31:29 -07:00
jint jvmci_slot = JVMCIENV - > get_int_at ( slots , i ) ;
2015-10-08 12:49:30 -10:00
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 ;
}
2018-11-02 00:26:25 -07:00
# if INCLUDE_AOT
2019-05-01 12:31:29 -07:00
AOTOopRecorder : : AOTOopRecorder ( CodeInstaller * code_inst , Arena * arena , bool deduplicate ) : OopRecorder ( arena , deduplicate ) {
_code_inst = code_inst ;
2017-10-19 19:23:48 -07:00
_meta_refs = new GrowableArray < jobject > ( ) ;
2016-12-11 19:07:04 -08:00
}
2017-10-19 19:23:48 -07:00
int AOTOopRecorder : : nr_meta_refs ( ) const {
return _meta_refs - > length ( ) ;
2016-12-11 19:07:04 -08:00
}
2017-10-19 19:23:48 -07:00
jobject AOTOopRecorder : : meta_element ( int pos ) const {
return _meta_refs - > at ( pos ) ;
2016-12-11 19:07:04 -08:00
}
int AOTOopRecorder : : find_index ( Metadata * h ) {
2017-10-19 19:23:48 -07:00
JavaThread * THREAD = JavaThread : : current ( ) ;
2019-05-01 12:31:29 -07:00
JVMCIEnv * JVMCIENV = _code_inst - > jvmci_env ( ) ;
2017-10-19 19:23:48 -07:00
int oldCount = metadata_count ( ) ;
2016-12-11 19:07:04 -08:00
int index = this - > OopRecorder : : find_index ( h ) ;
2017-10-19 19:23:48 -07:00
int newCount = metadata_count ( ) ;
if ( oldCount = = newCount ) {
// found a match
return index ;
}
vmassert ( index + 1 = = newCount , " must be last " ) ;
2016-12-11 19:07:04 -08:00
2018-06-24 21:46:11 -07:00
JVMCIKlassHandle klass ( THREAD ) ;
2019-05-01 12:31:29 -07:00
JVMCIObject result ;
2018-07-12 16:31:28 +02:00
guarantee ( h ! = NULL ,
" If DebugInformationRecorder::describe_scope passes NULL oldCount == newCount must hold. " ) ;
2016-12-11 19:07:04 -08:00
if ( h - > is_klass ( ) ) {
klass = ( Klass * ) h ;
2019-05-01 12:31:29 -07:00
result = JVMCIENV - > get_jvmci_type ( klass , JVMCI_CATCH ) ;
2016-12-11 19:07:04 -08:00
} else if ( h - > is_method ( ) ) {
Method * method = ( Method * ) h ;
2019-11-13 08:23:23 -05:00
methodHandle mh ( THREAD , method ) ;
result = JVMCIENV - > get_jvmci_method ( mh , JVMCI_CATCH ) ;
2016-12-11 19:07:04 -08:00
}
2019-05-01 12:31:29 -07:00
jobject ref = JVMCIENV - > get_jobject ( result ) ;
2017-10-19 19:23:48 -07:00
record_meta_ref ( ref , index ) ;
2016-12-11 19:07:04 -08:00
return index ;
}
int AOTOopRecorder : : find_index ( jobject h ) {
if ( h = = NULL ) {
return 0 ;
}
oop javaMirror = JNIHandles : : resolve ( h ) ;
Klass * klass = java_lang_Class : : as_Klass ( javaMirror ) ;
return find_index ( klass ) ;
}
2017-10-19 19:23:48 -07:00
void AOTOopRecorder : : record_meta_ref ( jobject o , int index ) {
2016-12-11 19:07:04 -08:00
assert ( index > 0 , " must be 1..n " ) ;
index - = 1 ; // reduce by one to convert to array index
2017-10-19 19:23:48 -07:00
assert ( index = = _meta_refs - > length ( ) , " must be last " ) ;
_meta_refs - > append ( o ) ;
2016-12-11 19:07:04 -08:00
}
2018-11-02 00:26:25 -07:00
# endif // INCLUDE_AOT
2016-12-11 19:07:04 -08:00
2019-05-01 12:31:29 -07:00
void * CodeInstaller : : record_metadata_reference ( CodeSection * section , address dest , JVMCIObject constant , JVMCI_TRAPS ) {
2016-03-25 12:43:23 +01:00
/*
* 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 ,
2016-05-12 12:59:35 +02:00
* the compiler expects a direct pointer to the subclass ( Klass * or Method * ) , not a pointer to the
* base class ( Metadata * or MetaspaceObj * ) .
2016-03-25 12:43:23 +01:00
*/
2019-05-01 12:31:29 -07:00
JVMCIObject obj = jvmci_env ( ) - > get_HotSpotMetaspaceConstantImpl_metaspaceObject ( constant ) ;
if ( jvmci_env ( ) - > isa_HotSpotResolvedObjectTypeImpl ( obj ) ) {
Klass * klass = JVMCIENV - > asKlass ( obj ) ;
assert ( ! jvmci_env ( ) - > get_HotSpotMetaspaceConstantImpl_compressed ( constant ) , " unexpected compressed klass pointer %s @ " INTPTR_FORMAT , klass - > name ( ) - > as_C_string ( ) , p2i ( klass ) ) ;
2015-11-04 07:23:23 -10:00
int index = _oop_recorder - > find_index ( klass ) ;
2016-09-29 10:00:56 -07:00
section - > relocate ( dest , metadata_Relocation : : spec ( index ) ) ;
2015-11-04 07:23:23 -10:00
TRACE_jvmci_3 ( " metadata[%d of %d] = %s " , index , _oop_recorder - > metadata_count ( ) , klass - > name ( ) - > as_C_string ( ) ) ;
return klass ;
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_HotSpotResolvedJavaMethodImpl ( obj ) ) {
Method * method = jvmci_env ( ) - > asMethod ( obj ) ;
assert ( ! jvmci_env ( ) - > get_HotSpotMetaspaceConstantImpl_compressed ( constant ) , " unexpected compressed method pointer %s @ " INTPTR_FORMAT , method - > name ( ) - > as_C_string ( ) , p2i ( method ) ) ;
2015-11-04 07:23:23 -10:00
int index = _oop_recorder - > find_index ( method ) ;
2016-09-29 10:00:56 -07:00
section - > relocate ( dest , metadata_Relocation : : spec ( index ) ) ;
2015-11-04 07:23:23 -10:00
TRACE_jvmci_3 ( " metadata[%d of %d] = %s " , index , _oop_recorder - > metadata_count ( ) , method - > name ( ) - > as_C_string ( ) ) ;
return method ;
2015-10-08 12:49:30 -10:00
} else {
2019-05-01 12:31:29 -07:00
JVMCI_ERROR_NULL ( " unexpected metadata reference for constant of type %s " , jvmci_env ( ) - > klass_name ( obj ) ) ;
2015-10-08 12:49:30 -10:00
}
}
2015-11-04 07:23:23 -10:00
# ifdef _LP64
2019-05-01 12:31:29 -07:00
narrowKlass CodeInstaller : : record_narrow_metadata_reference ( CodeSection * section , address dest , JVMCIObject constant , JVMCI_TRAPS ) {
JVMCIObject obj = jvmci_env ( ) - > get_HotSpotMetaspaceConstantImpl_metaspaceObject ( constant ) ;
assert ( jvmci_env ( ) - > get_HotSpotMetaspaceConstantImpl_compressed ( constant ) , " unexpected uncompressed pointer " ) ;
2015-11-06 10:06:51 -10:00
2019-05-01 12:31:29 -07:00
if ( ! jvmci_env ( ) - > isa_HotSpotResolvedObjectTypeImpl ( obj ) ) {
JVMCI_ERROR_0 ( " unexpected compressed pointer of type %s " , jvmci_env ( ) - > klass_name ( obj ) ) ;
2015-11-06 10:06:51 -10:00
}
2015-11-04 07:23:23 -10:00
2019-05-01 12:31:29 -07:00
Klass * klass = JVMCIENV - > asKlass ( obj ) ;
2015-11-04 07:23:23 -10:00
int index = _oop_recorder - > find_index ( klass ) ;
2016-09-29 10:00:56 -07:00
section - > relocate ( dest , metadata_Relocation : : spec ( index ) ) ;
2015-11-04 07:23:23 -10:00
TRACE_jvmci_3 ( " narrowKlass[%d of %d] = %s " , index , _oop_recorder - > metadata_count ( ) , klass - > name ( ) - > as_C_string ( ) ) ;
2019-05-09 14:26:03 +02:00
return CompressedKlassPointers : : encode ( klass ) ;
2015-10-08 12:49:30 -10:00
}
2015-11-04 07:23:23 -10:00
# endif
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
Location : : Type CodeInstaller : : get_oop_type ( JVMCIObject value ) {
JVMCIObject valueKind = jvmci_env ( ) - > get_Value_valueKind ( value ) ;
JVMCIObject platformKind = jvmci_env ( ) - > get_ValueKind_platformKind ( valueKind ) ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
if ( jvmci_env ( ) - > equals ( platformKind , word_kind ( ) ) ) {
2015-10-08 12:49:30 -10:00
return Location : : oop ;
} else {
return Location : : narrowoop ;
}
}
2019-05-01 12:31:29 -07:00
ScopeValue * CodeInstaller : : get_scope_value ( JVMCIObject value , BasicType type , GrowableArray < ScopeValue * > * objects , ScopeValue * & second , JVMCI_TRAPS ) {
2015-10-08 12:49:30 -10:00
second = NULL ;
2015-11-06 10:06:51 -10:00
if ( value . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_NULL ( NullPointerException ) ;
} else if ( JVMCIENV - > equals ( value , jvmci_env ( ) - > get_Value_ILLEGAL ( ) ) ) {
2015-11-06 10:06:51 -10:00
if ( type ! = T_ILLEGAL ) {
JVMCI_ERROR_NULL ( " unexpected illegal value, expected %s " , basictype_to_str ( type ) ) ;
}
2015-10-08 12:49:30 -10:00
return _illegal_value ;
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_RegisterValue ( value ) ) {
JVMCIObject reg = jvmci_env ( ) - > get_RegisterValue_reg ( value ) ;
jint number = jvmci_env ( ) - > get_code_Register_number ( reg ) ;
VMReg hotspotRegister = get_hotspot_reg ( number , JVMCI_CHECK_NULL ) ;
2015-10-08 12:49:30 -10:00
if ( is_general_purpose_reg ( hotspotRegister ) ) {
Location : : Type locationType ;
if ( type = = T_OBJECT ) {
2019-05-01 12:31:29 -07:00
locationType = get_oop_type ( value ) ;
2015-10-08 12:49:30 -10:00
} else if ( type = = T_LONG ) {
locationType = Location : : lng ;
2015-11-06 10:06:51 -10:00
} else if ( type = = T_INT | | type = = T_FLOAT | | type = = T_SHORT | | type = = T_CHAR | | type = = T_BYTE | | type = = T_BOOLEAN ) {
2015-10-08 12:49:30 -10:00
locationType = Location : : int_in_long ;
2015-11-06 10:06:51 -10:00
} else {
JVMCI_ERROR_NULL ( " unexpected type %s in cpu register " , basictype_to_str ( type ) ) ;
2015-10-08 12:49:30 -10:00
}
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 ;
2015-11-06 10:06:51 -10:00
} else if ( type = = T_DOUBLE ) {
2015-10-08 12:49:30 -10:00
locationType = Location : : dbl ;
2015-11-06 10:06:51 -10:00
} else {
JVMCI_ERROR_NULL ( " unexpected type %s in floating point register " , basictype_to_str ( type ) ) ;
2015-10-08 12:49:30 -10:00
}
ScopeValue * value = new LocationValue ( Location : : new_reg_loc ( locationType , hotspotRegister ) ) ;
if ( type = = T_DOUBLE ) {
second = value ;
}
return value ;
}
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_StackSlot ( value ) ) {
jint offset = jvmci_env ( ) - > get_StackSlot_offset ( value ) ;
if ( jvmci_env ( ) - > get_StackSlot_addFrameSize ( value ) ) {
2015-10-08 12:49:30 -10:00
offset + = _total_frame_size ;
}
Location : : Type locationType ;
if ( type = = T_OBJECT ) {
2019-05-01 12:31:29 -07:00
locationType = get_oop_type ( value ) ;
2015-10-08 12:49:30 -10:00
} else if ( type = = T_LONG ) {
locationType = Location : : lng ;
} else if ( type = = T_DOUBLE ) {
locationType = Location : : dbl ;
2015-11-06 10:06:51 -10:00
} else if ( type = = T_INT | | type = = T_FLOAT | | type = = T_SHORT | | type = = T_CHAR | | type = = T_BYTE | | type = = T_BOOLEAN ) {
2015-10-08 12:49:30 -10:00
locationType = Location : : normal ;
2015-11-06 10:06:51 -10:00
} else {
JVMCI_ERROR_NULL ( " unexpected type %s in stack slot " , basictype_to_str ( type ) ) ;
2015-10-08 12:49:30 -10:00
}
ScopeValue * value = new LocationValue ( Location : : new_stk_loc ( locationType , offset ) ) ;
if ( type = = T_DOUBLE | | type = = T_LONG ) {
second = value ;
}
return value ;
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_JavaConstant ( value ) ) {
if ( jvmci_env ( ) - > isa_PrimitiveConstant ( value ) ) {
if ( jvmci_env ( ) - > isa_RawConstant ( value ) ) {
jlong prim = jvmci_env ( ) - > get_PrimitiveConstant_primitive ( value ) ;
2015-10-08 12:49:30 -10:00
return new ConstantLongValue ( prim ) ;
} else {
2019-05-01 12:31:29 -07:00
BasicType constantType = jvmci_env ( ) - > kindToBasicType ( jvmci_env ( ) - > get_PrimitiveConstant_kind ( value ) , JVMCI_CHECK_NULL ) ;
2015-11-06 10:06:51 -10:00
if ( type ! = constantType ) {
JVMCI_ERROR_NULL ( " primitive constant type doesn't match, expected %s but got %s " , basictype_to_str ( type ) , basictype_to_str ( constantType ) ) ;
}
2015-10-08 12:49:30 -10:00
if ( type = = T_INT | | type = = T_FLOAT ) {
2019-05-01 12:31:29 -07:00
jint prim = ( jint ) jvmci_env ( ) - > get_PrimitiveConstant_primitive ( value ) ;
2015-10-08 12:49:30 -10:00
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 ) ;
}
2015-11-06 10:06:51 -10:00
} else if ( type = = T_LONG | | type = = T_DOUBLE ) {
2019-05-01 12:31:29 -07:00
jlong prim = jvmci_env ( ) - > get_PrimitiveConstant_primitive ( value ) ;
2015-10-08 12:49:30 -10:00
second = _int_1_scope_value ;
return new ConstantLongValue ( prim ) ;
2015-11-06 10:06:51 -10:00
} else {
JVMCI_ERROR_NULL ( " unexpected primitive constant type %s " , basictype_to_str ( type ) ) ;
2015-10-08 12:49:30 -10:00
}
}
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_NullConstant ( value ) | | jvmci_env ( ) - > isa_HotSpotCompressedNullConstant ( value ) ) {
2015-11-06 10:06:51 -10:00
if ( type = = T_OBJECT ) {
2015-10-08 12:49:30 -10:00
return _oop_null_scope_value ;
} else {
2015-11-06 10:06:51 -10:00
JVMCI_ERROR_NULL ( " unexpected null constant, expected %s " , basictype_to_str ( type ) ) ;
}
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_HotSpotObjectConstantImpl ( value ) ) {
2015-11-06 10:06:51 -10:00
if ( type = = T_OBJECT ) {
2019-05-01 12:31:29 -07:00
Handle obj = jvmci_env ( ) - > asConstant ( value , JVMCI_CHECK_NULL ) ;
2015-11-06 10:06:51 -10:00
if ( obj = = NULL ) {
JVMCI_ERROR_NULL ( " null value must be in NullConstant " ) ;
}
2019-05-01 12:31:29 -07:00
return new ConstantOopWriteValue ( JNIHandles : : make_local ( obj ( ) ) ) ;
2015-11-06 10:06:51 -10:00
} else {
JVMCI_ERROR_NULL ( " unexpected object constant, expected %s " , basictype_to_str ( type ) ) ;
2015-10-08 12:49:30 -10:00
}
}
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_VirtualObject ( value ) ) {
2015-11-06 10:06:51 -10:00
if ( type = = T_OBJECT ) {
2019-05-01 12:31:29 -07:00
int id = jvmci_env ( ) - > get_VirtualObject_id ( value ) ;
2015-11-06 10:06:51 -10:00
if ( 0 < = id & & id < objects - > length ( ) ) {
ScopeValue * object = objects - > at ( id ) ;
if ( object ! = NULL ) {
return object ;
}
}
JVMCI_ERROR_NULL ( " unknown virtual object id %d " , id ) ;
} else {
JVMCI_ERROR_NULL ( " unexpected virtual object, expected %s " , basictype_to_str ( type ) ) ;
}
2015-10-08 12:49:30 -10:00
}
2015-11-06 10:06:51 -10:00
2019-05-01 12:31:29 -07:00
JVMCI_ERROR_NULL ( " unexpected value in scope: %s " , jvmci_env ( ) - > klass_name ( value ) )
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : record_object_value ( ObjectValue * sv , JVMCIObject value , GrowableArray < ScopeValue * > * objects , JVMCI_TRAPS ) {
JVMCIObject type = jvmci_env ( ) - > get_VirtualObject_type ( value ) ;
int id = jvmci_env ( ) - > get_VirtualObject_id ( value ) ;
Klass * klass = JVMCIENV - > asKlass ( type ) ;
2015-10-08 12:49:30 -10:00
bool isLongArray = klass = = Universe : : longArrayKlassObj ( ) ;
2019-05-01 12:31:29 -07:00
JVMCIObjectArray values = jvmci_env ( ) - > get_VirtualObject_values ( value ) ;
JVMCIObjectArray slotKinds = jvmci_env ( ) - > get_VirtualObject_slotKinds ( value ) ;
for ( jint i = 0 ; i < JVMCIENV - > get_length ( values ) ; i + + ) {
2015-10-08 12:49:30 -10:00
ScopeValue * cur_second = NULL ;
2019-05-01 12:31:29 -07:00
JVMCIObject object = JVMCIENV - > get_object_at ( values , i ) ;
BasicType type = jvmci_env ( ) - > kindToBasicType ( JVMCIENV - > get_object_at ( slotKinds , i ) , JVMCI_CHECK ) ;
ScopeValue * value = get_scope_value ( object , type , objects , cur_second , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
if ( isLongArray & & cur_second = = NULL ) {
// 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 ( cur_second ! = NULL ) {
sv - > field_values ( ) - > append ( cur_second ) ;
}
assert ( value ! = NULL , " missing value " ) ;
sv - > field_values ( ) - > append ( value ) ;
}
}
2019-05-01 12:31:29 -07:00
MonitorValue * CodeInstaller : : get_monitor_value ( JVMCIObject value , GrowableArray < ScopeValue * > * objects , JVMCI_TRAPS ) {
2015-11-06 10:06:51 -10:00
if ( value . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_NULL ( NullPointerException ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
if ( ! jvmci_env ( ) - > isa_StackLockValue ( value ) ) {
JVMCI_ERROR_NULL ( " Monitors must be of type StackLockValue, got %s " , jvmci_env ( ) - > klass_name ( value ) ) ;
2015-11-06 10:06:51 -10:00
}
2015-10-08 12:49:30 -10:00
ScopeValue * second = NULL ;
2019-05-01 12:31:29 -07:00
ScopeValue * owner_value = get_scope_value ( jvmci_env ( ) - > get_StackLockValue_owner ( value ) , T_OBJECT , objects , second , JVMCI_CHECK_NULL ) ;
2015-10-08 12:49:30 -10:00
assert ( second = = NULL , " monitor cannot occupy two stack slots " ) ;
2019-05-01 12:31:29 -07:00
ScopeValue * lock_data_value = get_scope_value ( jvmci_env ( ) - > get_StackLockValue_slot ( value ) , T_LONG , objects , second , JVMCI_CHECK_NULL ) ;
2015-10-08 12:49:30 -10:00
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 ( ) ;
bool eliminated = false ;
2019-05-01 12:31:29 -07:00
if ( jvmci_env ( ) - > get_StackLockValue_eliminated ( value ) ) {
2015-10-08 12:49:30 -10:00
eliminated = true ;
}
return new MonitorValue ( owner_value , lock_data_loc , eliminated ) ;
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : initialize_dependencies ( JVMCIObject compiled_code , OopRecorder * oop_recorder , JVMCI_TRAPS ) {
2015-10-08 12:49:30 -10:00
JavaThread * thread = JavaThread : : current ( ) ;
CompilerThread * compilerThread = thread - > is_Compiler_thread ( ) ? thread - > as_CompilerThread ( ) : NULL ;
2019-05-01 12:31:29 -07:00
_oop_recorder = oop_recorder ;
2015-10-08 12:49:30 -10:00
_dependencies = new Dependencies ( & _arena , _oop_recorder , compilerThread ! = NULL ? compilerThread - > log ( ) : NULL ) ;
2019-05-01 12:31:29 -07:00
JVMCIObjectArray assumptions = jvmci_env ( ) - > get_HotSpotCompiledCode_assumptions ( compiled_code ) ;
if ( assumptions . is_non_null ( ) ) {
int length = JVMCIENV - > get_length ( assumptions ) ;
2015-10-08 12:49:30 -10:00
for ( int i = 0 ; i < length ; + + i ) {
2019-05-01 12:31:29 -07:00
JVMCIObject assumption = JVMCIENV - > get_object_at ( assumptions , i ) ;
if ( assumption . is_non_null ( ) ) {
if ( jvmci_env ( ) - > isa_Assumptions_NoFinalizableSubclass ( assumption ) ) {
assumption_NoFinalizableSubclass ( assumption ) ;
} else if ( jvmci_env ( ) - > isa_Assumptions_ConcreteSubtype ( assumption ) ) {
assumption_ConcreteSubtype ( assumption ) ;
} else if ( jvmci_env ( ) - > isa_Assumptions_LeafType ( assumption ) ) {
assumption_LeafType ( assumption ) ;
} else if ( jvmci_env ( ) - > isa_Assumptions_ConcreteMethod ( assumption ) ) {
assumption_ConcreteMethod ( assumption ) ;
} else if ( jvmci_env ( ) - > isa_Assumptions_CallSiteTargetValue ( assumption ) ) {
assumption_CallSiteTargetValue ( assumption , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
} else {
2019-05-01 12:31:29 -07:00
JVMCI_ERROR ( " unexpected Assumption subclass %s " , jvmci_env ( ) - > klass_name ( assumption ) ) ;
2015-10-08 12:49:30 -10:00
}
}
}
}
2015-11-04 07:23:23 -10:00
if ( JvmtiExport : : can_hotswap_or_post_breakpoint ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCIObjectArray methods = jvmci_env ( ) - > get_HotSpotCompiledCode_methods ( compiled_code ) ;
if ( methods . is_non_null ( ) ) {
int length = JVMCIENV - > get_length ( methods ) ;
2015-11-04 07:23:23 -10:00
for ( int i = 0 ; i < length ; + + i ) {
2019-05-01 12:31:29 -07:00
JVMCIObject method_handle = JVMCIENV - > get_object_at ( methods , i ) ;
2019-11-13 08:23:23 -05:00
Method * method = jvmci_env ( ) - > asMethod ( method_handle ) ;
_dependencies - > assert_evol_method ( method ) ;
2015-11-04 07:23:23 -10:00
}
2015-10-08 12:49:30 -10:00
}
}
}
2018-11-02 00:26:25 -07:00
# if INCLUDE_AOT
2015-10-08 12:49:30 -10:00
RelocBuffer : : ~ RelocBuffer ( ) {
2019-09-11 14:16:30 +02:00
FREE_C_HEAP_ARRAY ( char , _buffer ) ;
2015-10-08 12:49:30 -10:00
}
address RelocBuffer : : begin ( ) const {
if ( _buffer ! = NULL ) {
return ( address ) _buffer ;
}
return ( address ) _static_buffer ;
}
void RelocBuffer : : set_size ( size_t bytes ) {
assert ( bytes < = _size , " can't grow in size! " ) ;
_size = bytes ;
}
void RelocBuffer : : ensure_size ( size_t bytes ) {
assert ( _buffer = = NULL , " can only be used once " ) ;
assert ( _size = = 0 , " can only be used once " ) ;
if ( bytes > = RelocBuffer : : stack_size ) {
2019-05-01 12:31:29 -07:00
_buffer = NEW_C_HEAP_ARRAY ( char , bytes , mtJVMCI ) ;
2015-10-08 12:49:30 -10:00
}
_size = bytes ;
}
2019-05-01 12:31:29 -07:00
JVMCI : : CodeInstallResult CodeInstaller : : gather_metadata ( JVMCIObject target , JVMCIObject compiled_code , CodeMetadata & metadata , JVMCI_TRAPS ) {
assert ( JVMCIENV - > is_hotspot ( ) , " AOT code is executed only in HotSpot mode " ) ;
2015-10-08 12:49:30 -10:00
CodeBuffer buffer ( " JVMCI Compiler CodeBuffer for Metadata " ) ;
2019-05-01 12:31:29 -07:00
AOTOopRecorder * recorder = new AOTOopRecorder ( this , & _arena , true ) ;
initialize_dependencies ( compiled_code , recorder , JVMCI_CHECK_OK ) ;
2016-12-11 19:07:04 -08:00
metadata . set_oop_recorder ( recorder ) ;
2015-10-08 12:49:30 -10:00
// Get instructions and constants CodeSections early because we need it.
_instructions = buffer . insts ( ) ;
_constants = buffer . consts ( ) ;
2018-05-14 12:03:59 +01:00
buffer . set_immutable_PIC ( _immutable_pic_compilation ) ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
initialize_fields ( target , compiled_code , JVMCI_CHECK_OK ) ;
JVMCI : : CodeInstallResult result = initialize_buffer ( buffer , false , JVMCI_CHECK_OK ) ;
if ( result ! = JVMCI : : ok ) {
2015-11-06 10:06:51 -10:00
return result ;
2015-10-08 12:49:30 -10:00
}
2016-05-18 21:50:27 +00:00
_debug_recorder - > pcs_size ( ) ; // create the sentinel record
2015-10-08 12:49:30 -10:00
assert ( _debug_recorder - > pcs_length ( ) > = 2 , " must be at least 2 " ) ;
metadata . set_pc_desc ( _debug_recorder - > pcs ( ) , _debug_recorder - > pcs_length ( ) ) ;
metadata . set_scopes ( _debug_recorder - > stream ( ) - > buffer ( ) , _debug_recorder - > data_size ( ) ) ;
metadata . set_exception_table ( & _exception_handler_table ) ;
2019-06-07 10:26:21 -07:00
metadata . set_implicit_exception_table ( & _implicit_exception_table ) ;
2015-10-08 12:49:30 -10:00
RelocBuffer * reloc_buffer = metadata . get_reloc_buffer ( ) ;
reloc_buffer - > ensure_size ( buffer . total_relocation_size ( ) ) ;
size_t size = ( size_t ) buffer . copy_relocations_to ( reloc_buffer - > begin ( ) , ( CodeBuffer : : csize_t ) reloc_buffer - > size ( ) , true ) ;
reloc_buffer - > set_size ( size ) ;
2019-05-01 12:31:29 -07:00
return JVMCI : : ok ;
2015-10-08 12:49:30 -10:00
}
2018-11-02 00:26:25 -07:00
# endif // INCLUDE_AOT
2015-10-08 12:49:30 -10:00
// constructor used to create a method
2019-05-01 12:31:29 -07:00
JVMCI : : CodeInstallResult CodeInstaller : : install ( JVMCICompiler * compiler ,
JVMCIObject target ,
JVMCIObject compiled_code ,
CodeBlob * & cb ,
JVMCIObject installed_code ,
FailedSpeculation * * failed_speculations ,
char * speculations ,
int speculations_len ,
JVMCI_TRAPS ) {
2015-10-08 12:49:30 -10:00
CodeBuffer buffer ( " JVMCI Compiler CodeBuffer " ) ;
OopRecorder * recorder = new OopRecorder ( & _arena , true ) ;
2019-05-01 12:31:29 -07:00
initialize_dependencies ( compiled_code , recorder , JVMCI_CHECK_OK ) ;
2015-10-08 12:49:30 -10:00
// Get instructions and constants CodeSections early because we need it.
_instructions = buffer . insts ( ) ;
_constants = buffer . consts ( ) ;
2018-05-14 12:03:59 +01:00
# if INCLUDE_AOT
buffer . set_immutable_PIC ( _immutable_pic_compilation ) ;
# endif
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
initialize_fields ( target , compiled_code , JVMCI_CHECK_OK ) ;
JVMCI : : CodeInstallResult result = initialize_buffer ( buffer , true , JVMCI_CHECK_OK ) ;
if ( result ! = JVMCI : : ok ) {
2015-10-08 12:49:30 -10:00
return result ;
}
int stack_slots = _total_frame_size / HeapWordSize ; // conversion to words
2019-05-01 12:31:29 -07:00
if ( ! jvmci_env ( ) - > isa_HotSpotCompiledNmethod ( compiled_code ) ) {
JVMCIObject stubName = jvmci_env ( ) - > get_HotSpotCompiledCode_name ( compiled_code ) ;
if ( stubName . is_null ( ) ) {
2018-01-04 14:44:38 -08:00
JVMCI_ERROR_OK ( " stub should have a name " ) ;
}
2019-05-01 12:31:29 -07:00
char * name = strdup ( jvmci_env ( ) - > as_utf8_string ( stubName ) ) ;
2015-10-08 12:49:30 -10:00
cb = RuntimeStub : : new_runtime_stub ( name ,
& buffer ,
CodeOffsets : : frame_never_safe ,
stack_slots ,
_debug_recorder - > _oopmaps ,
false ) ;
2019-05-01 12:31:29 -07:00
result = JVMCI : : ok ;
2015-10-08 12:49:30 -10:00
} else {
2019-05-01 12:31:29 -07:00
JVMCICompileState * compile_state = ( JVMCICompileState * ) ( address ) jvmci_env ( ) - > get_HotSpotCompiledNmethod_compileState ( compiled_code ) ;
if ( compile_state ! = NULL ) {
jvmci_env ( ) - > set_compile_state ( compile_state ) ;
}
2019-11-13 08:23:23 -05:00
Thread * thread = Thread : : current ( ) ;
methodHandle method ( thread , jvmci_env ( ) - > asMethod ( jvmci_env ( ) - > get_HotSpotCompiledNmethod_method ( compiled_code ) ) ) ;
2019-05-01 12:31:29 -07:00
jint entry_bci = jvmci_env ( ) - > get_HotSpotCompiledNmethod_entryBCI ( compiled_code ) ;
bool has_unsafe_access = jvmci_env ( ) - > get_HotSpotCompiledNmethod_hasUnsafeAccess ( compiled_code ) = = JNI_TRUE ;
jint id = jvmci_env ( ) - > get_HotSpotCompiledNmethod_id ( compiled_code ) ;
2015-10-08 12:49:30 -10:00
if ( id = = - 1 ) {
// Make sure a valid compile_id is associated with every compile
2019-11-13 08:23:23 -05:00
id = CompileBroker : : assign_compile_id_unlocked ( thread , method , entry_bci ) ;
2019-05-01 12:31:29 -07:00
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 ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
JVMCIObject mirror = installed_code ;
nmethod * nm = NULL ;
result = runtime ( ) - > register_method ( jvmci_env ( ) , method , nm , entry_bci , & _offsets , _orig_pc_offset , & buffer ,
2019-06-07 10:26:21 -07:00
stack_slots , _debug_recorder - > _oopmaps , & _exception_handler_table , & _implicit_exception_table ,
2019-05-01 12:31:29 -07:00
compiler , _debug_recorder , _dependencies , id ,
has_unsafe_access , _has_wide_vector , compiled_code , mirror ,
failed_speculations , speculations , speculations_len ) ;
2016-12-11 19:07:04 -08:00
cb = nm - > as_codeblob_or_null ( ) ;
2019-05-01 12:31:29 -07:00
if ( nm ! = NULL & & compile_state = = NULL ) {
2019-10-10 11:40:59 -07:00
// This compile didn't come through the CompileBroker so perform the printing here
2016-02-24 09:22:45 -08:00
DirectiveSet * directive = DirectivesStack : : getMatchingDirective ( method , compiler ) ;
2019-10-10 11:40:59 -07:00
nm - > maybe_print_nmethod ( directive ) ;
2016-02-24 09:22:45 -08:00
DirectivesStack : : release ( directive ) ;
}
2015-10-08 12:49:30 -10:00
}
if ( cb ! = NULL ) {
// Make sure the pre-calculated constants section size was correct.
2015-10-17 19:40:30 -04:00
guarantee ( ( cb - > code_begin ( ) - cb - > content_begin ( ) ) > = _constants_size , " %d < %d " , ( int ) ( cb - > code_begin ( ) - cb - > content_begin ( ) ) , _constants_size ) ;
2015-10-08 12:49:30 -10:00
}
return result ;
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : initialize_fields ( JVMCIObject target , JVMCIObject compiled_code , JVMCI_TRAPS ) {
if ( jvmci_env ( ) - > isa_HotSpotCompiledNmethod ( compiled_code ) ) {
JVMCIObject hotspotJavaMethod = jvmci_env ( ) - > get_HotSpotCompiledNmethod_method ( compiled_code ) ;
2019-11-13 08:23:23 -05:00
Thread * thread = Thread : : current ( ) ;
methodHandle method ( thread , jvmci_env ( ) - > asMethod ( hotspotJavaMethod ) ) ;
2015-10-08 12:49:30 -10:00
_parameter_count = method - > size_of_parameters ( ) ;
TRACE_jvmci_2 ( " installing code for %s " , method - > name_and_sig_as_C_string ( ) ) ;
} else {
// Must be a HotSpotCompiledRuntimeStub.
// Only used in OopMap constructor for non-product builds
_parameter_count = 0 ;
}
2019-05-01 12:31:29 -07:00
_sites_handle = jvmci_env ( ) - > get_HotSpotCompiledCode_sites ( compiled_code ) ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
_code_handle = jvmci_env ( ) - > get_HotSpotCompiledCode_targetCode ( compiled_code ) ;
_code_size = jvmci_env ( ) - > get_HotSpotCompiledCode_targetCodeSize ( compiled_code ) ;
_total_frame_size = jvmci_env ( ) - > get_HotSpotCompiledCode_totalFrameSize ( compiled_code ) ;
2016-02-03 12:16:44 +01:00
2019-05-01 12:31:29 -07:00
JVMCIObject deoptRescueSlot = jvmci_env ( ) - > get_HotSpotCompiledCode_deoptRescueSlot ( compiled_code ) ;
if ( deoptRescueSlot . is_null ( ) ) {
2016-02-03 12:16:44 +01:00
_orig_pc_offset = - 1 ;
} else {
2019-05-01 12:31:29 -07:00
_orig_pc_offset = jvmci_env ( ) - > get_StackSlot_offset ( deoptRescueSlot ) ;
if ( jvmci_env ( ) - > get_StackSlot_addFrameSize ( deoptRescueSlot ) ) {
2016-02-03 12:16:44 +01:00
_orig_pc_offset + = _total_frame_size ;
}
if ( _orig_pc_offset < 0 ) {
JVMCI_ERROR ( " invalid deopt rescue slot: %d " , _orig_pc_offset ) ;
}
}
2015-10-08 12:49:30 -10:00
// Pre-calculate the constants section size. This is required for PC-relative addressing.
2019-05-01 12:31:29 -07:00
_data_section_handle = jvmci_env ( ) - > get_HotSpotCompiledCode_dataSection ( compiled_code ) ;
if ( ( _constants - > alignment ( ) % jvmci_env ( ) - > get_HotSpotCompiledCode_dataSectionAlignment ( compiled_code ) ) ! = 0 ) {
JVMCI_ERROR ( " invalid data section alignment: %d " , jvmci_env ( ) - > get_HotSpotCompiledCode_dataSectionAlignment ( compiled_code ) ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
_constants_size = JVMCIENV - > get_length ( data_section ( ) ) ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
_data_section_patches_handle = jvmci_env ( ) - > get_HotSpotCompiledCode_dataSectionPatches ( compiled_code ) ;
2015-10-08 12:49:30 -10:00
# ifndef PRODUCT
2019-05-01 12:31:29 -07:00
_comments_handle = jvmci_env ( ) - > get_HotSpotCompiledCode_comments ( compiled_code ) ;
2015-10-08 12:49:30 -10:00
# endif
_next_call_type = INVOKE_INVALID ;
_has_wide_vector = false ;
2019-05-01 12:31:29 -07:00
JVMCIObject arch = jvmci_env ( ) - > get_TargetDescription_arch ( target ) ;
_word_kind_handle = jvmci_env ( ) - > get_Architecture_wordKind ( arch ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
int CodeInstaller : : estimate_stubs_size ( JVMCI_TRAPS ) {
2016-12-11 19:07:04 -08:00
// Estimate the number of static and aot call stubs that might be emitted.
2015-10-08 12:49:30 -10:00
int static_call_stubs = 0 ;
2016-12-11 19:07:04 -08:00
int aot_call_stubs = 0 ;
2018-01-03 17:29:20 +00:00
int trampoline_stubs = 0 ;
2019-05-01 12:31:29 -07:00
JVMCIObjectArray sites = this - > sites ( ) ;
for ( int i = 0 ; i < JVMCIENV - > get_length ( sites ) ; i + + ) {
JVMCIObject site = JVMCIENV - > get_object_at ( sites , i ) ;
if ( ! site . is_null ( ) ) {
if ( jvmci_env ( ) - > isa_site_Mark ( site ) ) {
JVMCIObject id_obj = jvmci_env ( ) - > get_site_Mark_id ( site ) ;
if ( id_obj . is_non_null ( ) ) {
if ( ! jvmci_env ( ) - > is_boxing_object ( T_INT , id_obj ) ) {
JVMCI_ERROR_0 ( " expected Integer id, got %s " , jvmci_env ( ) - > klass_name ( id_obj ) ) ;
2016-12-11 19:07:04 -08:00
}
2019-05-01 12:31:29 -07:00
jint id = jvmci_env ( ) - > get_boxed_value ( T_INT , id_obj ) . i ;
2018-01-03 17:29:20 +00:00
switch ( id ) {
2019-05-01 12:31:29 -07:00
case INVOKEINTERFACE :
case INVOKEVIRTUAL :
trampoline_stubs + + ;
break ;
case INVOKESTATIC :
case INVOKESPECIAL :
static_call_stubs + + ;
trampoline_stubs + + ;
break ;
default :
break ;
2016-12-11 19:07:04 -08:00
}
2015-11-06 10:06:51 -10:00
}
2016-12-11 19:07:04 -08:00
}
2018-11-02 00:26:25 -07:00
# if INCLUDE_AOT
2019-05-01 12:31:29 -07:00
if ( UseAOT & & jvmci_env ( ) - > isa_site_Call ( site ) ) {
JVMCIObject target = jvmci_env ( ) - > get_site_Call_target ( site ) ;
if ( ! jvmci_env ( ) - > isa_HotSpotForeignCallTarget ( target ) ) {
2016-12-11 19:07:04 -08:00
// Add far aot trampolines.
aot_call_stubs + + ;
2015-10-08 12:49:30 -10:00
}
}
2018-11-02 00:26:25 -07:00
# endif
2015-10-08 12:49:30 -10:00
}
}
2016-12-11 19:07:04 -08:00
int size = static_call_stubs * CompiledStaticCall : : to_interp_stub_size ( ) ;
2018-01-03 17:29:20 +00:00
size + = trampoline_stubs * CompiledStaticCall : : to_trampoline_stub_size ( ) ;
2016-12-11 19:07:04 -08:00
# if INCLUDE_AOT
size + = aot_call_stubs * CompiledStaticCall : : to_aot_stub_size ( ) ;
# endif
return size ;
2015-10-08 12:49:30 -10:00
}
// perform data and call relocation on the CodeBuffer
2019-05-01 12:31:29 -07:00
JVMCI : : CodeInstallResult CodeInstaller : : initialize_buffer ( CodeBuffer & buffer , bool check_size , JVMCI_TRAPS ) {
2015-11-04 07:23:23 -10:00
HandleMark hm ;
2019-05-01 12:31:29 -07:00
JVMCIObjectArray sites = this - > sites ( ) ;
int locs_buffer_size = JVMCIENV - > get_length ( sites ) * ( relocInfo : : length_limit + sizeof ( relocInfo ) ) ;
2015-10-08 12:49:30 -10:00
// 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.
2019-05-01 12:31:29 -07:00
int stubs_size = estimate_stubs_size ( JVMCI_CHECK_OK ) ;
2017-04-13 09:57:51 +02:00
int total_size = align_up ( _code_size , buffer . insts ( ) - > alignment ( ) ) + align_up ( _constants_size , buffer . consts ( ) - > alignment ( ) ) + align_up ( stubs_size , buffer . stubs ( ) - > alignment ( ) ) ;
2015-10-08 12:49:30 -10:00
2017-01-03 08:54:29 +01:00
if ( check_size & & total_size > JVMCINMethodSizeLimit ) {
2019-05-01 12:31:29 -07:00
return JVMCI : : code_too_large ;
2015-10-08 12:49:30 -10:00
}
buffer . initialize ( total_size , locs_buffer_size ) ;
if ( buffer . blob ( ) = = NULL ) {
2019-05-01 12:31:29 -07:00
return JVMCI : : cache_full ;
2015-10-08 12:49:30 -10:00
}
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 ;
2019-05-01 12:31:29 -07:00
JVMCIENV - > copy_bytes_to ( data_section ( ) , ( jbyte * ) _constants - > start ( ) , 0 , _constants_size ) ;
2015-10-08 12:49:30 -10:00
_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 " ) ;
2019-05-01 12:31:29 -07:00
JVMCIENV - > copy_bytes_to ( code ( ) , ( jbyte * ) _instructions - > start ( ) , 0 , _code_size ) ;
2015-10-08 12:49:30 -10:00
_instructions - > set_end ( end_pc ) ;
2019-05-01 12:31:29 -07:00
for ( int i = 0 ; i < JVMCIENV - > get_length ( data_section_patches ( ) ) ; i + + ) {
// HandleMark hm(THREAD);
JVMCIObject patch = JVMCIENV - > get_object_at ( data_section_patches ( ) , i ) ;
2015-11-06 10:06:51 -10:00
if ( patch . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_ ( NullPointerException , JVMCI : : ok ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
JVMCIObject reference = jvmci_env ( ) - > get_site_DataPatch_reference ( patch ) ;
2015-11-06 10:06:51 -10:00
if ( reference . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_ ( NullPointerException , JVMCI : : ok ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
if ( ! jvmci_env ( ) - > isa_site_ConstantReference ( reference ) ) {
JVMCI_ERROR_OK ( " invalid patch in data section: %s " , jvmci_env ( ) - > klass_name ( reference ) ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
JVMCIObject constant = jvmci_env ( ) - > get_site_ConstantReference_constant ( reference ) ;
2015-11-06 10:06:51 -10:00
if ( constant . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_ ( NullPointerException , JVMCI : : ok ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
address dest = _constants - > start ( ) + jvmci_env ( ) - > get_site_Site_pcOffset ( patch ) ;
if ( jvmci_env ( ) - > isa_HotSpotMetaspaceConstantImpl ( constant ) ) {
if ( jvmci_env ( ) - > get_HotSpotMetaspaceConstantImpl_compressed ( constant ) ) {
2015-11-04 07:23:23 -10:00
# ifdef _LP64
2019-05-01 12:31:29 -07:00
* ( ( narrowKlass * ) dest ) = record_narrow_metadata_reference ( _constants , dest , constant , JVMCI_CHECK_OK ) ;
2015-11-04 07:23:23 -10:00
# else
2015-11-06 10:06:51 -10:00
JVMCI_ERROR_OK ( " unexpected compressed Klass* in 32-bit mode " ) ;
2015-11-04 07:23:23 -10:00
# endif
} else {
2019-05-01 12:31:29 -07:00
* ( ( void * * ) dest ) = record_metadata_reference ( _constants , dest , constant , JVMCI_CHECK_OK ) ;
2015-11-04 07:23:23 -10:00
}
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_HotSpotObjectConstantImpl ( constant ) ) {
Handle obj = jvmci_env ( ) - > asConstant ( constant , JVMCI_CHECK_OK ) ;
2015-10-08 12:49:30 -10:00
jobject value = JNIHandles : : make_local ( obj ( ) ) ;
int oop_index = _oop_recorder - > find_index ( value ) ;
2019-05-01 12:31:29 -07:00
if ( jvmci_env ( ) - > get_HotSpotObjectConstantImpl_compressed ( constant ) ) {
2015-10-08 12:49:30 -10:00
# ifdef _LP64
_constants - > relocate ( dest , oop_Relocation : : spec ( oop_index ) , relocInfo : : narrow_oop_in_const ) ;
# else
2015-11-06 10:06:51 -10:00
JVMCI_ERROR_OK ( " unexpected compressed oop in 32-bit mode " ) ;
2015-10-08 12:49:30 -10:00
# endif
} else {
_constants - > relocate ( dest , oop_Relocation : : spec ( oop_index ) ) ;
}
} else {
2019-05-01 12:31:29 -07:00
JVMCI_ERROR_OK ( " invalid constant in data section: %s " , jvmci_env ( ) - > klass_name ( constant ) ) ;
2015-10-08 12:49:30 -10:00
}
}
jint last_pc_offset = - 1 ;
2019-05-01 12:31:29 -07:00
for ( int i = 0 ; i < JVMCIENV - > get_length ( sites ) ; i + + ) {
// HandleMark hm(THREAD);
JVMCIObject site = JVMCIENV - > get_object_at ( sites , i ) ;
2015-11-06 10:06:51 -10:00
if ( site . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_ ( NullPointerException , JVMCI : : ok ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
jint pc_offset = jvmci_env ( ) - > get_site_Site_pcOffset ( site ) ;
2015-11-06 10:06:51 -10:00
2019-05-01 12:31:29 -07:00
if ( jvmci_env ( ) - > isa_site_Call ( site ) ) {
2015-11-06 10:06:51 -10:00
TRACE_jvmci_4 ( " call at %i " , pc_offset ) ;
2019-05-01 12:31:29 -07:00
site_Call ( buffer , pc_offset , site , JVMCI_CHECK_OK ) ;
} else if ( jvmci_env ( ) - > isa_site_Infopoint ( site ) ) {
2015-11-06 10:06:51 -10:00
// three reasons for infopoints denote actual safepoints
2019-05-01 12:31:29 -07:00
JVMCIObject reason = jvmci_env ( ) - > get_site_Infopoint_reason ( site ) ;
if ( JVMCIENV - > equals ( reason , jvmci_env ( ) - > get_site_InfopointReason_SAFEPOINT ( ) ) | |
JVMCIENV - > equals ( reason , jvmci_env ( ) - > get_site_InfopointReason_CALL ( ) ) | |
JVMCIENV - > equals ( reason , jvmci_env ( ) - > get_site_InfopointReason_IMPLICIT_EXCEPTION ( ) ) ) {
2015-11-06 10:06:51 -10:00
TRACE_jvmci_4 ( " safepoint at %i " , pc_offset ) ;
2019-05-01 12:31:29 -07:00
site_Safepoint ( buffer , pc_offset , site , JVMCI_CHECK_OK ) ;
2016-02-03 12:16:44 +01:00
if ( _orig_pc_offset < 0 ) {
2016-02-05 11:33:27 +01:00
JVMCI_ERROR_OK ( " method contains safepoint, but has no deopt rescue slot " ) ;
2016-02-03 12:16:44 +01:00
}
2019-06-07 10:26:21 -07:00
if ( JVMCIENV - > equals ( reason , jvmci_env ( ) - > get_site_InfopointReason_IMPLICIT_EXCEPTION ( ) ) ) {
TRACE_jvmci_4 ( " implicit exception at %i " , pc_offset ) ;
_implicit_exception_table . add_deoptimize ( pc_offset ) ;
}
2015-11-06 10:06:51 -10:00
} else {
2015-11-30 15:40:07 -10:00
TRACE_jvmci_4 ( " infopoint at %i " , pc_offset ) ;
2019-05-01 12:31:29 -07:00
site_Infopoint ( buffer , pc_offset , site , JVMCI_CHECK_OK ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_site_DataPatch ( site ) ) {
2015-11-06 10:06:51 -10:00
TRACE_jvmci_4 ( " datapatch at %i " , pc_offset ) ;
2019-05-01 12:31:29 -07:00
site_DataPatch ( buffer , pc_offset , site , JVMCI_CHECK_OK ) ;
} else if ( jvmci_env ( ) - > isa_site_Mark ( site ) ) {
2015-11-06 10:06:51 -10:00
TRACE_jvmci_4 ( " mark at %i " , pc_offset ) ;
2019-05-01 12:31:29 -07:00
site_Mark ( buffer , pc_offset , site , JVMCI_CHECK_OK ) ;
} else if ( jvmci_env ( ) - > isa_site_ExceptionHandler ( site ) ) {
2016-01-20 14:22:46 +01:00
TRACE_jvmci_4 ( " exceptionhandler at %i " , pc_offset ) ;
site_ExceptionHandler ( pc_offset , site ) ;
2015-11-06 10:06:51 -10:00
} else {
2019-05-01 12:31:29 -07:00
JVMCI_ERROR_OK ( " unexpected site subclass: %s " , jvmci_env ( ) - > klass_name ( site ) ) ;
2015-10-08 12:49:30 -10:00
}
2015-11-06 10:06:51 -10:00
last_pc_offset = pc_offset ;
2017-08-31 10:00:28 +02:00
JavaThread * thread = JavaThread : : current ( ) ;
2018-11-08 14:32:49 +01:00
if ( SafepointMechanism : : should_block ( thread ) ) {
2015-10-08 12:49:30 -10:00
// this is a hacky way to force a safepoint check but nothing else was jumping out at me.
2017-08-31 10:00:28 +02:00
ThreadToNativeFromVM ttnfv ( thread ) ;
2015-10-08 12:49:30 -10:00
}
}
# ifndef PRODUCT
2019-05-01 12:31:29 -07:00
if ( comments ( ) . is_non_null ( ) ) {
for ( int i = 0 ; i < JVMCIENV - > get_length ( comments ( ) ) ; i + + ) {
JVMCIObject comment = JVMCIENV - > get_object_at ( comments ( ) , i ) ;
assert ( jvmci_env ( ) - > isa_HotSpotCompiledCode_Comment ( comment ) , " cce " ) ;
jint offset = jvmci_env ( ) - > get_HotSpotCompiledCode_Comment_pcOffset ( comment ) ;
const char * text = jvmci_env ( ) - > as_utf8_string ( jvmci_env ( ) - > get_HotSpotCompiledCode_Comment_text ( comment ) ) ;
2015-10-08 12:49:30 -10:00
buffer . block_comment ( offset , text ) ;
}
}
# endif
2019-05-01 12:31:29 -07:00
return JVMCI : : ok ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : assumption_NoFinalizableSubclass ( JVMCIObject assumption ) {
JVMCIObject receiverType_handle = jvmci_env ( ) - > get_Assumptions_NoFinalizableSubclass_receiverType ( assumption ) ;
Klass * receiverType = jvmci_env ( ) - > asKlass ( receiverType_handle ) ;
2015-10-08 12:49:30 -10:00
_dependencies - > assert_has_no_finalizable_subclasses ( receiverType ) ;
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : assumption_ConcreteSubtype ( JVMCIObject assumption ) {
JVMCIObject context_handle = jvmci_env ( ) - > get_Assumptions_ConcreteSubtype_context ( assumption ) ;
JVMCIObject subtype_handle = jvmci_env ( ) - > get_Assumptions_ConcreteSubtype_subtype ( assumption ) ;
Klass * context = jvmci_env ( ) - > asKlass ( context_handle ) ;
Klass * subtype = jvmci_env ( ) - > asKlass ( subtype_handle ) ;
2015-10-08 12:49:30 -10:00
assert ( context - > is_abstract ( ) , " " ) ;
_dependencies - > assert_abstract_with_unique_concrete_subtype ( context , subtype ) ;
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : assumption_LeafType ( JVMCIObject assumption ) {
JVMCIObject context_handle = jvmci_env ( ) - > get_Assumptions_LeafType_context ( assumption ) ;
Klass * context = jvmci_env ( ) - > asKlass ( context_handle ) ;
2015-10-08 12:49:30 -10:00
_dependencies - > assert_leaf_type ( context ) ;
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : assumption_ConcreteMethod ( JVMCIObject assumption ) {
JVMCIObject impl_handle = jvmci_env ( ) - > get_Assumptions_ConcreteMethod_impl ( assumption ) ;
JVMCIObject context_handle = jvmci_env ( ) - > get_Assumptions_ConcreteMethod_context ( assumption ) ;
2015-10-08 12:49:30 -10:00
2019-11-13 08:23:23 -05:00
Method * impl = jvmci_env ( ) - > asMethod ( impl_handle ) ;
2019-05-01 12:31:29 -07:00
Klass * context = jvmci_env ( ) - > asKlass ( context_handle ) ;
2015-10-08 12:49:30 -10:00
2019-11-13 08:23:23 -05:00
_dependencies - > assert_unique_concrete_method ( context , impl ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : assumption_CallSiteTargetValue ( JVMCIObject assumption , JVMCI_TRAPS ) {
JVMCIObject callSiteConstant = jvmci_env ( ) - > get_Assumptions_CallSiteTargetValue_callSite ( assumption ) ;
Handle callSite = jvmci_env ( ) - > asConstant ( callSiteConstant , JVMCI_CHECK ) ;
JVMCIObject methodConstant = jvmci_env ( ) - > get_Assumptions_CallSiteTargetValue_methodHandle ( assumption ) ;
Handle methodHandle = jvmci_env ( ) - > asConstant ( methodConstant , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
_dependencies - > assert_call_site_target_value ( callSite ( ) , methodHandle ( ) ) ;
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : site_ExceptionHandler ( jint pc_offset , JVMCIObject exc ) {
jint handler_offset = jvmci_env ( ) - > get_site_ExceptionHandler_handlerPos ( exc ) ;
2015-10-08 12:49:30 -10:00
2016-01-20 14:22:46 +01:00
// Subtable header
_exception_handler_table . add_entry ( HandlerTableEntry ( 1 , pc_offset , 0 ) ) ;
2015-10-08 12:49:30 -10:00
2016-01-20 14:22:46 +01:00
// Subtable entry
_exception_handler_table . add_entry ( HandlerTableEntry ( - 1 , handler_offset , 0 ) ) ;
2015-10-08 12:49:30 -10:00
}
// If deoptimization happens, the interpreter should reexecute these bytecodes.
// This function mainly helps the compilers to set up the reexecute bit.
static bool bytecode_should_reexecute ( Bytecodes : : Code code ) {
switch ( code ) {
case Bytecodes : : _invokedynamic :
case Bytecodes : : _invokevirtual :
case Bytecodes : : _invokeinterface :
case Bytecodes : : _invokespecial :
case Bytecodes : : _invokestatic :
return false ;
default :
return true ;
}
return true ;
}
2019-05-01 12:31:29 -07:00
GrowableArray < ScopeValue * > * CodeInstaller : : record_virtual_objects ( JVMCIObject debug_info , JVMCI_TRAPS ) {
JVMCIObjectArray virtualObjects = jvmci_env ( ) - > get_DebugInfo_virtualObjectMapping ( debug_info ) ;
2015-11-06 10:06:51 -10:00
if ( virtualObjects . is_null ( ) ) {
2015-10-08 12:49:30 -10:00
return NULL ;
}
2019-05-01 12:31:29 -07:00
GrowableArray < ScopeValue * > * objects = new GrowableArray < ScopeValue * > ( JVMCIENV - > get_length ( virtualObjects ) , JVMCIENV - > get_length ( virtualObjects ) , NULL ) ;
2015-10-08 12:49:30 -10:00
// Create the unique ObjectValues
2019-05-01 12:31:29 -07:00
for ( int i = 0 ; i < JVMCIENV - > get_length ( virtualObjects ) ; i + + ) {
// HandleMark hm(THREAD);
JVMCIObject value = JVMCIENV - > get_object_at ( virtualObjects , i ) ;
int id = jvmci_env ( ) - > get_VirtualObject_id ( value ) ;
JVMCIObject type = jvmci_env ( ) - > get_VirtualObject_type ( value ) ;
2019-06-03 13:21:02 -07:00
bool is_auto_box = jvmci_env ( ) - > get_VirtualObject_isAutoBox ( value ) ;
2019-05-01 12:31:29 -07:00
Klass * klass = jvmci_env ( ) - > asKlass ( type ) ;
oop javaMirror = klass - > java_mirror ( ) ;
2019-06-03 13:21:02 -07:00
ScopeValue * klass_sv = new ConstantOopWriteValue ( JNIHandles : : make_local ( Thread : : current ( ) , javaMirror ) ) ;
ObjectValue * sv = is_auto_box ? new AutoBoxObjectValue ( id , klass_sv ) : new ObjectValue ( id , klass_sv ) ;
2015-11-06 10:06:51 -10:00
if ( id < 0 | | id > = objects - > length ( ) ) {
JVMCI_ERROR_NULL ( " virtual object id %d out of bounds " , id ) ;
}
if ( objects - > at ( id ) ! = NULL ) {
JVMCI_ERROR_NULL ( " duplicate virtual object id %d " , id ) ;
}
2015-10-08 12:49:30 -10:00
objects - > at_put ( id , sv ) ;
}
// All the values which could be referenced by the VirtualObjects
// exist, so now describe all the VirtualObjects themselves.
2019-05-01 12:31:29 -07:00
for ( int i = 0 ; i < JVMCIENV - > get_length ( virtualObjects ) ; i + + ) {
// HandleMark hm(THREAD);
JVMCIObject value = JVMCIENV - > get_object_at ( virtualObjects , i ) ;
int id = jvmci_env ( ) - > get_VirtualObject_id ( value ) ;
record_object_value ( objects - > at ( id ) - > as_ObjectValue ( ) , value , objects , JVMCI_CHECK_NULL ) ;
2015-10-08 12:49:30 -10:00
}
_debug_recorder - > dump_object_pool ( objects ) ;
return objects ;
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : record_scope ( jint pc_offset , JVMCIObject debug_info , ScopeMode scope_mode , bool return_oop , JVMCI_TRAPS ) {
JVMCIObject position = jvmci_env ( ) - > get_DebugInfo_bytecodePosition ( debug_info ) ;
2015-11-06 10:06:51 -10:00
if ( position . is_null ( ) ) {
2015-10-08 12:49:30 -10:00
// Stubs do not record scope info, just oop maps
return ;
}
2015-11-30 15:40:07 -10:00
GrowableArray < ScopeValue * > * objectMapping ;
if ( scope_mode = = CodeInstaller : : FullFrame ) {
2019-05-01 12:31:29 -07:00
objectMapping = record_virtual_objects ( debug_info , JVMCI_CHECK ) ;
2015-11-30 15:40:07 -10:00
} else {
objectMapping = NULL ;
}
2019-05-01 12:31:29 -07:00
record_scope ( pc_offset , position , scope_mode , objectMapping , return_oop , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
}
2018-06-22 15:58:32 -07:00
int CodeInstaller : : map_jvmci_bci ( int bci ) {
if ( bci < 0 ) {
2019-05-01 12:31:29 -07:00
if ( bci = = jvmci_env ( ) - > get_BytecodeFrame_BEFORE_BCI ( ) ) {
2018-06-22 15:58:32 -07:00
return BeforeBci ;
2019-05-01 12:31:29 -07:00
} else if ( bci = = jvmci_env ( ) - > get_BytecodeFrame_AFTER_BCI ( ) ) {
2018-06-22 15:58:32 -07:00
return AfterBci ;
2019-05-01 12:31:29 -07:00
} else if ( bci = = jvmci_env ( ) - > get_BytecodeFrame_UNWIND_BCI ( ) ) {
2018-06-22 15:58:32 -07:00
return UnwindBci ;
2019-05-01 12:31:29 -07:00
} else if ( bci = = jvmci_env ( ) - > get_BytecodeFrame_AFTER_EXCEPTION_BCI ( ) ) {
2018-06-22 15:58:32 -07:00
return AfterExceptionBci ;
2019-05-01 12:31:29 -07:00
} else if ( bci = = jvmci_env ( ) - > get_BytecodeFrame_UNKNOWN_BCI ( ) ) {
2018-06-22 15:58:32 -07:00
return UnknownBci ;
2019-05-01 12:31:29 -07:00
} else if ( bci = = jvmci_env ( ) - > get_BytecodeFrame_INVALID_FRAMESTATE_BCI ( ) ) {
2018-06-22 15:58:32 -07:00
return InvalidFrameStateBci ;
}
ShouldNotReachHere ( ) ;
}
return bci ;
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : record_scope ( jint pc_offset , JVMCIObject position , ScopeMode scope_mode , GrowableArray < ScopeValue * > * objects , bool return_oop , JVMCI_TRAPS ) {
JVMCIObject frame ;
2015-11-30 15:40:07 -10:00
if ( scope_mode = = CodeInstaller : : FullFrame ) {
2019-05-01 12:31:29 -07:00
if ( ! jvmci_env ( ) - > isa_BytecodeFrame ( position ) ) {
2015-11-30 15:40:07 -10:00
JVMCI_ERROR ( " Full frame expected for debug info at %i " , pc_offset ) ;
}
2015-10-08 12:49:30 -10:00
frame = position ;
}
2019-05-01 12:31:29 -07:00
JVMCIObject caller_frame = jvmci_env ( ) - > get_BytecodePosition_caller ( position ) ;
if ( caller_frame . is_non_null ( ) ) {
record_scope ( pc_offset , caller_frame , scope_mode , objects , return_oop , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
JVMCIObject hotspot_method = jvmci_env ( ) - > get_BytecodePosition_method ( position ) ;
2019-11-13 08:23:23 -05:00
Thread * thread = Thread : : current ( ) ;
methodHandle method ( thread , jvmci_env ( ) - > asMethod ( hotspot_method ) ) ;
2019-05-01 12:31:29 -07:00
jint bci = map_jvmci_bci ( jvmci_env ( ) - > get_BytecodePosition_bci ( position ) ) ;
if ( bci = = jvmci_env ( ) - > get_BytecodeFrame_BEFORE_BCI ( ) ) {
bci = SynchronizationEntryBCI ;
}
2015-10-08 12:49:30 -10:00
TRACE_jvmci_2 ( " Recording scope pc_offset=%d bci=%d method=%s " , pc_offset , bci , method - > name_and_sig_as_C_string ( ) ) ;
bool reexecute = false ;
2019-05-01 12:31:29 -07:00
if ( frame . is_non_null ( ) ) {
if ( bci < 0 ) {
2015-10-08 12:49:30 -10:00
reexecute = false ;
} else {
2019-11-13 08:23:23 -05:00
Bytecodes : : Code code = Bytecodes : : java_code_at ( method ( ) , method - > bcp_from ( bci ) ) ;
2015-10-08 12:49:30 -10:00
reexecute = bytecode_should_reexecute ( code ) ;
2019-05-01 12:31:29 -07:00
if ( frame . is_non_null ( ) ) {
reexecute = ( jvmci_env ( ) - > get_BytecodeFrame_duringCall ( frame ) = = JNI_FALSE ) ;
2015-10-08 12:49:30 -10:00
}
}
}
DebugToken * locals_token = NULL ;
DebugToken * expressions_token = NULL ;
DebugToken * monitors_token = NULL ;
bool throw_exception = false ;
2019-05-01 12:31:29 -07:00
if ( frame . is_non_null ( ) ) {
jint local_count = jvmci_env ( ) - > get_BytecodeFrame_numLocals ( frame ) ;
jint expression_count = jvmci_env ( ) - > get_BytecodeFrame_numStack ( frame ) ;
jint monitor_count = jvmci_env ( ) - > get_BytecodeFrame_numLocks ( frame ) ;
JVMCIObjectArray values = jvmci_env ( ) - > get_BytecodeFrame_values ( frame ) ;
JVMCIObjectArray slotKinds = jvmci_env ( ) - > get_BytecodeFrame_slotKinds ( frame ) ;
2015-10-08 12:49:30 -10:00
2015-11-06 10:06:51 -10:00
if ( values . is_null ( ) | | slotKinds . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW ( NullPointerException ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
if ( local_count + expression_count + monitor_count ! = JVMCIENV - > get_length ( values ) ) {
JVMCI_ERROR ( " unexpected values length %d in scope (%d locals, %d expressions, %d monitors) " , JVMCIENV - > get_length ( values ) , local_count , expression_count , monitor_count ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
if ( local_count + expression_count ! = JVMCIENV - > get_length ( slotKinds ) ) {
JVMCI_ERROR ( " unexpected slotKinds length %d in scope (%d locals, %d expressions) " , JVMCIENV - > get_length ( slotKinds ) , local_count , expression_count ) ;
2015-11-06 10:06:51 -10:00
}
2015-10-08 12:49:30 -10:00
GrowableArray < ScopeValue * > * locals = local_count > 0 ? new GrowableArray < ScopeValue * > ( local_count ) : NULL ;
GrowableArray < ScopeValue * > * expressions = expression_count > 0 ? new GrowableArray < ScopeValue * > ( expression_count ) : NULL ;
GrowableArray < MonitorValue * > * monitors = monitor_count > 0 ? new GrowableArray < MonitorValue * > ( monitor_count ) : NULL ;
2019-05-01 12:31:29 -07:00
TRACE_jvmci_2 ( " Scope at bci %d with %d values " , bci , JVMCIENV - > get_length ( values ) ) ;
2015-10-08 12:49:30 -10:00
TRACE_jvmci_2 ( " %d locals %d expressions, %d monitors " , local_count , expression_count , monitor_count ) ;
2019-05-01 12:31:29 -07:00
for ( jint i = 0 ; i < JVMCIENV - > get_length ( values ) ; i + + ) {
// HandleMark hm(THREAD);
2015-10-08 12:49:30 -10:00
ScopeValue * second = NULL ;
2019-05-01 12:31:29 -07:00
JVMCIObject value = JVMCIENV - > get_object_at ( values , i ) ;
2015-10-08 12:49:30 -10:00
if ( i < local_count ) {
2019-05-01 12:31:29 -07:00
BasicType type = jvmci_env ( ) - > kindToBasicType ( JVMCIENV - > get_object_at ( slotKinds , i ) , JVMCI_CHECK ) ;
ScopeValue * first = get_scope_value ( value , type , objects , second , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
if ( second ! = NULL ) {
locals - > append ( second ) ;
}
locals - > append ( first ) ;
} else if ( i < local_count + expression_count ) {
2019-05-01 12:31:29 -07:00
BasicType type = jvmci_env ( ) - > kindToBasicType ( JVMCIENV - > get_object_at ( slotKinds , i ) , JVMCI_CHECK ) ;
ScopeValue * first = get_scope_value ( value , type , objects , second , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
if ( second ! = NULL ) {
expressions - > append ( second ) ;
}
expressions - > append ( first ) ;
} else {
2019-05-01 12:31:29 -07:00
MonitorValue * monitor = get_monitor_value ( value , objects , JVMCI_CHECK ) ;
2015-11-06 10:06:51 -10:00
monitors - > append ( monitor ) ;
2015-10-08 12:49:30 -10:00
}
if ( second ! = NULL ) {
i + + ;
2019-05-01 12:31:29 -07:00
if ( i > = JVMCIENV - > get_length ( values ) | | ! JVMCIENV - > equals ( JVMCIENV - > get_object_at ( values , i ) , jvmci_env ( ) - > get_Value_ILLEGAL ( ) ) ) {
2015-11-06 10:06:51 -10:00
JVMCI_ERROR ( " double-slot value not followed by Value.ILLEGAL " ) ;
}
2015-10-08 12:49:30 -10:00
}
}
locals_token = _debug_recorder - > create_scope_values ( locals ) ;
expressions_token = _debug_recorder - > create_scope_values ( expressions ) ;
monitors_token = _debug_recorder - > create_monitor_values ( monitors ) ;
2019-05-01 12:31:29 -07:00
throw_exception = jvmci_env ( ) - > get_BytecodeFrame_rethrowException ( frame ) = = JNI_TRUE ;
2015-10-08 12:49:30 -10:00
}
2016-12-20 20:38:14 -08:00
_debug_recorder - > describe_scope ( pc_offset , method , NULL , bci , reexecute , throw_exception , false , return_oop ,
2015-10-08 12:49:30 -10:00
locals_token , expressions_token , monitors_token ) ;
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : site_Safepoint ( CodeBuffer & buffer , jint pc_offset , JVMCIObject site , JVMCI_TRAPS ) {
JVMCIObject debug_info = jvmci_env ( ) - > get_site_Infopoint_debugInfo ( site ) ;
2015-11-06 10:06:51 -10:00
if ( debug_info . is_null ( ) ) {
JVMCI_ERROR ( " debug info expected at safepoint at %i " , pc_offset ) ;
}
2015-10-08 12:49:30 -10:00
// address instruction = _instructions->start() + pc_offset;
// jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();
2019-05-01 12:31:29 -07:00
OopMap * map = create_oop_map ( debug_info , JVMCI_CHECK ) ;
2015-11-06 10:06:51 -10:00
_debug_recorder - > add_safepoint ( pc_offset , map ) ;
2019-05-01 12:31:29 -07:00
record_scope ( pc_offset , debug_info , CodeInstaller : : FullFrame , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
_debug_recorder - > end_safepoint ( pc_offset ) ;
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : site_Infopoint ( CodeBuffer & buffer , jint pc_offset , JVMCIObject site , JVMCI_TRAPS ) {
JVMCIObject debug_info = jvmci_env ( ) - > get_site_Infopoint_debugInfo ( site ) ;
2015-11-06 10:06:51 -10:00
if ( debug_info . is_null ( ) ) {
JVMCI_ERROR ( " debug info expected at infopoint at %i " , pc_offset ) ;
}
2015-10-08 12:49:30 -10:00
2015-11-30 15:40:07 -10:00
// We'd like to check that pc_offset is greater than the
// last pc recorded with _debug_recorder (raising an exception if not)
// but DebugInformationRecorder doesn't have sufficient public API.
2015-10-08 12:49:30 -10:00
_debug_recorder - > add_non_safepoint ( pc_offset ) ;
2019-05-01 12:31:29 -07:00
record_scope ( pc_offset , debug_info , CodeInstaller : : BytecodePosition , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
_debug_recorder - > end_non_safepoint ( pc_offset ) ;
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : site_Call ( CodeBuffer & buffer , jint pc_offset , JVMCIObject site , JVMCI_TRAPS ) {
JVMCIObject target = jvmci_env ( ) - > get_site_Call_target ( site ) ;
JVMCIObject hotspot_method ; // JavaMethod
JVMCIObject foreign_call ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
if ( jvmci_env ( ) - > isa_HotSpotForeignCallTarget ( target ) ) {
2015-10-08 12:49:30 -10:00
foreign_call = target ;
} else {
hotspot_method = target ;
}
2019-05-01 12:31:29 -07:00
JVMCIObject debug_info = jvmci_env ( ) - > get_site_Infopoint_debugInfo ( site ) ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
assert ( hotspot_method . is_non_null ( ) ^ foreign_call . is_non_null ( ) , " Call site needs exactly one type " ) ;
2015-10-08 12:49:30 -10:00
NativeInstruction * inst = nativeInstruction_at ( _instructions - > start ( ) + pc_offset ) ;
2019-05-01 12:31:29 -07:00
jint next_pc_offset = CodeInstaller : : pd_next_offset ( inst , pc_offset , hotspot_method , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
if ( debug_info . is_non_null ( ) ) {
OopMap * map = create_oop_map ( debug_info , JVMCI_CHECK ) ;
2015-11-06 10:06:51 -10:00
_debug_recorder - > add_safepoint ( next_pc_offset , map ) ;
2016-12-20 20:38:14 -08:00
2019-05-01 12:31:29 -07:00
bool return_oop = hotspot_method . is_non_null ( ) & & jvmci_env ( ) - > asMethod ( hotspot_method ) - > is_returning_oop ( ) ;
2016-12-20 20:38:14 -08:00
2019-05-01 12:31:29 -07:00
record_scope ( next_pc_offset , debug_info , CodeInstaller : : FullFrame , return_oop , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
if ( foreign_call . is_non_null ( ) ) {
jlong foreign_call_destination = jvmci_env ( ) - > get_HotSpotForeignCallTarget_address ( foreign_call ) ;
2016-12-11 19:07:04 -08:00
if ( _immutable_pic_compilation ) {
// Use fake short distance during PIC compilation.
foreign_call_destination = ( jlong ) ( _instructions - > start ( ) + pc_offset ) ;
}
2019-05-01 12:31:29 -07:00
CodeInstaller : : pd_relocate_ForeignCall ( inst , foreign_call_destination , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
} else { // method != NULL
2015-11-06 10:06:51 -10:00
if ( debug_info . is_null ( ) ) {
JVMCI_ERROR ( " debug info expected at call at %i " , pc_offset ) ;
}
2015-10-08 12:49:30 -10:00
TRACE_jvmci_3 ( " method call " ) ;
2019-05-01 12:31:29 -07:00
CodeInstaller : : pd_relocate_JavaMethod ( buffer , hotspot_method , pc_offset , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
if ( _next_call_type = = INVOKESTATIC | | _next_call_type = = INVOKESPECIAL ) {
// Need a static call stub for transitions from compiled to interpreted.
CompiledStaticCall : : emit_to_interp_stub ( buffer , _instructions - > start ( ) + pc_offset ) ;
}
2016-12-11 19:07:04 -08:00
# if INCLUDE_AOT
// Trampoline to far aot code.
CompiledStaticCall : : emit_to_aot_stub ( buffer , _instructions - > start ( ) + pc_offset ) ;
# endif
2015-10-08 12:49:30 -10:00
}
_next_call_type = INVOKE_INVALID ;
2019-05-01 12:31:29 -07:00
if ( debug_info . is_non_null ( ) ) {
2015-10-08 12:49:30 -10:00
_debug_recorder - > end_safepoint ( next_pc_offset ) ;
}
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : site_DataPatch ( CodeBuffer & buffer , jint pc_offset , JVMCIObject site , JVMCI_TRAPS ) {
JVMCIObject reference = jvmci_env ( ) - > get_site_DataPatch_reference ( site ) ;
2015-11-06 10:06:51 -10:00
if ( reference . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW ( NullPointerException ) ;
} else if ( jvmci_env ( ) - > isa_site_ConstantReference ( reference ) ) {
JVMCIObject constant = jvmci_env ( ) - > get_site_ConstantReference_constant ( reference ) ;
2015-11-06 10:06:51 -10:00
if ( constant . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW ( NullPointerException ) ;
} else if ( jvmci_env ( ) - > isa_DirectHotSpotObjectConstantImpl ( constant ) ) {
if ( ! JVMCIENV - > is_hotspot ( ) ) {
JVMCIObject string = JVMCIENV - > call_HotSpotJVMCIRuntime_callToString ( constant , JVMCI_CHECK ) ;
const char * to_string = JVMCIENV - > as_utf8_string ( string ) ;
JVMCI_THROW_MSG ( IllegalArgumentException , err_msg ( " Direct object constant reached the backend: %s " , to_string ) ) ;
}
if ( ! _immutable_pic_compilation ) {
// Do not patch during PIC compilation.
pd_patch_OopConstant ( pc_offset , constant , JVMCI_CHECK ) ;
}
} else if ( jvmci_env ( ) - > isa_IndirectHotSpotObjectConstantImpl ( constant ) ) {
2016-12-11 19:07:04 -08:00
if ( ! _immutable_pic_compilation ) {
// Do not patch during PIC compilation.
2019-05-01 12:31:29 -07:00
pd_patch_OopConstant ( pc_offset , constant , JVMCI_CHECK ) ;
2016-12-11 19:07:04 -08:00
}
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_HotSpotMetaspaceConstantImpl ( constant ) ) {
2016-12-11 19:07:04 -08:00
if ( ! _immutable_pic_compilation ) {
2019-05-01 12:31:29 -07:00
pd_patch_MetaspaceConstant ( pc_offset , constant , JVMCI_CHECK ) ;
2016-12-11 19:07:04 -08:00
}
2018-11-02 00:26:25 -07:00
# if INCLUDE_AOT
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_HotSpotSentinelConstant ( constant ) ) {
2016-12-11 19:07:04 -08:00
if ( ! _immutable_pic_compilation ) {
2019-05-01 12:31:29 -07:00
JVMCI_ERROR ( " sentinel constant not supported for normal compiles: %s " , jvmci_env ( ) - > klass_name ( constant ) ) ;
2016-12-11 19:07:04 -08:00
}
2018-11-02 00:26:25 -07:00
# endif
2015-10-08 12:49:30 -10:00
} else {
2019-05-01 12:31:29 -07:00
JVMCI_ERROR ( " unknown constant type in data patch: %s " , jvmci_env ( ) - > klass_name ( constant ) ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
} else if ( jvmci_env ( ) - > isa_site_DataSectionReference ( reference ) ) {
int data_offset = jvmci_env ( ) - > get_site_DataSectionReference_offset ( reference ) ;
2015-11-06 10:06:51 -10:00
if ( 0 < = data_offset & & data_offset < _constants_size ) {
2019-05-01 12:31:29 -07:00
pd_patch_DataSectionReference ( pc_offset , data_offset , JVMCI_CHECK ) ;
2015-11-06 10:06:51 -10:00
} else {
JVMCI_ERROR ( " data offset 0x%X points outside data section (size 0x%X) " , data_offset , _constants_size ) ;
}
2015-10-08 12:49:30 -10:00
} else {
2019-05-01 12:31:29 -07:00
JVMCI_ERROR ( " unknown data patch type: %s " , jvmci_env ( ) - > klass_name ( reference ) ) ;
2015-10-08 12:49:30 -10:00
}
}
2019-05-01 12:31:29 -07:00
void CodeInstaller : : site_Mark ( CodeBuffer & buffer , jint pc_offset , JVMCIObject site , JVMCI_TRAPS ) {
JVMCIObject id_obj = jvmci_env ( ) - > get_site_Mark_id ( site ) ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
if ( id_obj . is_non_null ( ) ) {
if ( ! jvmci_env ( ) - > is_boxing_object ( T_INT , id_obj ) ) {
JVMCI_ERROR ( " expected Integer id, got %s " , jvmci_env ( ) - > klass_name ( id_obj ) ) ;
2015-11-06 10:06:51 -10:00
}
2019-05-01 12:31:29 -07:00
jint id = jvmci_env ( ) - > get_boxed_value ( T_INT , id_obj ) . i ;
2015-10-08 12:49:30 -10:00
address pc = _instructions - > start ( ) + pc_offset ;
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 INVOKEVIRTUAL :
case INVOKEINTERFACE :
case INLINE_INVOKE :
case INVOKESTATIC :
case INVOKESPECIAL :
_next_call_type = ( MarkId ) id ;
_invoke_mark_pc = pc ;
break ;
case POLL_NEAR :
case POLL_FAR :
case POLL_RETURN_NEAR :
case POLL_RETURN_FAR :
2019-05-01 12:31:29 -07:00
pd_relocate_poll ( pc , id , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
break ;
2015-11-04 07:23:23 -10:00
case CARD_TABLE_SHIFT :
2015-10-08 12:49:30 -10:00
case CARD_TABLE_ADDRESS :
case HEAP_TOP_ADDRESS :
case HEAP_END_ADDRESS :
case NARROW_KLASS_BASE_ADDRESS :
2017-01-10 21:39:20 +03:00
case NARROW_OOP_BASE_ADDRESS :
2015-10-08 12:49:30 -10:00
case CRC_TABLE_ADDRESS :
2016-12-11 19:07:04 -08:00
case LOG_OF_HEAP_REGION_GRAIN_BYTES :
case INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED :
2015-10-08 12:49:30 -10:00
break ;
default :
2015-11-06 10:06:51 -10:00
JVMCI_ERROR ( " invalid mark id: %d " , id ) ;
2015-10-08 12:49:30 -10:00
break ;
}
}
}