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"
2019-10-29 15:35:06 -07:00
# include "classfile/classLoaderData.inline.hpp"
2018-03-09 12:38:54 -08:00
# include "classfile/javaClasses.inline.hpp"
2019-05-01 12:31:29 -07:00
# include "classfile/stringTable.hpp"
# include "classfile/symbolTable.hpp"
2015-10-08 12:49:30 -10:00
# include "code/scopeDesc.hpp"
# include "compiler/compileBroker.hpp"
# include "compiler/disassembler.hpp"
2019-05-01 12:31:29 -07:00
# include "interpreter/linkResolver.hpp"
# include "interpreter/bytecodeStream.hpp"
2015-10-08 12:49:30 -10:00
# include "jvmci/jvmciCompilerToVM.hpp"
# include "jvmci/jvmciCodeInstaller.hpp"
2018-03-09 10:15:22 -08:00
# include "jvmci/jvmciRuntime.hpp"
2019-11-11 12:11:34 -05:00
# include "logging/log.hpp"
# include "logging/logTag.hpp"
2019-05-01 12:31:29 -07:00
# include "memory/oopFactory.hpp"
2019-05-09 14:28:30 +02:00
# include "memory/universe.hpp"
2019-05-01 12:31:29 -07:00
# include "oops/constantPool.inline.hpp"
# include "oops/method.inline.hpp"
# include "oops/typeArrayOop.inline.hpp"
# include "prims/nativeLookup.hpp"
# include "runtime/deoptimization.hpp"
2018-08-20 13:58:23 -07:00
# include "runtime/fieldDescriptor.inline.hpp"
2018-03-21 19:45:24 -04:00
# include "runtime/frame.inline.hpp"
2018-03-16 09:12:13 -04:00
# include "runtime/interfaceSupport.inline.hpp"
2018-03-09 10:15:22 -08:00
# include "runtime/jniHandles.inline.hpp"
2016-03-15 14:41:07 +01:00
# include "runtime/timerTrace.hpp"
2015-10-08 12:49:30 -10:00
# include "runtime/vframe_hp.hpp"
2018-06-24 21:46:11 -07:00
JVMCIKlassHandle : : JVMCIKlassHandle ( Thread * thread , Klass * klass ) {
_thread = thread ;
_klass = klass ;
if ( klass ! = NULL ) {
2018-12-07 14:48:35 -05:00
_holder = Handle ( _thread , klass - > klass_holder ( ) ) ;
2018-06-24 21:46:11 -07:00
}
}
JVMCIKlassHandle & JVMCIKlassHandle : : operator = ( Klass * klass ) {
_klass = klass ;
if ( klass ! = NULL ) {
2018-12-07 14:48:35 -05:00
_holder = Handle ( _thread , klass - > klass_holder ( ) ) ;
2018-06-24 21:46:11 -07:00
}
return * this ;
}
2015-10-08 12:49:30 -10:00
2019-05-06 20:05:19 -07:00
static void requireInHotSpot ( const char * caller , JVMCI_TRAPS ) {
if ( ! JVMCIENV - > is_hotspot ( ) ) {
JVMCI_THROW_MSG ( IllegalStateException , err_msg ( " Cannot call %s from JVMCI shared library " , caller ) ) ;
}
}
void JNIHandleMark : : push_jni_handle_block ( JavaThread * thread ) {
2017-02-27 17:36:36 +01:00
if ( thread ! = NULL ) {
// Allocate a new block for JNI handles.
// Inlined code from jni_PushLocalFrame()
2019-05-06 20:05:19 -07:00
JNIHandleBlock * java_handles = thread - > active_handles ( ) ;
2017-02-27 17:36:36 +01:00
JNIHandleBlock * compile_handles = JNIHandleBlock : : allocate_block ( thread ) ;
assert ( compile_handles ! = NULL & & java_handles ! = NULL , " should not be NULL " ) ;
compile_handles - > set_pop_frame_link ( java_handles ) ;
thread - > set_active_handles ( compile_handles ) ;
}
}
2019-05-06 20:05:19 -07:00
void JNIHandleMark : : pop_jni_handle_block ( JavaThread * thread ) {
2017-02-27 17:36:36 +01:00
if ( thread ! = NULL ) {
// Release our JNI handle block
JNIHandleBlock * compile_handles = thread - > active_handles ( ) ;
JNIHandleBlock * java_handles = compile_handles - > pop_frame_link ( ) ;
thread - > set_active_handles ( java_handles ) ;
compile_handles - > set_pop_frame_link ( NULL ) ;
JNIHandleBlock : : release_block ( compile_handles , thread ) ; // may block
}
}
2019-05-01 12:31:29 -07:00
class JVMCITraceMark : public StackObj {
const char * _msg ;
public :
JVMCITraceMark ( const char * msg ) {
_msg = msg ;
if ( JVMCITraceLevel > = 1 ) {
tty - > print_cr ( PTR_FORMAT " JVMCITrace-1: Enter %s " , p2i ( JavaThread : : current ( ) ) , _msg ) ;
}
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
~ JVMCITraceMark ( ) {
if ( JVMCITraceLevel > = 1 ) {
tty - > print_cr ( PTR_FORMAT " JVMCITrace-1: Exit %s " , p2i ( JavaThread : : current ( ) ) , _msg ) ;
}
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
} ;
2015-10-08 12:49:30 -10:00
2018-03-16 09:12:13 -04:00
Handle JavaArgumentUnboxer : : next_arg ( BasicType expectedType ) {
assert ( _index < _args - > length ( ) , " out of bounds " ) ;
oop arg = ( ( objArrayOop ) ( _args ) ) - > obj_at ( _index + + ) ;
assert ( expectedType = = T_OBJECT | | java_lang_boxing_object : : is_instance ( arg , expectedType ) , " arg type mismatch " ) ;
return Handle ( Thread : : current ( ) , arg ) ;
}
2017-02-27 17:36:36 +01:00
2019-05-06 20:05:19 -07:00
// Bring the JVMCI compiler thread into the VM state.
# define JVMCI_VM_ENTRY_MARK \
ThreadInVMfromNative __tiv ( thread ) ; \
ResetNoHandleMark rnhm ; \
HandleMarkCleaner __hm ( thread ) ; \
Thread * THREAD = thread ; \
debug_only ( VMNativeEntryWrapper __vew ; )
// Native method block that transitions current thread to '_thread_in_vm'.
# define C2V_BLOCK(result_type, name, signature) \
TRACE_CALL ( result_type , jvmci_ # # name signature ) \
JVMCI_VM_ENTRY_MARK ; \
ResourceMark rm ; \
JNI_JVMCIENV ( thread , env ) ;
static Thread * get_current_thread ( ) {
return Thread : : current_or_null_safe ( ) ;
}
// Entry to native method implementation that transitions
// current thread to '_thread_in_vm'.
2019-05-01 12:31:29 -07:00
# define C2V_VMENTRY(result_type, name, signature) \
JNIEXPORT result_type JNICALL c2v_ # # name signature { \
2019-05-06 20:05:19 -07:00
Thread * base_thread = get_current_thread ( ) ; \
if ( base_thread = = NULL ) { \
env - > ThrowNew ( JNIJVMCI : : InternalError : : clazz ( ) , \
err_msg ( " Cannot call into HotSpot from JVMCI shared library without attaching current thread " ) ) ; \
return ; \
} \
assert ( base_thread - > is_Java_thread ( ) , " just checking " ) ; \
JavaThread * thread = ( JavaThread * ) base_thread ; \
2019-05-01 12:31:29 -07:00
JVMCITraceMark jtm ( " CompilerToVM:: " # name ) ; \
2019-05-06 20:05:19 -07:00
C2V_BLOCK ( result_type , name , signature )
# define C2V_VMENTRY_(result_type, name, signature, result) \
JNIEXPORT result_type JNICALL c2v_ # # name signature { \
Thread * base_thread = get_current_thread ( ) ; \
if ( base_thread = = NULL ) { \
env - > ThrowNew ( JNIJVMCI : : InternalError : : clazz ( ) , \
err_msg ( " Cannot call into HotSpot from JVMCI shared library without attaching current thread " ) ) ; \
return result ; \
} \
assert ( base_thread - > is_Java_thread ( ) , " just checking " ) ; \
JavaThread * thread = ( JavaThread * ) base_thread ; \
JVMCITraceMark jtm ( " CompilerToVM:: " # name ) ; \
C2V_BLOCK ( result_type , name , signature )
# define C2V_VMENTRY_NULL(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, NULL)
# define C2V_VMENTRY_0(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, 0)
// Entry to native method implementation that does not transition
// current thread to '_thread_in_vm'.
# define C2V_VMENTRY_PREFIX(result_type, name, signature) \
JNIEXPORT result_type JNICALL c2v_ # # name signature { \
Thread * base_thread = get_current_thread ( ) ;
2017-02-06 10:45:11 +01:00
2019-05-01 12:31:29 -07:00
# define C2V_END }
2017-02-06 10:45:11 +01:00
2019-05-06 20:05:19 -07:00
# define JNI_THROW(caller, name, msg) do { \
jint __throw_res = env - > ThrowNew ( JNIJVMCI : : name : : clazz ( ) , msg ) ; \
if ( __throw_res ! = JNI_OK ) { \
tty - > print_cr ( " Throwing " # name " in " caller " returned %d " , __throw_res ) ; \
} \
return ; \
} while ( 0 ) ;
# define JNI_THROW_(caller, name, msg, result) do { \
jint __throw_res = env - > ThrowNew ( JNIJVMCI : : name : : clazz ( ) , msg ) ; \
if ( __throw_res ! = JNI_OK ) { \
tty - > print_cr ( " Throwing " # name " in " caller " returned %d " , __throw_res ) ; \
} \
return result ; \
} while ( 0 )
2019-05-01 12:31:29 -07:00
jobjectArray readConfiguration0 ( JNIEnv * env , JVMCI_TRAPS ) ;
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobjectArray , readConfiguration , ( JNIEnv * env ) )
2019-05-01 12:31:29 -07:00
jobjectArray config = readConfiguration0 ( env , JVMCI_CHECK_NULL ) ;
return config ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getFlagValue , ( JNIEnv * env , jobject c2vm , jobject name_handle ) )
2019-05-01 12:31:29 -07:00
# define RETURN_BOXED_LONG(value) jvalue p; p.j = (jlong) (value); JVMCIObject box = JVMCIENV->create_box(T_LONG, &p, JVMCI_CHECK_NULL); return box.as_jobject();
# define RETURN_BOXED_DOUBLE(value) jvalue p; p.d = (jdouble) (value); JVMCIObject box = JVMCIENV->create_box(T_DOUBLE, &p, JVMCI_CHECK_NULL); return box.as_jobject();
JVMCIObject name = JVMCIENV - > wrap ( name_handle ) ;
2017-02-06 10:45:11 +01:00
if ( name . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_NULL ( NullPointerException ) ;
2017-02-06 10:45:11 +01:00
}
2019-05-01 12:31:29 -07:00
const char * cstring = JVMCIENV - > as_utf8_string ( name ) ;
2019-08-26 09:15:43 +02:00
const JVMFlag * flag = JVMFlag : : find_declared_flag ( cstring ) ;
2017-02-06 10:45:11 +01:00
if ( flag = = NULL ) {
return c2vm ;
}
if ( flag - > is_bool ( ) ) {
jvalue prim ;
prim . z = flag - > get_bool ( ) ;
2019-05-01 12:31:29 -07:00
JVMCIObject box = JVMCIENV - > create_box ( T_BOOLEAN , & prim , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( box ) ;
2017-02-06 10:45:11 +01:00
} else if ( flag - > is_ccstr ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCIObject value = JVMCIENV - > create_string ( flag - > get_ccstr ( ) , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( value ) ;
2017-02-06 10:45:11 +01:00
} else if ( flag - > is_intx ( ) ) {
RETURN_BOXED_LONG ( flag - > get_intx ( ) ) ;
} else if ( flag - > is_int ( ) ) {
RETURN_BOXED_LONG ( flag - > get_int ( ) ) ;
} else if ( flag - > is_uint ( ) ) {
RETURN_BOXED_LONG ( flag - > get_uint ( ) ) ;
} else if ( flag - > is_uint64_t ( ) ) {
RETURN_BOXED_LONG ( flag - > get_uint64_t ( ) ) ;
} else if ( flag - > is_size_t ( ) ) {
RETURN_BOXED_LONG ( flag - > get_size_t ( ) ) ;
} else if ( flag - > is_uintx ( ) ) {
RETURN_BOXED_LONG ( flag - > get_uintx ( ) ) ;
} else if ( flag - > is_double ( ) ) {
RETURN_BOXED_DOUBLE ( flag - > get_double ( ) ) ;
} else {
JVMCI_ERROR_NULL ( " VM flag %s has unsupported type %s " , flag - > _name , flag - > _type ) ;
}
2018-03-09 10:15:22 -08:00
# undef RETURN_BOXED_LONG
# undef RETURN_BOXED_DOUBLE
2017-02-06 10:45:11 +01:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getObjectAtAddress , ( JNIEnv * env , jobject c2vm , jlong oop_address ) )
requireInHotSpot ( " getObjectAtAddress " , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
if ( oop_address = = 0 ) {
JVMCI_THROW_MSG_NULL ( InternalError , " Handle must be non-zero " ) ;
}
oop obj = * ( ( oopDesc * * ) oop_address ) ;
if ( obj ! = NULL ) {
oopDesc : : verify ( obj ) ;
}
return JNIHandles : : make_local ( obj ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jbyteArray , getBytecode , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2015-10-08 12:49:30 -10:00
int code_size = method - > code_size ( ) ;
2019-05-01 12:31:29 -07:00
jbyte * reconstituted_code = NEW_RESOURCE_ARRAY ( jbyte , code_size ) ;
2015-10-08 12:49:30 -10:00
guarantee ( method - > method_holder ( ) - > is_rewritten ( ) , " Method's holder should be rewritten " ) ;
// iterate over all bytecodes and replace non-Java bytecodes
for ( BytecodeStream s ( method ) ; s . next ( ) ! = Bytecodes : : _illegal ; ) {
Bytecodes : : Code code = s . code ( ) ;
Bytecodes : : Code raw_code = s . raw_code ( ) ;
int bci = s . bci ( ) ;
int len = s . instruction_size ( ) ;
// Restore original byte code.
2019-05-01 12:31:29 -07:00
reconstituted_code [ bci ] = ( jbyte ) ( s . is_wide ( ) ? Bytecodes : : _wide : code ) ;
2015-10-08 12:49:30 -10:00
if ( len > 1 ) {
2019-05-01 12:31:29 -07:00
memcpy ( reconstituted_code + ( bci + 1 ) , s . bcp ( ) + 1 , len - 1 ) ;
2015-10-08 12:49:30 -10:00
}
if ( len > 1 ) {
// Restore the big-endian constant pool indexes.
// Cf. Rewriter::scan_method
switch ( code ) {
case Bytecodes : : _getstatic :
case Bytecodes : : _putstatic :
case Bytecodes : : _getfield :
case Bytecodes : : _putfield :
case Bytecodes : : _invokevirtual :
case Bytecodes : : _invokespecial :
case Bytecodes : : _invokestatic :
case Bytecodes : : _invokeinterface :
case Bytecodes : : _invokehandle : {
2019-05-01 12:31:29 -07:00
int cp_index = Bytes : : get_native_u2 ( ( address ) reconstituted_code + ( bci + 1 ) ) ;
Bytes : : put_Java_u2 ( ( address ) reconstituted_code + ( bci + 1 ) , ( u2 ) cp_index ) ;
2015-10-08 12:49:30 -10:00
break ;
}
2017-07-06 01:50:26 +02:00
case Bytecodes : : _invokedynamic : {
2019-05-01 12:31:29 -07:00
int cp_index = Bytes : : get_native_u4 ( ( address ) reconstituted_code + ( bci + 1 ) ) ;
Bytes : : put_Java_u4 ( ( address ) reconstituted_code + ( bci + 1 ) , ( u4 ) cp_index ) ;
2015-10-08 12:49:30 -10:00
break ;
2017-07-06 01:50:26 +02:00
}
default :
break ;
2015-10-08 12:49:30 -10:00
}
// Not all ldc byte code are rewritten.
switch ( raw_code ) {
case Bytecodes : : _fast_aldc : {
2019-05-01 12:31:29 -07:00
int cpc_index = reconstituted_code [ bci + 1 ] & 0xff ;
2015-10-08 12:49:30 -10:00
int cp_index = method - > constants ( ) - > object_to_cp_index ( cpc_index ) ;
assert ( cp_index < method - > constants ( ) - > length ( ) , " sanity check " ) ;
2019-05-01 12:31:29 -07:00
reconstituted_code [ bci + 1 ] = ( jbyte ) cp_index ;
2015-10-08 12:49:30 -10:00
break ;
}
case Bytecodes : : _fast_aldc_w : {
2019-05-01 12:31:29 -07:00
int cpc_index = Bytes : : get_native_u2 ( ( address ) reconstituted_code + ( bci + 1 ) ) ;
2015-10-08 12:49:30 -10:00
int cp_index = method - > constants ( ) - > object_to_cp_index ( cpc_index ) ;
assert ( cp_index < method - > constants ( ) - > length ( ) , " sanity check " ) ;
2019-05-01 12:31:29 -07:00
Bytes : : put_Java_u2 ( ( address ) reconstituted_code + ( bci + 1 ) , ( u2 ) cp_index ) ;
2015-10-08 12:49:30 -10:00
break ;
}
2017-07-06 01:50:26 +02:00
default :
break ;
2015-10-08 12:49:30 -10:00
}
}
}
2019-05-01 12:31:29 -07:00
JVMCIPrimitiveArray result = JVMCIENV - > new_byteArray ( code_size , JVMCI_CHECK_NULL ) ;
JVMCIENV - > copy_bytes_from ( reconstituted_code , result , 0 , code_size ) ;
return JVMCIENV - > get_jbyteArray ( result ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , getExceptionTableLength , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-11-13 08:23:23 -05:00
Method * method = JVMCIENV - > asMethod ( jvmci_method ) ;
2015-10-08 12:49:30 -10:00
return method - > exception_table_length ( ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jlong , getExceptionTableStart , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-11-13 08:23:23 -05:00
Method * method = JVMCIENV - > asMethod ( jvmci_method ) ;
2015-10-08 12:49:30 -10:00
if ( method - > exception_table_length ( ) = = 0 ) {
return 0L ;
}
return ( jlong ) ( address ) method - > exception_table_start ( ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , asResolvedJavaMethod , ( JNIEnv * env , jobject , jobject executable_handle ) )
requireInHotSpot ( " asResolvedJavaMethod " , JVMCI_CHECK_NULL ) ;
2016-09-14 12:34:37 -07:00
oop executable = JNIHandles : : resolve ( executable_handle ) ;
oop mirror = NULL ;
int slot = 0 ;
if ( executable - > klass ( ) = = SystemDictionary : : reflect_Constructor_klass ( ) ) {
mirror = java_lang_reflect_Constructor : : clazz ( executable ) ;
slot = java_lang_reflect_Constructor : : slot ( executable ) ;
} else {
assert ( executable - > klass ( ) = = SystemDictionary : : reflect_Method_klass ( ) , " wrong type " ) ;
mirror = java_lang_reflect_Method : : clazz ( executable ) ;
slot = java_lang_reflect_Method : : slot ( executable ) ;
}
Klass * holder = java_lang_Class : : as_Klass ( mirror ) ;
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , InstanceKlass : : cast ( holder ) - > method_with_idnum ( slot ) ) ;
2019-05-01 12:31:29 -07:00
JVMCIObject result = JVMCIENV - > get_jvmci_method ( method , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getResolvedJavaMethod , ( JNIEnv * env , jobject , jobject base , jlong offset ) )
2019-11-13 08:23:23 -05:00
Method * method ;
2019-05-01 12:31:29 -07:00
JVMCIObject base_object = JVMCIENV - > wrap ( base ) ;
if ( base_object . is_null ( ) ) {
2015-10-08 12:49:30 -10:00
method = * ( ( Method * * ) ( offset ) ) ;
2019-05-01 12:31:29 -07:00
} else if ( JVMCIENV - > isa_HotSpotObjectConstantImpl ( base_object ) ) {
Handle obj = JVMCIENV - > asConstant ( base_object , JVMCI_CHECK_NULL ) ;
if ( obj - > is_a ( SystemDictionary : : ResolvedMethodName_klass ( ) ) ) {
method = ( Method * ) ( intptr_t ) obj - > long_field ( offset ) ;
} else {
JVMCI_THROW_MSG_NULL ( IllegalArgumentException , err_msg ( " Unexpected type: %s " , obj - > klass ( ) - > external_name ( ) ) ) ;
}
} else if ( JVMCIENV - > isa_HotSpotResolvedJavaMethodImpl ( base_object ) ) {
method = JVMCIENV - > asMethod ( base_object ) ;
}
2019-11-13 08:23:23 -05:00
if ( method = = NULL ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_NULL ( IllegalArgumentException , err_msg ( " Unexpected type: %s " , JVMCIENV - > klass_name ( base_object ) ) ) ;
2015-10-08 12:49:30 -10:00
}
2019-11-13 08:23:23 -05:00
assert ( method - > is_method ( ) , " invalid read " ) ;
JVMCIObject result = JVMCIENV - > get_jvmci_method ( methodHandle ( THREAD , method ) , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
return JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getConstantPool , ( JNIEnv * env , jobject , jobject object_handle ) )
2019-11-13 08:23:23 -05:00
ConstantPool * cp = NULL ;
2019-05-01 12:31:29 -07:00
JVMCIObject object = JVMCIENV - > wrap ( object_handle ) ;
if ( object . is_null ( ) ) {
JVMCI_THROW_NULL ( NullPointerException ) ;
}
if ( JVMCIENV - > isa_HotSpotResolvedJavaMethodImpl ( object ) ) {
cp = JVMCIENV - > asMethod ( object ) - > constMethod ( ) - > constants ( ) ;
} else if ( JVMCIENV - > isa_HotSpotResolvedObjectTypeImpl ( object ) ) {
cp = InstanceKlass : : cast ( JVMCIENV - > asKlass ( object ) ) - > constants ( ) ;
2016-08-08 17:06:21 +02:00
} else {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_NULL ( IllegalArgumentException ,
err_msg ( " Unexpected type: %s " , JVMCIENV - > klass_name ( object ) ) ) ;
2016-08-08 17:06:21 +02:00
}
2019-11-13 08:23:23 -05:00
assert ( cp ! = NULL , " npe " ) ;
2019-05-01 12:31:29 -07:00
2019-11-13 08:23:23 -05:00
JVMCIObject result = JVMCIENV - > get_jvmci_constant_pool ( constantPoolHandle ( THREAD , cp ) , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
return JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getResolvedJavaType0 , ( JNIEnv * env , jobject , jobject base , jlong offset , jboolean compressed ) )
2018-06-24 21:46:11 -07:00
JVMCIKlassHandle klass ( THREAD ) ;
2019-05-01 12:31:29 -07:00
JVMCIObject base_object = JVMCIENV - > wrap ( base ) ;
2015-10-08 12:49:30 -10:00
jlong base_address = 0 ;
2019-05-01 12:31:29 -07:00
if ( base_object . is_non_null ( ) & & offset = = oopDesc : : klass_offset_in_bytes ( ) ) {
// klass = JVMCIENV->unhandle(base_object)->klass();
if ( JVMCIENV - > isa_HotSpotObjectConstantImpl ( base_object ) ) {
Handle base_oop = JVMCIENV - > asConstant ( base_object , JVMCI_CHECK_NULL ) ;
klass = base_oop - > klass ( ) ;
} else {
assert ( false , " What types are we actually expecting here? " ) ;
}
2015-10-08 12:49:30 -10:00
} else if ( ! compressed ) {
2019-05-01 12:31:29 -07:00
if ( base_object . is_non_null ( ) ) {
if ( JVMCIENV - > isa_HotSpotResolvedJavaMethodImpl ( base_object ) ) {
base_address = ( intptr_t ) JVMCIENV - > asMethod ( base_object ) ;
} else if ( JVMCIENV - > isa_HotSpotConstantPool ( base_object ) ) {
base_address = ( intptr_t ) JVMCIENV - > asConstantPool ( base_object ) ;
} else if ( JVMCIENV - > isa_HotSpotResolvedObjectTypeImpl ( base_object ) ) {
base_address = ( intptr_t ) JVMCIENV - > asKlass ( base_object ) ;
} else if ( JVMCIENV - > isa_HotSpotObjectConstantImpl ( base_object ) ) {
Handle base_oop = JVMCIENV - > asConstant ( base_object , JVMCI_CHECK_NULL ) ;
if ( base_oop - > is_a ( SystemDictionary : : Class_klass ( ) ) ) {
base_address = ( jlong ) ( address ) base_oop ( ) ;
}
}
if ( base_address = = 0 ) {
JVMCI_THROW_MSG_NULL ( IllegalArgumentException ,
err_msg ( " Unexpected arguments: %s " JLONG_FORMAT " %s " , JVMCIENV - > klass_name ( base_object ) , offset , compressed ? " true " : " false " ) ) ;
2015-10-08 12:49:30 -10:00
}
}
klass = * ( ( Klass * * ) ( intptr_t ) ( base_address + offset ) ) ;
} else {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_NULL ( IllegalArgumentException ,
2018-07-12 16:31:28 +02:00
err_msg ( " Unexpected arguments: %s " JLONG_FORMAT " %s " ,
2019-05-01 12:31:29 -07:00
base_object . is_non_null ( ) ? JVMCIENV - > klass_name ( base_object ) : " null " ,
2018-07-12 16:31:28 +02:00
offset , compressed ? " true " : " false " ) ) ;
2015-10-08 12:49:30 -10:00
}
2017-03-15 10:25:37 -04:00
assert ( klass = = NULL | | klass - > is_klass ( ) , " invalid read " ) ;
2019-05-01 12:31:29 -07:00
JVMCIObject result = JVMCIENV - > get_jvmci_type ( klass , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , findUniqueConcreteMethod , ( JNIEnv * env , jobject , jobject jvmci_type , jobject jvmci_method ) )
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2019-05-01 12:31:29 -07:00
Klass * holder = JVMCIENV - > asKlass ( jvmci_type ) ;
2015-10-08 12:49:30 -10:00
if ( holder - > is_interface ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_NULL ( InternalError , err_msg ( " Interface %s should be handled in Java code " , holder - > external_name ( ) ) ) ;
2015-10-08 12:49:30 -10:00
}
2019-06-07 18:11:33 -04:00
if ( method - > can_be_statically_bound ( ) ) {
JVMCI_THROW_MSG_NULL ( InternalError , err_msg ( " Effectively static method %s.%s should be handled in Java code " , method - > method_holder ( ) - > external_name ( ) , method - > external_name ( ) ) ) ;
}
2015-10-08 12:49:30 -10:00
methodHandle ucm ;
{
MutexLocker locker ( Compile_lock ) ;
2019-11-13 08:23:23 -05:00
ucm = methodHandle ( THREAD , Dependencies : : find_unique_concrete_method ( holder , method ( ) ) ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
JVMCIObject result = JVMCIENV - > get_jvmci_method ( ucm , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getImplementor , ( JNIEnv * env , jobject , jobject jvmci_type ) )
2019-05-01 12:31:29 -07:00
Klass * klass = JVMCIENV - > asKlass ( jvmci_type ) ;
2017-12-22 18:34:36 +01:00
if ( ! klass - > is_interface ( ) ) {
THROW_MSG_0 ( vmSymbols : : java_lang_IllegalArgumentException ( ) ,
err_msg ( " Expected interface type, got %s " , klass - > external_name ( ) ) ) ;
}
InstanceKlass * iklass = InstanceKlass : : cast ( klass ) ;
2018-08-11 12:49:33 -04:00
JVMCIKlassHandle handle ( THREAD ) ;
{
// Need Compile_lock around implementor()
MutexLocker locker ( Compile_lock ) ;
handle = iklass - > implementor ( ) ;
}
2019-05-01 12:31:29 -07:00
JVMCIObject implementor = JVMCIENV - > get_jvmci_type ( handle , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( implementor ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , methodIsIgnoredBySecurityStackWalk , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-11-13 08:23:23 -05:00
Method * method = JVMCIENV - > asMethod ( jvmci_method ) ;
2015-10-08 12:49:30 -10:00
return method - > is_ignored_by_security_stack_walk ( ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , isCompilable , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-11-13 08:23:23 -05:00
Method * method = JVMCIENV - > asMethod ( jvmci_method ) ;
ConstantPool * cp = method - > constMethod ( ) - > constants ( ) ;
assert ( cp ! = NULL , " npe " ) ;
2017-09-08 10:46:46 -07:00
// don't inline method when constant pool contains a CONSTANT_Dynamic
return ! method - > is_not_compilable ( CompLevel_full_optimization ) & & ! cp - > has_dynamic_constant ( ) ;
2017-01-22 21:40:59 +01:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , hasNeverInlineDirective , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2017-08-22 08:53:35 -07:00
return ! Inline | | CompilerOracle : : should_not_inline ( method ) | | method - > dont_inline ( ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , shouldInlineMethod , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2015-10-08 12:49:30 -10:00
return CompilerOracle : : should_inline ( method ) | | method - > force_inline ( ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , lookupType , ( JNIEnv * env , jobject , jstring jname , jclass accessing_class , jboolean resolve ) )
2019-05-01 12:31:29 -07:00
JVMCIObject name = JVMCIENV - > wrap ( jname ) ;
const char * str = JVMCIENV - > as_utf8_string ( name ) ;
2019-05-14 11:29:18 -04:00
TempNewSymbol class_name = SymbolTable : : new_symbol ( str ) ;
2019-05-01 12:31:29 -07:00
if ( class_name - > utf8_length ( ) < = 1 ) {
JVMCI_THROW_MSG_0 ( InternalError , err_msg ( " Primitive type %s should be handled in Java code " , class_name - > as_C_string ( ) ) ) ;
2015-10-08 12:49:30 -10:00
}
2018-06-24 21:46:11 -07:00
JVMCIKlassHandle resolved_klass ( THREAD ) ;
2019-05-01 12:31:29 -07:00
Klass * accessing_klass = NULL ;
Handle class_loader ;
Handle protection_domain ;
if ( accessing_class ! = NULL ) {
accessing_klass = JVMCIENV - > asKlass ( accessing_class ) ;
class_loader = Handle ( THREAD , accessing_klass - > class_loader ( ) ) ;
protection_domain = Handle ( THREAD , accessing_klass - > protection_domain ( ) ) ;
} else {
// Use the System class loader
class_loader = Handle ( THREAD , SystemDictionary : : java_system_loader ( ) ) ;
JVMCIENV - > runtime ( ) - > initialize ( JVMCIENV ) ;
2015-10-08 12:49:30 -10:00
}
if ( resolve ) {
resolved_klass = SystemDictionary : : resolve_or_null ( class_name , class_loader , protection_domain , CHECK_0 ) ;
2019-05-06 20:05:19 -07:00
if ( resolved_klass = = NULL ) {
JVMCI_THROW_MSG_NULL ( ClassNotFoundException , str ) ;
}
2015-10-08 12:49:30 -10:00
} else {
2019-10-21 13:13:16 -04:00
if ( class_name - > char_at ( 0 ) = = JVM_SIGNATURE_CLASS & &
class_name - > char_at ( class_name - > utf8_length ( ) - 1 ) = = JVM_SIGNATURE_ENDCLASS ) {
2015-10-08 12:49:30 -10:00
// This is a name from a signature. Strip off the trimmings.
// Call recursive to keep scope of strippedsym.
TempNewSymbol strippedsym = SymbolTable : : new_symbol ( class_name - > as_utf8 ( ) + 1 ,
2019-05-14 11:29:18 -04:00
class_name - > utf8_length ( ) - 2 ) ;
2015-10-08 12:49:30 -10:00
resolved_klass = SystemDictionary : : find ( strippedsym , class_loader , protection_domain , CHECK_0 ) ;
} else if ( FieldType : : is_array ( class_name ) ) {
FieldArrayInfo fd ;
// dimension and object_key in FieldArrayInfo are assigned as a side-effect
// of this call
BasicType t = FieldType : : get_array_info ( class_name , fd , CHECK_0 ) ;
if ( t = = T_OBJECT ) {
TempNewSymbol strippedsym = SymbolTable : : new_symbol ( class_name - > as_utf8 ( ) + 1 + fd . dimension ( ) ,
2019-05-14 11:29:18 -04:00
class_name - > utf8_length ( ) - 2 - fd . dimension ( ) ) ;
2015-10-08 12:49:30 -10:00
resolved_klass = SystemDictionary : : find ( strippedsym ,
class_loader ,
protection_domain ,
CHECK_0 ) ;
2018-06-24 21:46:11 -07:00
if ( ! resolved_klass . is_null ( ) ) {
2015-10-08 12:49:30 -10:00
resolved_klass = resolved_klass - > array_klass ( fd . dimension ( ) , CHECK_0 ) ;
}
} else {
2018-06-24 21:46:11 -07:00
resolved_klass = TypeArrayKlass : : cast ( Universe : : typeArrayKlassObj ( t ) ) - > array_klass ( fd . dimension ( ) , CHECK_0 ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
} else {
resolved_klass = SystemDictionary : : find ( class_name , class_loader , protection_domain , CHECK_0 ) ;
2015-10-08 12:49:30 -10:00
}
}
2019-05-01 12:31:29 -07:00
JVMCIObject result = JVMCIENV - > get_jvmci_type ( resolved_klass , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-06-21 16:21:13 -07:00
C2V_VMENTRY_NULL ( jobject , getArrayType , ( JNIEnv * env , jobject , jobject jvmci_type ) )
if ( jvmci_type = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
JVMCIObject jvmci_type_object = JVMCIENV - > wrap ( jvmci_type ) ;
JVMCIKlassHandle array_klass ( THREAD ) ;
if ( JVMCIENV - > isa_HotSpotResolvedPrimitiveType ( jvmci_type_object ) ) {
BasicType type = JVMCIENV - > kindToBasicType ( JVMCIENV - > get_HotSpotResolvedPrimitiveType_kind ( jvmci_type_object ) , JVMCI_CHECK_0 ) ;
if ( type = = T_VOID ) {
return NULL ;
}
array_klass = Universe : : typeArrayKlassObj ( type ) ;
if ( array_klass = = NULL ) {
JVMCI_THROW_MSG_NULL ( InternalError , err_msg ( " No array klass for primitive type %s " , type2name ( type ) ) ) ;
}
} else {
Klass * klass = JVMCIENV - > asKlass ( jvmci_type ) ;
if ( klass = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
array_klass = klass - > array_klass ( CHECK_NULL ) ;
}
JVMCIObject result = JVMCIENV - > get_jvmci_type ( array_klass , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , lookupClass , ( JNIEnv * env , jobject , jclass mirror ) )
requireInHotSpot ( " lookupClass " , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
if ( mirror = = NULL ) {
return NULL ;
}
JVMCIKlassHandle klass ( THREAD ) ;
klass = java_lang_Class : : as_Klass ( JNIHandles : : resolve ( mirror ) ) ;
if ( klass = = NULL ) {
JVMCI_THROW_MSG_NULL ( IllegalArgumentException , " Primitive classes are unsupported " ) ;
}
JVMCIObject result = JVMCIENV - > get_jvmci_type ( klass , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , resolvePossiblyCachedConstantInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2015-10-08 12:49:30 -10:00
oop result = cp - > resolve_possibly_cached_constant_at ( index , CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
return JVMCIENV - > get_jobject ( JVMCIENV - > get_object_constant ( result ) ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , lookupNameAndTypeRefIndexInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2015-10-08 12:49:30 -10:00
return cp - > name_and_type_ref_index_at ( index ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , lookupNameInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint which ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2019-05-01 12:31:29 -07:00
JVMCIObject sym = JVMCIENV - > create_string ( cp - > name_ref_at ( which ) , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( sym ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , lookupSignatureInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint which ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2019-05-01 12:31:29 -07:00
JVMCIObject sym = JVMCIENV - > create_string ( cp - > signature_ref_at ( which ) , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( sym ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , lookupKlassRefIndexInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2015-10-08 12:49:30 -10:00
return cp - > klass_ref_index_at ( index ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , resolveTypeInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2018-06-24 21:46:11 -07:00
Klass * klass = cp - > klass_at ( index , CHECK_NULL ) ;
JVMCIKlassHandle resolved_klass ( THREAD , klass ) ;
2018-03-20 10:23:14 -07:00
if ( resolved_klass - > is_instance_klass ( ) ) {
2019-05-06 20:05:19 -07:00
InstanceKlass : : cast ( resolved_klass ( ) ) - > link_class ( CHECK_NULL ) ;
if ( ! InstanceKlass : : cast ( resolved_klass ( ) ) - > is_linked ( ) ) {
// link_class() should not return here if there is an issue.
JVMCI_THROW_MSG_NULL ( InternalError , err_msg ( " Class %s must be linked " , resolved_klass ( ) - > external_name ( ) ) ) ;
2019-05-03 09:07:30 -07:00
}
2018-03-20 10:23:14 -07:00
}
2019-05-01 12:31:29 -07:00
JVMCIObject klassObject = JVMCIENV - > get_jvmci_type ( resolved_klass , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( klassObject ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , lookupKlassInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index , jbyte opcode ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2017-03-15 10:25:37 -04:00
Klass * loading_klass = cp - > pool_holder ( ) ;
2015-10-08 12:49:30 -10:00
bool is_accessible = false ;
2019-05-01 12:31:29 -07:00
JVMCIKlassHandle klass ( THREAD , JVMCIRuntime : : get_klass_by_index ( cp , index , is_accessible , loading_klass ) ) ;
2015-10-08 12:49:30 -10:00
Symbol * symbol = NULL ;
2019-05-01 12:31:29 -07:00
if ( klass . is_null ( ) ) {
constantTag tag = cp - > tag_at ( index ) ;
if ( tag . is_klass ( ) ) {
// The klass has been inserted into the constant pool
// very recently.
klass = cp - > resolved_klass_at ( index ) ;
} else if ( tag . is_symbol ( ) ) {
symbol = cp - > symbol_at ( index ) ;
} else {
assert ( cp - > tag_at ( index ) . is_unresolved_klass ( ) , " wrong tag " ) ;
symbol = cp - > klass_name_at ( index ) ;
}
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
JVMCIObject result ;
2018-06-24 21:46:11 -07:00
if ( ! klass . is_null ( ) ) {
2019-05-01 12:31:29 -07:00
result = JVMCIENV - > get_jvmci_type ( klass , JVMCI_CHECK_NULL ) ;
2015-10-08 12:49:30 -10:00
} else {
2019-05-01 12:31:29 -07:00
result = JVMCIENV - > create_string ( symbol , JVMCI_CHECK_NULL ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
return JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , lookupAppendixInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2015-10-08 12:49:30 -10:00
oop appendix_oop = ConstantPool : : appendix_at_if_loaded ( cp , index ) ;
2019-05-01 12:31:29 -07:00
return JVMCIENV - > get_jobject ( JVMCIENV - > get_object_constant ( appendix_oop ) ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , lookupMethodInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index , jbyte opcode ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2017-03-15 10:25:37 -04:00
InstanceKlass * pool_holder = cp - > pool_holder ( ) ;
2015-10-08 12:49:30 -10:00
Bytecodes : : Code bc = ( Bytecodes : : Code ) ( ( ( int ) opcode ) & 0xFF ) ;
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIRuntime : : get_method_by_index ( cp , index , bc , pool_holder ) ) ;
2019-05-01 12:31:29 -07:00
JVMCIObject result = JVMCIENV - > get_jvmci_method ( method , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , constantPoolRemapInstructionOperandFromCache , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2015-10-08 12:49:30 -10:00
return cp - > remap_instruction_operand_from_cache ( index ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , resolveFieldInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index , jobject jvmci_method , jbyte opcode , jintArray info_handle ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2015-10-08 12:49:30 -10:00
Bytecodes : : Code code = ( Bytecodes : : Code ) ( ( ( int ) opcode ) & 0xFF ) ;
fieldDescriptor fd ;
2019-11-13 08:23:23 -05:00
methodHandle mh ( THREAD , ( jvmci_method ! = NULL ) ? JVMCIENV - > asMethod ( jvmci_method ) : NULL ) ;
LinkInfo link_info ( cp , index , mh , CHECK_0 ) ;
2015-10-08 12:49:30 -10:00
LinkResolver : : resolve_field ( fd , link_info , Bytecodes : : java_code ( code ) , false , CHECK_0 ) ;
2019-05-01 12:31:29 -07:00
JVMCIPrimitiveArray info = JVMCIENV - > wrap ( info_handle ) ;
if ( info . is_null ( ) | | JVMCIENV - > get_length ( info ) ! = 3 ) {
2017-02-06 10:45:11 +01:00
JVMCI_ERROR_NULL ( " info must not be null and have a length of 3 " ) ;
}
2019-05-01 12:31:29 -07:00
JVMCIENV - > put_int_at ( info , 0 , fd . access_flags ( ) . as_int ( ) ) ;
JVMCIENV - > put_int_at ( info , 1 , fd . offset ( ) ) ;
JVMCIENV - > put_int_at ( info , 2 , fd . index ( ) ) ;
2018-06-24 21:46:11 -07:00
JVMCIKlassHandle handle ( THREAD , fd . field_holder ( ) ) ;
2019-05-01 12:31:29 -07:00
JVMCIObject field_holder = JVMCIENV - > get_jvmci_type ( handle , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( field_holder ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , getVtableIndexForInterfaceMethod , ( JNIEnv * env , jobject , jobject jvmci_type , jobject jvmci_method ) )
2019-05-01 12:31:29 -07:00
Klass * klass = JVMCIENV - > asKlass ( jvmci_type ) ;
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2015-10-08 12:49:30 -10:00
if ( klass - > is_interface ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_0 ( InternalError , err_msg ( " Interface %s should be handled in Java code " , klass - > external_name ( ) ) ) ;
2015-10-08 12:49:30 -10:00
}
if ( ! method - > method_holder ( ) - > is_interface ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_0 ( InternalError , err_msg ( " Method %s is not held by an interface, this case should be handled in Java code " , method - > name_and_sig_as_C_string ( ) ) ) ;
}
if ( ! klass - > is_instance_klass ( ) ) {
JVMCI_THROW_MSG_0 ( InternalError , err_msg ( " Class %s must be instance klass " , klass - > external_name ( ) ) ) ;
2015-10-08 12:49:30 -10:00
}
2015-11-04 07:23:23 -10:00
if ( ! InstanceKlass : : cast ( klass ) - > is_linked ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_0 ( InternalError , err_msg ( " Class %s must be linked " , klass - > external_name ( ) ) ) ;
2015-10-08 12:49:30 -10:00
}
return LinkResolver : : vtable_index_of_interface_method ( klass , method ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , resolveMethod , ( JNIEnv * env , jobject , jobject receiver_jvmci_type , jobject jvmci_method , jobject caller_jvmci_type ) )
2019-05-01 12:31:29 -07:00
Klass * recv_klass = JVMCIENV - > asKlass ( receiver_jvmci_type ) ;
Klass * caller_klass = JVMCIENV - > asKlass ( caller_jvmci_type ) ;
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2015-10-08 12:49:30 -10:00
2017-03-15 10:25:37 -04:00
Klass * resolved = method - > method_holder ( ) ;
2016-04-27 16:20:49 -07:00
Symbol * h_name = method - > name ( ) ;
Symbol * h_signature = method - > signature ( ) ;
2016-08-29 17:15:20 +00:00
if ( MethodHandles : : is_signature_polymorphic_method ( method ( ) ) ) {
// Signature polymorphic methods are already resolved, JVMCI just returns NULL in this case.
return NULL ;
}
2019-01-15 22:59:33 -08:00
if ( method - > name ( ) = = vmSymbols : : clone_name ( ) & &
resolved = = SystemDictionary : : Object_klass ( ) & &
recv_klass - > is_array_klass ( ) ) {
// Resolution of the clone method on arrays always returns Object.clone even though that method
// has protected access. There's some trickery in the access checking to make this all work out
// so it's necessary to pass in the array class as the resolved class to properly trigger this.
// Otherwise it's impossible to resolve the array clone methods through JVMCI. See
// LinkResolver::check_method_accessability for the matching logic.
resolved = recv_klass ;
}
2017-03-15 10:25:37 -04:00
LinkInfo link_info ( resolved , h_name , h_signature , caller_klass ) ;
2019-11-13 08:23:23 -05:00
Method * m = NULL ;
2016-04-27 16:20:49 -07:00
// Only do exact lookup if receiver klass has been linked. Otherwise,
// the vtable has not been setup, and the LinkResolver will fail.
if ( recv_klass - > is_array_klass ( ) | |
2017-07-06 01:50:26 +02:00
( InstanceKlass : : cast ( recv_klass ) - > is_linked ( ) & & ! recv_klass - > is_interface ( ) ) ) {
2017-03-15 10:25:37 -04:00
if ( resolved - > is_interface ( ) ) {
2016-04-27 16:20:49 -07:00
m = LinkResolver : : resolve_interface_call_or_null ( recv_klass , link_info ) ;
2015-10-08 12:49:30 -10:00
} else {
2016-04-27 16:20:49 -07:00
m = LinkResolver : : resolve_virtual_call_or_null ( recv_klass , link_info ) ;
2015-10-08 12:49:30 -10:00
}
}
2016-04-27 16:20:49 -07:00
2019-11-13 08:23:23 -05:00
if ( m = = NULL ) {
2016-08-29 17:15:20 +00:00
// Return NULL if there was a problem with lookup (uninitialized class, etc.)
2016-04-27 16:20:49 -07:00
return NULL ;
}
2019-11-13 08:23:23 -05:00
JVMCIObject result = JVMCIENV - > get_jvmci_method ( methodHandle ( THREAD , m ) , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
return JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , hasFinalizableSubclass , ( JNIEnv * env , jobject , jobject jvmci_type ) )
2019-05-01 12:31:29 -07:00
Klass * klass = JVMCIENV - > asKlass ( jvmci_type ) ;
2015-10-08 12:49:30 -10:00
assert ( klass ! = NULL , " method must not be called for primitive types " ) ;
return Dependencies : : find_finalizable_subclass ( klass ) ! = NULL ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getClassInitializer , ( JNIEnv * env , jobject , jobject jvmci_type ) )
2019-05-01 12:31:29 -07:00
Klass * klass = JVMCIENV - > asKlass ( jvmci_type ) ;
2017-12-22 18:34:36 +01:00
if ( ! klass - > is_instance_klass ( ) ) {
return NULL ;
}
InstanceKlass * iklass = InstanceKlass : : cast ( klass ) ;
2019-11-13 08:23:23 -05:00
methodHandle clinit ( THREAD , iklass - > class_initializer ( ) ) ;
JVMCIObject result = JVMCIENV - > get_jvmci_method ( clinit , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
return JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jlong , getMaxCallTargetOffset , ( JNIEnv * env , jobject , jlong addr ) )
2015-10-08 12:49:30 -10:00
address target_addr = ( address ) addr ;
if ( target_addr ! = 0x0 ) {
int64_t off_low = ( int64_t ) target_addr - ( ( int64_t ) CodeCache : : low_bound ( ) + sizeof ( int ) ) ;
int64_t off_high = ( int64_t ) target_addr - ( ( int64_t ) CodeCache : : high_bound ( ) + sizeof ( int ) ) ;
return MAX2 ( ABS ( off_low ) , ABS ( off_high ) ) ;
}
return - 1 ;
C2V_END
2019-05-01 12:31:29 -07:00
C2V_VMENTRY ( void , setNotInlinableOrCompilable , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2015-10-08 12:49:30 -10:00
method - > set_not_c1_compilable ( ) ;
method - > set_not_c2_compilable ( ) ;
method - > set_dont_inline ( true ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , installCode , ( JNIEnv * env , jobject , jobject target , jobject compiled_code ,
2019-05-01 12:31:29 -07:00
jobject installed_code , jlong failed_speculations_address , jbyteArray speculations_obj ) )
2015-10-08 12:49:30 -10:00
HandleMark hm ;
2019-05-06 20:05:19 -07:00
JNIHandleMark jni_hm ( thread ) ;
2017-02-27 17:36:36 +01:00
2019-05-01 12:31:29 -07:00
JVMCIObject target_handle = JVMCIENV - > wrap ( target ) ;
JVMCIObject compiled_code_handle = JVMCIENV - > wrap ( compiled_code ) ;
2015-10-08 12:49:30 -10:00
CodeBlob * cb = NULL ;
2019-05-01 12:31:29 -07:00
JVMCIObject installed_code_handle = JVMCIENV - > wrap ( installed_code ) ;
JVMCIPrimitiveArray speculations_handle = JVMCIENV - > wrap ( speculations_obj ) ;
int speculations_len = JVMCIENV - > get_length ( speculations_handle ) ;
char * speculations = NEW_RESOURCE_ARRAY ( char , speculations_len ) ;
JVMCIENV - > copy_bytes_to ( speculations_handle , ( jbyte * ) speculations , 0 , speculations_len ) ;
2015-10-08 12:49:30 -10:00
2017-11-06 21:38:42 +01:00
JVMCICompiler * compiler = JVMCICompiler : : instance ( true , CHECK_JNI_ERR ) ;
2015-10-08 12:49:30 -10:00
TraceTime install_time ( " installCode " , JVMCICompiler : : codeInstallTimer ( ) ) ;
2019-05-01 12:31:29 -07:00
bool is_immutable_PIC = JVMCIENV - > get_HotSpotCompiledCode_isImmutablePIC ( compiled_code_handle ) > 0 ;
CodeInstaller installer ( JVMCIENV , is_immutable_PIC ) ;
JVMCI : : CodeInstallResult result = installer . install ( compiler ,
target_handle ,
compiled_code_handle ,
cb ,
installed_code_handle ,
( FailedSpeculation * * ) ( address ) failed_speculations_address ,
speculations ,
speculations_len ,
JVMCI_CHECK_0 ) ;
2015-10-08 12:49:30 -10:00
if ( PrintCodeCacheOnCompilation ) {
stringStream s ;
2019-05-01 12:31:29 -07:00
// Dump code cache into a buffer before locking the tty,
2015-10-08 12:49:30 -10:00
{
2019-04-25 10:56:31 -04:00
MutexLocker mu ( CodeCache_lock , Mutex : : _no_safepoint_check_flag ) ;
2015-10-08 12:49:30 -10:00
CodeCache : : print_summary ( & s , false ) ;
}
ttyLocker ttyl ;
tty - > print_raw_cr ( s . as_string ( ) ) ;
}
2019-05-01 12:31:29 -07:00
if ( result ! = JVMCI : : ok ) {
2015-10-08 12:49:30 -10:00
assert ( cb = = NULL , " should be " ) ;
} else {
2019-05-01 12:31:29 -07:00
if ( installed_code_handle . is_non_null ( ) ) {
if ( cb - > is_nmethod ( ) ) {
assert ( JVMCIENV - > isa_HotSpotNmethod ( installed_code_handle ) , " wrong type " ) ;
// Clear the link to an old nmethod first
JVMCIObject nmethod_mirror = installed_code_handle ;
JVMCIENV - > invalidate_nmethod_mirror ( nmethod_mirror , JVMCI_CHECK_0 ) ;
} else {
assert ( JVMCIENV - > isa_InstalledCode ( installed_code_handle ) , " wrong type " ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
// Initialize the link to the new code blob
JVMCIENV - > initialize_installed_code ( installed_code_handle , cb , JVMCI_CHECK_0 ) ;
2015-10-08 12:49:30 -10:00
}
}
return result ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , getMetadata , ( JNIEnv * env , jobject , jobject target , jobject compiled_code , jobject metadata ) )
2018-11-02 00:26:25 -07:00
# if INCLUDE_AOT
2015-10-08 12:49:30 -10:00
HandleMark hm ;
2019-05-01 12:31:29 -07:00
assert ( JVMCIENV - > is_hotspot ( ) , " AOT code is executed only in HotSpot mode " ) ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
JVMCIObject target_handle = JVMCIENV - > wrap ( target ) ;
JVMCIObject compiled_code_handle = JVMCIENV - > wrap ( compiled_code ) ;
JVMCIObject metadata_handle = JVMCIENV - > wrap ( metadata ) ;
2015-10-08 12:49:30 -10:00
CodeMetadata code_metadata ;
2019-05-01 12:31:29 -07:00
CodeInstaller installer ( JVMCIENV , true /* immutable PIC compilation */ ) ;
JVMCI : : CodeInstallResult result = installer . gather_metadata ( target_handle , compiled_code_handle , code_metadata , JVMCI_CHECK_0 ) ;
if ( result ! = JVMCI : : ok ) {
2015-10-08 12:49:30 -10:00
return result ;
}
if ( code_metadata . get_nr_pc_desc ( ) > 0 ) {
2019-05-01 12:31:29 -07:00
int size = sizeof ( PcDesc ) * code_metadata . get_nr_pc_desc ( ) ;
JVMCIPrimitiveArray array = JVMCIENV - > new_byteArray ( size , JVMCI_CHECK_ ( JVMCI : : cache_full ) ) ;
JVMCIENV - > copy_bytes_from ( ( jbyte * ) code_metadata . get_pc_desc ( ) , array , 0 , size ) ;
HotSpotJVMCI : : HotSpotMetaData : : set_pcDescBytes ( JVMCIENV , metadata_handle , array ) ;
2015-10-08 12:49:30 -10:00
}
if ( code_metadata . get_scopes_size ( ) > 0 ) {
2019-05-01 12:31:29 -07:00
int size = code_metadata . get_scopes_size ( ) ;
JVMCIPrimitiveArray array = JVMCIENV - > new_byteArray ( size , JVMCI_CHECK_ ( JVMCI : : cache_full ) ) ;
JVMCIENV - > copy_bytes_from ( ( jbyte * ) code_metadata . get_scopes_desc ( ) , array , 0 , size ) ;
HotSpotJVMCI : : HotSpotMetaData : : set_scopesDescBytes ( JVMCIENV , metadata_handle , array ) ;
2015-10-08 12:49:30 -10:00
}
RelocBuffer * reloc_buffer = code_metadata . get_reloc_buffer ( ) ;
2019-05-01 12:31:29 -07:00
int size = ( int ) reloc_buffer - > size ( ) ;
JVMCIPrimitiveArray array = JVMCIENV - > new_byteArray ( size , JVMCI_CHECK_ ( JVMCI : : cache_full ) ) ;
JVMCIENV - > copy_bytes_from ( ( jbyte * ) reloc_buffer - > begin ( ) , array , 0 , size ) ;
HotSpotJVMCI : : HotSpotMetaData : : set_relocBytes ( JVMCIENV , metadata_handle , array ) ;
2015-10-08 12:49:30 -10:00
const OopMapSet * oopMapSet = installer . oopMapSet ( ) ;
{
ResourceMark mark ;
ImmutableOopMapBuilder builder ( oopMapSet ) ;
2019-05-01 12:31:29 -07:00
int size = builder . heap_size ( ) ;
JVMCIPrimitiveArray array = JVMCIENV - > new_byteArray ( size , JVMCI_CHECK_ ( JVMCI : : cache_full ) ) ;
builder . generate_into ( ( address ) HotSpotJVMCI : : resolve ( array ) - > byte_at_addr ( 0 ) ) ;
HotSpotJVMCI : : HotSpotMetaData : : set_oopMaps ( JVMCIENV , metadata_handle , array ) ;
2015-10-08 12:49:30 -10:00
}
2016-12-11 19:07:04 -08:00
AOTOopRecorder * recorder = code_metadata . get_oop_recorder ( ) ;
2017-10-19 19:23:48 -07:00
int nr_meta_refs = recorder - > nr_meta_refs ( ) ;
2019-05-01 12:31:29 -07:00
JVMCIObjectArray metadataArray = JVMCIENV - > new_Object_array ( nr_meta_refs , JVMCI_CHECK_ ( JVMCI : : cache_full ) ) ;
2017-10-19 19:23:48 -07:00
for ( int i = 0 ; i < nr_meta_refs ; + + i ) {
jobject element = recorder - > meta_element ( i ) ;
if ( element = = NULL ) {
2019-05-01 12:31:29 -07:00
return JVMCI : : cache_full ;
2017-10-19 19:23:48 -07:00
}
2019-05-01 12:31:29 -07:00
JVMCIENV - > put_object_at ( metadataArray , i , JVMCIENV - > wrap ( element ) ) ;
2016-12-11 19:07:04 -08:00
}
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotMetaData : : set_metadata ( JVMCIENV , metadata_handle , metadataArray ) ;
2015-10-08 12:49:30 -10:00
ExceptionHandlerTable * handler = code_metadata . get_exception_table ( ) ;
int table_size = handler - > size_in_bytes ( ) ;
2019-05-01 12:31:29 -07:00
JVMCIPrimitiveArray exceptionArray = JVMCIENV - > new_byteArray ( table_size , JVMCI_CHECK_ ( JVMCI : : cache_full ) ) ;
2015-10-08 12:49:30 -10:00
if ( table_size > 0 ) {
2019-05-01 12:31:29 -07:00
handler - > copy_bytes_to ( ( address ) HotSpotJVMCI : : resolve ( exceptionArray ) - > byte_at_addr ( 0 ) ) ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotMetaData : : set_exceptionBytes ( JVMCIENV , metadata_handle , exceptionArray ) ;
2015-10-08 12:49:30 -10:00
2019-06-07 10:26:21 -07:00
ImplicitExceptionTable * implicit = code_metadata . get_implicit_exception_table ( ) ;
int implicit_table_size = implicit - > size_in_bytes ( ) ;
JVMCIPrimitiveArray implicitExceptionArray = JVMCIENV - > new_byteArray ( implicit_table_size , JVMCI_CHECK_ ( JVMCI : : cache_full ) ) ;
if ( implicit_table_size > 0 ) {
implicit - > copy_bytes_to ( ( address ) HotSpotJVMCI : : resolve ( implicitExceptionArray ) - > byte_at_addr ( 0 ) , implicit_table_size ) ;
}
HotSpotJVMCI : : HotSpotMetaData : : set_implicitExceptionBytes ( JVMCIENV , metadata_handle , implicitExceptionArray ) ;
2015-10-08 12:49:30 -10:00
return result ;
2018-11-02 00:26:25 -07:00
# else
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_0 ( InternalError , " unimplemented " ) ;
2018-11-02 00:26:25 -07:00
# endif
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-01 12:31:29 -07:00
C2V_VMENTRY ( void , resetCompilationStatistics , ( JNIEnv * env , jobject ) )
2017-11-06 21:38:42 +01:00
JVMCICompiler * compiler = JVMCICompiler : : instance ( true , CHECK ) ;
2015-10-08 12:49:30 -10:00
CompilerStatistics * stats = compiler - > stats ( ) ;
stats - > _standard . reset ( ) ;
stats - > _osr . reset ( ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , disassembleCodeBlob , ( JNIEnv * env , jobject , jobject installedCode ) )
2015-10-08 12:49:30 -10:00
HandleMark hm ;
2015-11-04 07:23:23 -10:00
if ( installedCode = = NULL ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_NULL ( NullPointerException , " installedCode is null " ) ;
2015-11-04 07:23:23 -10:00
}
2019-05-01 12:31:29 -07:00
JVMCIObject installedCodeObject = JVMCIENV - > wrap ( installedCode ) ;
CodeBlob * cb = JVMCIENV - > asCodeBlob ( installedCodeObject ) ;
2015-10-08 12:49:30 -10:00
if ( cb = = NULL ) {
return NULL ;
}
// We don't want the stringStream buffer to resize during disassembly as it
// uses scoped resource memory. If a nested function called during disassembly uses
// a ResourceMark and the buffer expands within the scope of the mark,
// the buffer becomes garbage when that scope is exited. Experience shows that
// the disassembled code is typically about 10x the code size so a fixed buffer
// sized to 20x code size plus a fixed amount for header info should be sufficient.
int bufferSize = cb - > code_size ( ) * 20 + 1024 ;
char * buffer = NEW_RESOURCE_ARRAY ( char , bufferSize ) ;
stringStream st ( buffer , bufferSize ) ;
if ( cb - > is_nmethod ( ) ) {
nmethod * nm = ( nmethod * ) cb ;
if ( ! nm - > is_alive ( ) ) {
return NULL ;
}
}
2015-12-18 20:23:26 +03:00
Disassembler : : decode ( cb , & st ) ;
2015-10-08 12:49:30 -10:00
if ( st . size ( ) < = 0 ) {
return NULL ;
}
2019-05-01 12:31:29 -07:00
JVMCIObject result = JVMCIENV - > create_string ( st . as_string ( ) , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getStackTraceElement , ( JNIEnv * env , jobject , jobject jvmci_method , int bci ) )
2015-10-08 12:49:30 -10:00
HandleMark hm ;
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2019-05-01 12:31:29 -07:00
JVMCIObject element = JVMCIENV - > new_StackTraceElement ( method , bci , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( element ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , executeHotSpotNmethod , ( JNIEnv * env , jobject , jobject args , jobject hs_nmethod ) )
// The incoming arguments array would have to contain JavaConstants instead of regular objects
// and the return value would have to be wrapped as a JavaConstant.
requireInHotSpot ( " executeHotSpotNmethod " , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
2015-10-08 12:49:30 -10:00
HandleMark hm ;
2019-05-01 12:31:29 -07:00
JVMCIObject nmethod_mirror = JVMCIENV - > wrap ( hs_nmethod ) ;
nmethod * nm = JVMCIENV - > asNmethod ( nmethod_mirror ) ;
if ( nm = = NULL ) {
JVMCI_THROW_NULL ( InvalidInstalledCodeException ) ;
2015-10-08 12:49:30 -10:00
}
2019-11-13 08:23:23 -05:00
methodHandle mh ( THREAD , nm - > method ( ) ) ;
2015-10-08 12:49:30 -10:00
Symbol * signature = mh - > signature ( ) ;
JavaCallArguments jca ( mh - > size_of_parameters ( ) ) ;
JavaArgumentUnboxer jap ( signature , & jca , ( arrayOop ) JNIHandles : : resolve ( args ) , mh - > is_static ( ) ) ;
JavaValue result ( jap . get_ret_type ( ) ) ;
jca . set_alternative_target ( nm ) ;
JavaCalls : : call ( & result , mh , & jca , CHECK_NULL ) ;
if ( jap . get_ret_type ( ) = = T_VOID ) {
return NULL ;
2019-09-23 14:49:04 -04:00
} else if ( is_reference_type ( jap . get_ret_type ( ) ) ) {
2019-05-01 12:31:29 -07:00
return JNIHandles : : make_local ( ( oop ) result . get_jobject ( ) ) ;
2015-10-08 12:49:30 -10:00
} else {
jvalue * value = ( jvalue * ) result . get_value_addr ( ) ;
// Narrow the value down if required (Important on big endian machines)
switch ( jap . get_ret_type ( ) ) {
case T_BOOLEAN :
value - > z = ( jboolean ) value - > i ;
break ;
case T_BYTE :
value - > b = ( jbyte ) value - > i ;
break ;
case T_CHAR :
value - > c = ( jchar ) value - > i ;
break ;
case T_SHORT :
value - > s = ( jshort ) value - > i ;
break ;
2017-07-06 01:50:26 +02:00
default :
break ;
}
2019-05-01 12:31:29 -07:00
JVMCIObject o = JVMCIENV - > create_box ( jap . get_ret_type ( ) , value , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( o ) ;
2015-10-08 12:49:30 -10:00
}
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jlongArray , getLineNumberTable , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-05-01 12:31:29 -07:00
Method * method = JVMCIENV - > asMethod ( jvmci_method ) ;
2015-10-08 12:49:30 -10:00
if ( ! method - > has_linenumber_table ( ) ) {
return NULL ;
}
u2 num_entries = 0 ;
CompressedLineNumberReadStream streamForSize ( method - > compressed_linenumber_table ( ) ) ;
while ( streamForSize . read_pair ( ) ) {
num_entries + + ;
}
CompressedLineNumberReadStream stream ( method - > compressed_linenumber_table ( ) ) ;
2019-05-01 12:31:29 -07:00
JVMCIPrimitiveArray result = JVMCIENV - > new_longArray ( 2 * num_entries , JVMCI_CHECK_NULL ) ;
2015-10-08 12:49:30 -10:00
int i = 0 ;
jlong value ;
while ( stream . read_pair ( ) ) {
value = ( ( long ) stream . bci ( ) ) ;
2019-05-01 12:31:29 -07:00
JVMCIENV - > put_long_at ( result , i , value ) ;
2015-10-08 12:49:30 -10:00
value = ( ( long ) stream . line ( ) ) ;
2019-05-01 12:31:29 -07:00
JVMCIENV - > put_long_at ( result , i + 1 , value ) ;
2015-10-08 12:49:30 -10:00
i + = 2 ;
}
2019-05-01 12:31:29 -07:00
return ( jlongArray ) JVMCIENV - > get_jobject ( result ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jlong , getLocalVariableTableStart , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-05-01 12:31:29 -07:00
Method * method = JVMCIENV - > asMethod ( jvmci_method ) ;
2015-10-08 12:49:30 -10:00
if ( ! method - > has_localvariable_table ( ) ) {
return 0 ;
}
return ( jlong ) ( address ) method - > localvariable_table_start ( ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , getLocalVariableTableLength , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-05-01 12:31:29 -07:00
Method * method = JVMCIENV - > asMethod ( jvmci_method ) ;
2015-10-08 12:49:30 -10:00
return method - > localvariable_table_length ( ) ;
C2V_END
2019-05-01 12:31:29 -07:00
C2V_VMENTRY ( void , reprofile , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2015-10-08 12:49:30 -10:00
MethodCounters * mcs = method - > method_counters ( ) ;
if ( mcs ! = NULL ) {
mcs - > clear_counters ( ) ;
}
NOT_PRODUCT ( method - > set_compiled_invocation_count ( 0 ) ) ;
2016-04-26 10:28:51 +02:00
CompiledMethod * code = method - > code ( ) ;
2015-10-08 12:49:30 -10:00
if ( code ! = NULL ) {
code - > make_not_entrant ( ) ;
}
MethodData * method_data = method - > method_data ( ) ;
if ( method_data = = NULL ) {
ClassLoaderData * loader_data = method - > method_holder ( ) - > class_loader_data ( ) ;
method_data = MethodData : : allocate ( loader_data , method , CHECK ) ;
method - > set_method_data ( method_data ) ;
} else {
method_data - > initialize ( ) ;
}
C2V_END
2019-05-01 12:31:29 -07:00
C2V_VMENTRY ( void , invalidateHotSpotNmethod , ( JNIEnv * env , jobject , jobject hs_nmethod ) )
JVMCIObject nmethod_mirror = JVMCIENV - > wrap ( hs_nmethod ) ;
JVMCIENV - > invalidate_nmethod_mirror ( nmethod_mirror , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , readUncompressedOop , ( JNIEnv * env , jobject , jlong addr ) )
2019-05-01 12:31:29 -07:00
oop ret = RawAccess < > : : oop_load ( ( oop * ) ( address ) addr ) ;
return JVMCIENV - > get_jobject ( JVMCIENV - > get_object_constant ( ret ) ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jlongArray , collectCounters , ( JNIEnv * env , jobject ) )
// Returns a zero length array if counters aren't enabled
2019-05-01 12:31:29 -07:00
JVMCIPrimitiveArray array = JVMCIENV - > new_longArray ( JVMCICounterSize , JVMCI_CHECK_NULL ) ;
2019-05-06 20:05:19 -07:00
if ( JVMCICounterSize > 0 ) {
jlong * temp_array = NEW_RESOURCE_ARRAY ( jlong , JVMCICounterSize ) ;
JavaThread : : collect_counters ( temp_array , JVMCICounterSize ) ;
JVMCIENV - > copy_longs_from ( temp_array , array , 0 , JVMCICounterSize ) ;
}
2019-05-01 12:31:29 -07:00
return ( jlongArray ) JVMCIENV - > get_jobject ( array ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-06-04 12:44:53 -07:00
C2V_VMENTRY_0 ( jint , getCountersSize , ( JNIEnv * env , jobject ) )
return ( jint ) JVMCICounterSize ;
C2V_END
2019-09-24 03:28:42 -04:00
C2V_VMENTRY ( void , setCountersSize , ( JNIEnv * env , jobject , jint new_size ) )
JavaThread : : resize_all_jvmci_counters ( new_size ) ;
2019-06-04 12:44:53 -07:00
C2V_END
C2V_VMENTRY_0 ( jint , allocateCompileId , ( JNIEnv * env , jobject , jobject jvmci_method , int entry_bci ) )
2015-10-08 12:49:30 -10:00
HandleMark hm ;
2019-05-01 12:31:29 -07:00
if ( jvmci_method = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
2015-10-08 12:49:30 -10:00
}
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2015-10-08 12:49:30 -10:00
if ( entry_bci > = method - > code_size ( ) | | entry_bci < - 1 ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_0 ( IllegalArgumentException , err_msg ( " Unexpected bci %d " , entry_bci ) ) ;
2015-10-08 12:49:30 -10:00
}
return CompileBroker : : assign_compile_id_unlocked ( THREAD , method , entry_bci ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , isMature , ( JNIEnv * env , jobject , jlong metaspace_method_data ) )
2019-05-01 12:31:29 -07:00
MethodData * mdo = JVMCIENV - > asMethodData ( metaspace_method_data ) ;
2015-10-08 12:49:30 -10:00
return mdo ! = NULL & & mdo - > is_mature ( ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , hasCompiledCodeForOSR , ( JNIEnv * env , jobject , jobject jvmci_method , int entry_bci , int comp_level ) )
2019-05-01 12:31:29 -07:00
Method * method = JVMCIENV - > asMethod ( jvmci_method ) ;
2015-10-08 12:49:30 -10:00
return method - > lookup_osr_nmethod_for ( entry_bci , comp_level , true ) ! = NULL ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getSymbol , ( JNIEnv * env , jobject , jlong symbol ) )
2019-05-01 12:31:29 -07:00
JVMCIObject sym = JVMCIENV - > create_string ( ( Symbol * ) ( address ) symbol , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( sym ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-01 12:31:29 -07:00
bool matches ( jobjectArray methods , Method * method , JVMCIEnv * JVMCIENV ) {
2015-10-08 12:49:30 -10:00
objArrayOop methods_oop = ( objArrayOop ) JNIHandles : : resolve ( methods ) ;
for ( int i = 0 ; i < methods_oop - > length ( ) ; i + + ) {
2015-11-04 07:23:23 -10:00
oop resolved = methods_oop - > obj_at ( i ) ;
2019-05-01 12:31:29 -07:00
if ( ( resolved - > klass ( ) = = HotSpotJVMCI : : HotSpotResolvedJavaMethodImpl : : klass ( ) ) & & HotSpotJVMCI : : asMethod ( JVMCIENV , resolved ) = = method ) {
2015-10-08 12:49:30 -10:00
return true ;
}
}
return false ;
}
2018-03-07 19:32:54 -08:00
void call_interface ( JavaValue * result , Klass * spec_klass , Symbol * name , Symbol * signature , JavaCallArguments * args , TRAPS ) {
CallInfo callinfo ;
Handle receiver = args - > receiver ( ) ;
Klass * recvrKlass = receiver . is_null ( ) ? ( Klass * ) NULL : receiver - > klass ( ) ;
LinkInfo link_info ( spec_klass , name , signature ) ;
LinkResolver : : resolve_interface_call (
callinfo , receiver , recvrKlass , link_info , true , CHECK ) ;
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , callinfo . selected_method ( ) ) ;
2018-03-07 19:32:54 -08:00
assert ( method . not_null ( ) , " should have thrown exception " ) ;
// Invoke the method
JavaCalls : : call ( result , method , args , CHECK ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , iterateFrames , ( JNIEnv * env , jobject compilerToVM , jobjectArray initial_methods , jobjectArray match_methods , jint initialSkip , jobject visitor_handle ) )
2015-10-08 12:49:30 -10:00
2018-03-07 19:32:54 -08:00
if ( ! thread - > has_last_Java_frame ( ) ) {
return NULL ;
}
Handle visitor ( THREAD , JNIHandles : : resolve_non_null ( visitor_handle ) ) ;
2015-10-08 12:49:30 -10:00
2019-05-06 20:05:19 -07:00
requireInHotSpot ( " iterateFrames " , JVMCI_CHECK_NULL ) ;
2018-03-07 19:32:54 -08:00
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotStackFrameReference : : klass ( ) - > initialize ( CHECK_NULL ) ;
Handle frame_reference = HotSpotJVMCI : : HotSpotStackFrameReference : : klass ( ) - > allocate_instance_handle ( CHECK_NULL ) ;
StackFrameStream fst ( thread ) ;
2018-03-07 19:32:54 -08:00
jobjectArray methods = initial_methods ;
2015-10-08 12:49:30 -10:00
int frame_number = 0 ;
vframe * vf = vframe : : new_vframe ( fst . current ( ) , fst . register_map ( ) , thread ) ;
while ( true ) {
// look for the given method
2018-03-07 19:32:54 -08:00
bool realloc_called = false ;
2015-10-08 12:49:30 -10:00
while ( true ) {
StackValueCollection * locals = NULL ;
if ( vf - > is_compiled_frame ( ) ) {
// compiled method frame
compiledVFrame * cvf = compiledVFrame : : cast ( vf ) ;
2019-05-01 12:31:29 -07:00
if ( methods = = NULL | | matches ( methods , cvf - > method ( ) , JVMCIENV ) ) {
2015-10-08 12:49:30 -10:00
if ( initialSkip > 0 ) {
2018-03-07 19:32:54 -08:00
initialSkip - - ;
2015-10-08 12:49:30 -10:00
} else {
ScopeDesc * scope = cvf - > scope ( ) ;
2017-08-10 12:16:35 -07:00
// native wrappers do not have a scope
2015-10-08 12:49:30 -10:00
if ( scope ! = NULL & & scope - > objects ( ) ! = NULL ) {
2018-03-07 19:32:54 -08:00
GrowableArray < ScopeValue * > * objects ;
if ( ! realloc_called ) {
objects = scope - > objects ( ) ;
} else {
// some object might already have been re-allocated, only reallocate the non-allocated ones
objects = new GrowableArray < ScopeValue * > ( scope - > objects ( ) - > length ( ) ) ;
for ( int i = 0 ; i < scope - > objects ( ) - > length ( ) ; i + + ) {
ObjectValue * sv = ( ObjectValue * ) scope - > objects ( ) - > at ( i ) ;
if ( sv - > value ( ) . is_null ( ) ) {
2018-08-31 11:43:06 +02:00
objects - > append ( sv ) ;
2018-03-07 19:32:54 -08:00
}
}
}
2019-06-03 13:21:02 -07:00
bool realloc_failures = Deoptimization : : realloc_objects ( thread , fst . current ( ) , fst . register_map ( ) , objects , CHECK_NULL ) ;
2018-03-07 19:32:54 -08:00
Deoptimization : : reassign_fields ( fst . current ( ) , fst . register_map ( ) , objects , realloc_failures , false ) ;
realloc_called = true ;
2015-10-08 12:49:30 -10:00
GrowableArray < ScopeValue * > * local_values = scope - > locals ( ) ;
2018-01-18 10:05:32 -08:00
assert ( local_values ! = NULL , " NULL locals " ) ;
2017-08-10 12:16:35 -07:00
typeArrayOop array_oop = oopFactory : : new_boolArray ( local_values - > length ( ) , CHECK_NULL ) ;
2017-02-15 22:59:57 -05:00
typeArrayHandle array ( THREAD , array_oop ) ;
2015-10-08 12:49:30 -10:00
for ( int i = 0 ; i < local_values - > length ( ) ; i + + ) {
ScopeValue * value = local_values - > at ( i ) ;
if ( value - > is_object ( ) ) {
array - > bool_at_put ( i , true ) ;
}
}
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotStackFrameReference : : set_localIsVirtual ( JVMCIENV , frame_reference ( ) , array ( ) ) ;
2015-10-08 12:49:30 -10:00
} else {
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotStackFrameReference : : set_localIsVirtual ( JVMCIENV , frame_reference ( ) , NULL ) ;
2015-10-08 12:49:30 -10:00
}
locals = cvf - > locals ( ) ;
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotStackFrameReference : : set_bci ( JVMCIENV , frame_reference ( ) , cvf - > bci ( ) ) ;
2019-11-13 08:23:23 -05:00
methodHandle mh ( THREAD , cvf - > method ( ) ) ;
JVMCIObject method = JVMCIENV - > get_jvmci_method ( mh , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotStackFrameReference : : set_method ( JVMCIENV , frame_reference ( ) , JNIHandles : : resolve ( method . as_jobject ( ) ) ) ;
2015-10-08 12:49:30 -10:00
}
}
} else if ( vf - > is_interpreted_frame ( ) ) {
// interpreted method frame
interpretedVFrame * ivf = interpretedVFrame : : cast ( vf ) ;
2019-05-01 12:31:29 -07:00
if ( methods = = NULL | | matches ( methods , ivf - > method ( ) , JVMCIENV ) ) {
2015-10-08 12:49:30 -10:00
if ( initialSkip > 0 ) {
2018-03-07 19:32:54 -08:00
initialSkip - - ;
2015-10-08 12:49:30 -10:00
} else {
locals = ivf - > locals ( ) ;
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotStackFrameReference : : set_bci ( JVMCIENV , frame_reference ( ) , ivf - > bci ( ) ) ;
2019-11-13 08:23:23 -05:00
methodHandle mh ( THREAD , ivf - > method ( ) ) ;
JVMCIObject method = JVMCIENV - > get_jvmci_method ( mh , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotStackFrameReference : : set_method ( JVMCIENV , frame_reference ( ) , JNIHandles : : resolve ( method . as_jobject ( ) ) ) ;
HotSpotJVMCI : : HotSpotStackFrameReference : : set_localIsVirtual ( JVMCIENV , frame_reference ( ) , NULL ) ;
2015-10-08 12:49:30 -10:00
}
}
}
// locals != NULL means that we found a matching frame and result is already partially initialized
if ( locals ! = NULL ) {
2018-03-07 19:32:54 -08:00
methods = match_methods ;
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotStackFrameReference : : set_compilerToVM ( JVMCIENV , frame_reference ( ) , JNIHandles : : resolve ( compilerToVM ) ) ;
HotSpotJVMCI : : HotSpotStackFrameReference : : set_stackPointer ( JVMCIENV , frame_reference ( ) , ( jlong ) fst . current ( ) - > sp ( ) ) ;
HotSpotJVMCI : : HotSpotStackFrameReference : : set_frameNumber ( JVMCIENV , frame_reference ( ) , frame_number ) ;
2015-10-08 12:49:30 -10:00
// initialize the locals array
2017-02-15 22:59:57 -05:00
objArrayOop array_oop = oopFactory : : new_objectArray ( locals - > size ( ) , CHECK_NULL ) ;
objArrayHandle array ( THREAD , array_oop ) ;
2015-10-08 12:49:30 -10:00
for ( int i = 0 ; i < locals - > size ( ) ; i + + ) {
StackValue * var = locals - > at ( i ) ;
if ( var - > type ( ) = = T_OBJECT ) {
array - > obj_at_put ( i , locals - > at ( i ) - > get_obj ( ) ( ) ) ;
}
}
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotStackFrameReference : : set_locals ( JVMCIENV , frame_reference ( ) , array ( ) ) ;
HotSpotJVMCI : : HotSpotStackFrameReference : : set_objectsMaterialized ( JVMCIENV , frame_reference ( ) , JNI_FALSE ) ;
2018-03-07 19:32:54 -08:00
JavaValue result ( T_OBJECT ) ;
JavaCallArguments args ( visitor ) ;
args . push_oop ( frame_reference ) ;
2019-05-01 12:31:29 -07:00
call_interface ( & result , HotSpotJVMCI : : InspectedFrameVisitor : : klass ( ) , vmSymbols : : visitFrame_name ( ) , vmSymbols : : visitFrame_signature ( ) , & args , CHECK_NULL ) ;
2018-03-07 19:32:54 -08:00
if ( result . get_jobject ( ) ! = NULL ) {
return JNIHandles : : make_local ( thread , ( oop ) result . get_jobject ( ) ) ;
}
assert ( initialSkip = = 0 , " There should be no match before initialSkip == 0 " ) ;
2019-05-01 12:31:29 -07:00
if ( HotSpotJVMCI : : HotSpotStackFrameReference : : objectsMaterialized ( JVMCIENV , frame_reference ( ) ) = = JNI_TRUE ) {
2018-03-07 19:32:54 -08:00
// the frame has been deoptimized, we need to re-synchronize the frame and vframe
2019-05-01 12:31:29 -07:00
intptr_t * stack_pointer = ( intptr_t * ) HotSpotJVMCI : : HotSpotStackFrameReference : : stackPointer ( JVMCIENV , frame_reference ( ) ) ;
2018-03-07 19:32:54 -08:00
fst = StackFrameStream ( thread ) ;
while ( fst . current ( ) - > sp ( ) ! = stack_pointer & & ! fst . is_done ( ) ) {
fst . next ( ) ;
}
if ( fst . current ( ) - > sp ( ) ! = stack_pointer ) {
THROW_MSG_NULL ( vmSymbols : : java_lang_IllegalStateException ( ) , " stack frame not found after deopt " )
}
vf = vframe : : new_vframe ( fst . current ( ) , fst . register_map ( ) , thread ) ;
if ( ! vf - > is_compiled_frame ( ) ) {
THROW_MSG_NULL ( vmSymbols : : java_lang_IllegalStateException ( ) , " compiled stack frame expected " )
}
for ( int i = 0 ; i < frame_number ; i + + ) {
if ( vf - > is_top ( ) ) {
THROW_MSG_NULL ( vmSymbols : : java_lang_IllegalStateException ( ) , " vframe not found after deopt " )
}
vf = vf - > sender ( ) ;
assert ( vf - > is_compiled_frame ( ) , " Wrong frame type " ) ;
}
}
2019-05-01 12:31:29 -07:00
frame_reference = HotSpotJVMCI : : HotSpotStackFrameReference : : klass ( ) - > allocate_instance_handle ( CHECK_NULL ) ;
HotSpotJVMCI : : HotSpotStackFrameReference : : klass ( ) - > initialize ( CHECK_NULL ) ;
2015-10-08 12:49:30 -10:00
}
if ( vf - > is_top ( ) ) {
break ;
}
frame_number + + ;
vf = vf - > sender ( ) ;
} // end of vframe loop
if ( fst . is_done ( ) ) {
break ;
}
fst . next ( ) ;
vf = vframe : : new_vframe ( fst . current ( ) , fst . register_map ( ) , thread ) ;
frame_number = 0 ;
} // end of frame loop
// the end was reached without finding a matching method
return NULL ;
C2V_END
2019-05-01 12:31:29 -07:00
C2V_VMENTRY ( void , resolveInvokeDynamicInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2015-10-08 12:49:30 -10:00
CallInfo callInfo ;
LinkResolver : : resolve_invoke ( callInfo , Handle ( ) , cp , index , Bytecodes : : _invokedynamic , CHECK ) ;
ConstantPoolCacheEntry * cp_cache_entry = cp - > invokedynamic_cp_cache_entry_at ( index ) ;
cp_cache_entry - > set_dynamic_call ( cp , callInfo ) ;
C2V_END
2019-05-01 12:31:29 -07:00
C2V_VMENTRY ( void , resolveInvokeHandleInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2017-03-15 10:25:37 -04:00
Klass * holder = cp - > klass_ref_at ( index , CHECK ) ;
2016-08-23 15:16:45 +00:00
Symbol * name = cp - > name_ref_at ( index ) ;
2017-03-15 10:25:37 -04:00
if ( MethodHandles : : is_signature_polymorphic_name ( holder , name ) ) {
2016-08-23 15:16:45 +00:00
CallInfo callInfo ;
LinkResolver : : resolve_invoke ( callInfo , Handle ( ) , cp , index , Bytecodes : : _invokehandle , CHECK ) ;
2017-03-15 10:25:37 -04:00
ConstantPoolCacheEntry * cp_cache_entry = cp - > cache ( ) - > entry_at ( cp - > decode_cpcache_index ( index ) ) ;
2016-08-23 15:16:45 +00:00
cp_cache_entry - > set_method_handle ( cp , callInfo ) ;
}
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , isResolvedInvokeHandleInPool , ( JNIEnv * env , jobject , jobject jvmci_constant_pool , jint index ) )
2019-11-13 08:23:23 -05:00
constantPoolHandle cp ( THREAD , JVMCIENV - > asConstantPool ( jvmci_constant_pool ) ) ;
2017-10-19 19:23:48 -07:00
ConstantPoolCacheEntry * cp_cache_entry = cp - > cache ( ) - > entry_at ( cp - > decode_cpcache_index ( index ) ) ;
if ( cp_cache_entry - > is_resolved ( Bytecodes : : _invokehandle ) ) {
// MethodHandle.invoke* --> LambdaForm?
ResourceMark rm ;
LinkInfo link_info ( cp , index , CATCH ) ;
Klass * resolved_klass = link_info . resolved_klass ( ) ;
Symbol * name_sym = cp - > name_ref_at ( index ) ;
vmassert ( MethodHandles : : is_method_handle_invoke_name ( resolved_klass , name_sym ) , " ! " ) ;
vmassert ( MethodHandles : : is_signature_polymorphic_name ( resolved_klass , name_sym ) , " ! " ) ;
2019-11-13 08:23:23 -05:00
methodHandle adapter_method ( THREAD , cp_cache_entry - > f1_as_method ( ) ) ;
2017-10-19 19:23:48 -07:00
methodHandle resolved_method ( adapter_method ) ;
// Can we treat it as a regular invokevirtual?
if ( resolved_method - > method_holder ( ) = = resolved_klass & & resolved_method - > name ( ) = = name_sym ) {
vmassert ( ! resolved_method - > is_static ( ) , " ! " ) ;
vmassert ( MethodHandles : : is_signature_polymorphic_method ( resolved_method ( ) ) , " ! " ) ;
vmassert ( ! MethodHandles : : is_signature_polymorphic_static ( resolved_method - > intrinsic_id ( ) ) , " ! " ) ;
vmassert ( cp_cache_entry - > appendix_if_resolved ( cp ) = = NULL , " ! " ) ;
2019-11-13 08:23:23 -05:00
methodHandle m ( THREAD , LinkResolver : : linktime_resolve_virtual_method_or_null ( link_info ) ) ;
2017-10-19 19:23:48 -07:00
vmassert ( m = = resolved_method , " !! " ) ;
return - 1 ;
}
return Bytecodes : : _invokevirtual ;
}
if ( cp_cache_entry - > is_resolved ( Bytecodes : : _invokedynamic ) ) {
return Bytecodes : : _invokedynamic ;
}
return - 1 ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getSignaturePolymorphicHolders , ( JNIEnv * env , jobject ) )
2019-05-01 12:31:29 -07:00
JVMCIObjectArray holders = JVMCIENV - > new_String_array ( 2 , JVMCI_CHECK_NULL ) ;
JVMCIObject mh = JVMCIENV - > create_string ( " Ljava/lang/invoke/MethodHandle; " , JVMCI_CHECK_NULL ) ;
JVMCIObject vh = JVMCIENV - > create_string ( " Ljava/lang/invoke/VarHandle; " , JVMCI_CHECK_NULL ) ;
JVMCIENV - > put_object_at ( holders , 0 , mh ) ;
JVMCIENV - > put_object_at ( holders , 1 , vh ) ;
return JVMCIENV - > get_jobject ( holders ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , shouldDebugNonSafepoints , ( JNIEnv * env , jobject ) )
2015-10-08 12:49:30 -10:00
//see compute_recording_non_safepoints in debugInfroRec.cpp
if ( JvmtiExport : : should_post_compiled_method_load ( ) & & FLAG_IS_DEFAULT ( DebugNonSafepoints ) ) {
return true ;
}
return DebugNonSafepoints ;
C2V_END
// public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
2019-05-01 12:31:29 -07:00
C2V_VMENTRY ( void , materializeVirtualObjects , ( JNIEnv * env , jobject , jobject _hs_frame , bool invalidate ) )
JVMCIObject hs_frame = JVMCIENV - > wrap ( _hs_frame ) ;
if ( hs_frame . is_null ( ) ) {
JVMCI_THROW_MSG ( NullPointerException , " stack frame is null " ) ;
}
2015-10-08 12:49:30 -10:00
2019-05-06 20:05:19 -07:00
requireInHotSpot ( " materializeVirtualObjects " , JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
2019-05-01 12:31:29 -07:00
JVMCIENV - > HotSpotStackFrameReference_initialize ( JVMCI_CHECK ) ;
2015-10-08 12:49:30 -10:00
// look for the given stack frame
StackFrameStream fst ( thread ) ;
2019-05-01 12:31:29 -07:00
intptr_t * stack_pointer = ( intptr_t * ) JVMCIENV - > get_HotSpotStackFrameReference_stackPointer ( hs_frame ) ;
2015-10-08 12:49:30 -10:00
while ( fst . current ( ) - > sp ( ) ! = stack_pointer & & ! fst . is_done ( ) ) {
fst . next ( ) ;
}
if ( fst . current ( ) - > sp ( ) ! = stack_pointer ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG ( IllegalStateException , " stack frame not found " ) ;
2015-10-08 12:49:30 -10:00
}
if ( invalidate ) {
if ( ! fst . current ( ) - > is_compiled_frame ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG ( IllegalStateException , " compiled stack frame expected " ) ;
2015-10-08 12:49:30 -10:00
}
assert ( fst . current ( ) - > cb ( ) - > is_nmethod ( ) , " nmethod expected " ) ;
( ( nmethod * ) fst . current ( ) - > cb ( ) ) - > make_not_entrant ( ) ;
}
Deoptimization : : deoptimize ( thread , * fst . current ( ) , fst . register_map ( ) , Deoptimization : : Reason_none ) ;
// look for the frame again as it has been updated by deopt (pc, deopt state...)
StackFrameStream fstAfterDeopt ( thread ) ;
while ( fstAfterDeopt . current ( ) - > sp ( ) ! = stack_pointer & & ! fstAfterDeopt . is_done ( ) ) {
fstAfterDeopt . next ( ) ;
}
if ( fstAfterDeopt . current ( ) - > sp ( ) ! = stack_pointer ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG ( IllegalStateException , " stack frame not found after deopt " ) ;
2015-10-08 12:49:30 -10:00
}
vframe * vf = vframe : : new_vframe ( fstAfterDeopt . current ( ) , fstAfterDeopt . register_map ( ) , thread ) ;
if ( ! vf - > is_compiled_frame ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG ( IllegalStateException , " compiled stack frame expected " ) ;
2015-10-08 12:49:30 -10:00
}
GrowableArray < compiledVFrame * > * virtualFrames = new GrowableArray < compiledVFrame * > ( 10 ) ;
while ( true ) {
assert ( vf - > is_compiled_frame ( ) , " Wrong frame type " ) ;
virtualFrames - > push ( compiledVFrame : : cast ( vf ) ) ;
if ( vf - > is_top ( ) ) {
break ;
}
vf = vf - > sender ( ) ;
}
2019-05-01 12:31:29 -07:00
int last_frame_number = JVMCIENV - > get_HotSpotStackFrameReference_frameNumber ( hs_frame ) ;
2015-10-08 12:49:30 -10:00
if ( last_frame_number > = virtualFrames - > length ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG ( IllegalStateException , " invalid frame number " ) ;
2015-10-08 12:49:30 -10:00
}
// Reallocate the non-escaping objects and restore their fields.
assert ( virtualFrames - > at ( last_frame_number ) - > scope ( ) ! = NULL , " invalid scope " ) ;
GrowableArray < ScopeValue * > * objects = virtualFrames - > at ( last_frame_number ) - > scope ( ) - > objects ( ) ;
if ( objects = = NULL ) {
// no objects to materialize
return ;
}
2019-06-03 13:21:02 -07:00
bool realloc_failures = Deoptimization : : realloc_objects ( thread , fstAfterDeopt . current ( ) , fstAfterDeopt . register_map ( ) , objects , CHECK ) ;
2015-10-08 12:49:30 -10:00
Deoptimization : : reassign_fields ( fstAfterDeopt . current ( ) , fstAfterDeopt . register_map ( ) , objects , realloc_failures , false ) ;
for ( int frame_index = 0 ; frame_index < virtualFrames - > length ( ) ; frame_index + + ) {
compiledVFrame * cvf = virtualFrames - > at ( frame_index ) ;
GrowableArray < ScopeValue * > * scopeLocals = cvf - > scope ( ) - > locals ( ) ;
StackValueCollection * locals = cvf - > locals ( ) ;
if ( locals ! = NULL ) {
for ( int i2 = 0 ; i2 < locals - > size ( ) ; i2 + + ) {
StackValue * var = locals - > at ( i2 ) ;
if ( var - > type ( ) = = T_OBJECT & & scopeLocals - > at ( i2 ) - > is_object ( ) ) {
jvalue val ;
val . l = ( jobject ) locals - > at ( i2 ) - > get_obj ( ) ( ) ;
cvf - > update_local ( T_OBJECT , i2 , val ) ;
}
}
}
2018-01-18 09:01:00 -08:00
GrowableArray < ScopeValue * > * scopeExpressions = cvf - > scope ( ) - > expressions ( ) ;
StackValueCollection * expressions = cvf - > expressions ( ) ;
if ( expressions ! = NULL ) {
for ( int i2 = 0 ; i2 < expressions - > size ( ) ; i2 + + ) {
StackValue * var = expressions - > at ( i2 ) ;
if ( var - > type ( ) = = T_OBJECT & & scopeExpressions - > at ( i2 ) - > is_object ( ) ) {
jvalue val ;
val . l = ( jobject ) expressions - > at ( i2 ) - > get_obj ( ) ( ) ;
cvf - > update_stack ( T_OBJECT , i2 , val ) ;
}
}
}
GrowableArray < MonitorValue * > * scopeMonitors = cvf - > scope ( ) - > monitors ( ) ;
GrowableArray < MonitorInfo * > * monitors = cvf - > monitors ( ) ;
if ( monitors ! = NULL ) {
for ( int i2 = 0 ; i2 < monitors - > length ( ) ; i2 + + ) {
cvf - > update_monitor ( i2 , monitors - > at ( i2 ) ) ;
}
}
2015-10-08 12:49:30 -10:00
}
// all locals are materialized by now
2019-05-01 12:31:29 -07:00
JVMCIENV - > set_HotSpotStackFrameReference_localIsVirtual ( hs_frame , NULL ) ;
2015-10-08 12:49:30 -10:00
// update the locals array
2019-05-01 12:31:29 -07:00
JVMCIObjectArray array = JVMCIENV - > get_HotSpotStackFrameReference_locals ( hs_frame ) ;
2015-10-08 12:49:30 -10:00
StackValueCollection * locals = virtualFrames - > at ( last_frame_number ) - > locals ( ) ;
for ( int i = 0 ; i < locals - > size ( ) ; i + + ) {
StackValue * var = locals - > at ( i ) ;
if ( var - > type ( ) = = T_OBJECT ) {
2019-05-01 12:31:29 -07:00
JVMCIENV - > put_object_at ( array , i , HotSpotJVMCI : : wrap ( locals - > at ( i ) - > get_obj ( ) ( ) ) ) ;
2015-10-08 12:49:30 -10:00
}
}
2019-05-01 12:31:29 -07:00
HotSpotJVMCI : : HotSpotStackFrameReference : : set_objectsMaterialized ( JVMCIENV , hs_frame , JNI_TRUE ) ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
// Creates a scope where the current thread is attached and detached
// from HotSpot if it wasn't already attached when entering the scope.
extern " C " void jio_printf ( const char * fmt , . . . ) ;
class AttachDetach : public StackObj {
public :
bool _attached ;
AttachDetach ( JNIEnv * env , Thread * current_thread ) {
if ( current_thread = = NULL ) {
extern struct JavaVM_ main_vm ;
JNIEnv * hotspotEnv ;
jint res = main_vm . AttachCurrentThread ( ( void * * ) & hotspotEnv , NULL ) ;
_attached = res = = JNI_OK ;
static volatile int report_attach_error = 0 ;
2019-11-25 12:33:15 +01:00
if ( res ! = JNI_OK & & report_attach_error = = 0 & & Atomic : : cmpxchg ( & report_attach_error , 0 , 1 ) = = 0 ) {
2019-05-06 20:05:19 -07:00
// Only report an attach error once
jio_printf ( " Warning: attaching current thread to VM failed with %d (future attach errors are suppressed) \n " , res ) ;
}
} else {
_attached = false ;
}
}
~ AttachDetach ( ) {
if ( _attached & & get_current_thread ( ) ! = NULL ) {
extern struct JavaVM_ main_vm ;
jint res = main_vm . DetachCurrentThread ( ) ;
static volatile int report_detach_error = 0 ;
2019-11-25 12:33:15 +01:00
if ( res ! = JNI_OK & & report_detach_error = = 0 & & Atomic : : cmpxchg ( & report_detach_error , 0 , 1 ) = = 0 ) {
2019-05-06 20:05:19 -07:00
// Only report an attach error once
jio_printf ( " Warning: detaching current thread from VM failed with %d (future attach errors are suppressed) \n " , res ) ;
}
}
}
} ;
C2V_VMENTRY_PREFIX ( jint , writeDebugOutput , ( JNIEnv * env , jobject , jbyteArray bytes , jint offset , jint length , bool flush , bool can_throw ) )
AttachDetach ad ( env , base_thread ) ;
bool use_tty = true ;
if ( base_thread = = NULL ) {
if ( ! ad . _attached ) {
// Can only use tty if the current thread is attached
return 0 ;
}
base_thread = get_current_thread ( ) ;
}
JVMCITraceMark jtm ( " writeDebugOutput " ) ;
assert ( base_thread - > is_Java_thread ( ) , " just checking " ) ;
JavaThread * thread = ( JavaThread * ) base_thread ;
C2V_BLOCK ( void , writeDebugOutput , ( JNIEnv * env , jobject , jbyteArray bytes , jint offset , jint length ) )
2015-10-08 12:49:30 -10:00
if ( bytes = = NULL ) {
2019-05-06 20:05:19 -07:00
if ( can_throw ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
return - 1 ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
JVMCIPrimitiveArray array = JVMCIENV - > wrap ( bytes ) ;
2015-10-08 12:49:30 -10:00
// Check if offset and length are non negative.
if ( offset < 0 | | length < 0 ) {
2019-05-06 20:05:19 -07:00
if ( can_throw ) {
JVMCI_THROW_0 ( ArrayIndexOutOfBoundsException ) ;
}
return - 2 ;
2015-10-08 12:49:30 -10:00
}
// Check if the range is valid.
2019-05-01 12:31:29 -07:00
int array_length = JVMCIENV - > get_length ( array ) ;
if ( ( ( ( unsigned int ) length + ( unsigned int ) offset ) > ( unsigned int ) array_length ) ) {
2019-05-06 20:05:19 -07:00
if ( can_throw ) {
JVMCI_THROW_0 ( ArrayIndexOutOfBoundsException ) ;
}
return - 2 ;
2015-10-08 12:49:30 -10:00
}
2019-05-01 12:31:29 -07:00
jbyte buffer [ O_BUFLEN ] ;
2015-10-08 12:49:30 -10:00
while ( length > 0 ) {
2019-05-01 12:31:29 -07:00
int copy_len = MIN2 ( length , ( jint ) O_BUFLEN ) ;
JVMCIENV - > copy_bytes_to ( array , buffer , offset , copy_len ) ;
tty - > write ( ( char * ) buffer , copy_len ) ;
2015-10-08 12:49:30 -10:00
length - = O_BUFLEN ;
offset + = O_BUFLEN ;
}
2019-05-06 20:05:19 -07:00
if ( flush ) {
tty - > flush ( ) ;
}
return 0 ;
2015-10-08 12:49:30 -10:00
C2V_END
2019-05-01 12:31:29 -07:00
C2V_VMENTRY ( void , flushDebugOutput , ( JNIEnv * env , jobject ) )
2015-10-08 12:49:30 -10:00
tty - > flush ( ) ;
C2V_END
2019-06-04 12:44:53 -07:00
C2V_VMENTRY_0 ( jint , methodDataProfileDataSize , ( JNIEnv * env , jobject , jlong metaspace_method_data , jint position ) )
2019-05-01 12:31:29 -07:00
MethodData * mdo = JVMCIENV - > asMethodData ( metaspace_method_data ) ;
2015-11-04 07:23:23 -10:00
ProfileData * profile_data = mdo - > data_at ( position ) ;
if ( mdo - > is_valid ( profile_data ) ) {
return profile_data - > size_in_bytes ( ) ;
}
DataLayout * data = mdo - > extra_data_base ( ) ;
DataLayout * end = mdo - > extra_data_limit ( ) ;
for ( ; ; data = mdo - > next_extra ( data ) ) {
assert ( data < end , " moved past end of extra data " ) ;
profile_data = data - > data_in ( ) ;
if ( mdo - > dp_to_di ( profile_data - > dp ( ) ) = = position ) {
return profile_data - > size_in_bytes ( ) ;
}
}
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_0 ( IllegalArgumentException , err_msg ( " Invalid profile data position %d " , position ) ) ;
2015-11-04 07:23:23 -10:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jlong , getFingerprint , ( JNIEnv * env , jobject , jlong metaspace_klass ) )
2018-11-02 00:26:25 -07:00
# if INCLUDE_AOT
2019-05-01 12:31:29 -07:00
Klass * k = ( Klass * ) ( address ) metaspace_klass ;
2016-12-11 19:07:04 -08:00
if ( k - > is_instance_klass ( ) ) {
return InstanceKlass : : cast ( k ) - > get_stored_fingerprint ( ) ;
} else {
return 0 ;
}
2018-11-02 00:26:25 -07:00
# else
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_0 ( InternalError , " unimplemented " ) ;
2018-11-02 00:26:25 -07:00
# endif
2016-12-11 19:07:04 -08:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getHostClass , ( JNIEnv * env , jobject , jobject jvmci_type ) )
2019-05-01 12:31:29 -07:00
InstanceKlass * k = InstanceKlass : : cast ( JVMCIENV - > asKlass ( jvmci_type ) ) ;
2018-08-20 08:25:57 -04:00
InstanceKlass * host = k - > unsafe_anonymous_host ( ) ;
2018-06-24 21:46:11 -07:00
JVMCIKlassHandle handle ( THREAD , host ) ;
2019-05-01 12:31:29 -07:00
JVMCIObject result = JVMCIENV - > get_jvmci_type ( handle , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getInterfaces , ( JNIEnv * env , jobject , jobject jvmci_type ) )
2019-05-01 12:31:29 -07:00
if ( jvmci_type = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Klass * klass = JVMCIENV - > asKlass ( jvmci_type ) ;
if ( klass = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
if ( ! klass - > is_instance_klass ( ) ) {
JVMCI_THROW_MSG_0 ( InternalError , err_msg ( " Class %s must be instance klass " , klass - > external_name ( ) ) ) ;
}
InstanceKlass * iklass = InstanceKlass : : cast ( klass ) ;
// Regular instance klass, fill in all local interfaces
int size = iklass - > local_interfaces ( ) - > length ( ) ;
JVMCIObjectArray interfaces = JVMCIENV - > new_HotSpotResolvedObjectTypeImpl_array ( size , JVMCI_CHECK_NULL ) ;
for ( int index = 0 ; index < size ; index + + ) {
JVMCIKlassHandle klass ( THREAD ) ;
Klass * k = iklass - > local_interfaces ( ) - > at ( index ) ;
klass = k ;
JVMCIObject type = JVMCIENV - > get_jvmci_type ( klass , JVMCI_CHECK_NULL ) ;
JVMCIENV - > put_object_at ( interfaces , index , type ) ;
}
return JVMCIENV - > get_jobject ( interfaces ) ;
2017-06-16 12:18:46 -07:00
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getComponentType , ( JNIEnv * env , jobject , jobject jvmci_type ) )
2019-05-01 12:31:29 -07:00
if ( jvmci_type = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Klass * klass = JVMCIENV - > asKlass ( jvmci_type ) ;
oop mirror = klass - > java_mirror ( ) ;
if ( java_lang_Class : : is_primitive ( mirror ) | |
! java_lang_Class : : as_Klass ( mirror ) - > is_array_klass ( ) ) {
return NULL ;
}
oop component_mirror = java_lang_Class : : component_mirror ( mirror ) ;
if ( component_mirror = = NULL ) {
return NULL ;
}
Klass * component_klass = java_lang_Class : : as_Klass ( component_mirror ) ;
if ( component_klass ! = NULL ) {
JVMCIKlassHandle klass_handle ( THREAD ) ;
klass_handle = component_klass ;
JVMCIObject result = JVMCIENV - > get_jvmci_type ( klass_handle , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
}
BasicType type = java_lang_Class : : primitive_type ( component_mirror ) ;
JVMCIObject result = JVMCIENV - > get_jvmci_primitive_type ( type ) ;
return JVMCIENV - > get_jobject ( result ) ;
C2V_END
C2V_VMENTRY ( void , ensureInitialized , ( JNIEnv * env , jobject , jobject jvmci_type ) )
if ( jvmci_type = = NULL ) {
JVMCI_THROW ( NullPointerException ) ;
}
Klass * klass = JVMCIENV - > asKlass ( jvmci_type ) ;
if ( klass ! = NULL & & klass - > should_be_initialized ( ) ) {
InstanceKlass * k = InstanceKlass : : cast ( klass ) ;
k - > initialize ( CHECK ) ;
}
C2V_END
2019-06-04 12:44:53 -07:00
C2V_VMENTRY_0 ( jint , interpreterFrameSize , ( JNIEnv * env , jobject , jobject bytecode_frame_handle ) )
2016-01-22 11:11:06 -08:00
if ( bytecode_frame_handle = = NULL ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_0 ( NullPointerException ) ;
2016-01-22 11:11:06 -08:00
}
2019-05-01 12:31:29 -07:00
JVMCIObject top_bytecode_frame = JVMCIENV - > wrap ( bytecode_frame_handle ) ;
JVMCIObject bytecode_frame = top_bytecode_frame ;
2016-01-22 11:11:06 -08:00
int size = 0 ;
int callee_parameters = 0 ;
int callee_locals = 0 ;
2019-05-01 12:31:29 -07:00
Method * method = JVMCIENV - > asMethod ( JVMCIENV - > get_BytecodePosition_method ( bytecode_frame ) ) ;
int extra_args = method - > max_stack ( ) - JVMCIENV - > get_BytecodeFrame_numStack ( bytecode_frame ) ;
2016-01-22 11:11:06 -08:00
2019-05-01 12:31:29 -07:00
while ( bytecode_frame . is_non_null ( ) ) {
int locks = JVMCIENV - > get_BytecodeFrame_numLocks ( bytecode_frame ) ;
int temps = JVMCIENV - > get_BytecodeFrame_numStack ( bytecode_frame ) ;
bool is_top_frame = ( JVMCIENV - > equals ( bytecode_frame , top_bytecode_frame ) ) ;
Method * method = JVMCIENV - > asMethod ( JVMCIENV - > get_BytecodePosition_method ( bytecode_frame ) ) ;
2016-01-22 11:11:06 -08:00
int frame_size = BytesPerWord * Interpreter : : size_activation ( method - > max_stack ( ) ,
temps + callee_parameters ,
extra_args ,
locks ,
callee_parameters ,
callee_locals ,
is_top_frame ) ;
size + = frame_size ;
callee_parameters = method - > size_of_parameters ( ) ;
callee_locals = method - > max_locals ( ) ;
extra_args = 0 ;
2019-05-01 12:31:29 -07:00
bytecode_frame = JVMCIENV - > get_BytecodePosition_caller ( bytecode_frame ) ;
2016-01-22 11:11:06 -08:00
}
return size + Deoptimization : : last_frame_adjust ( 0 , callee_locals ) * BytesPerWord ;
C2V_END
2019-05-01 12:31:29 -07:00
C2V_VMENTRY ( void , compileToBytecode , ( JNIEnv * env , jobject , jobject lambda_form_handle ) )
Handle lambda_form = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( lambda_form_handle ) , JVMCI_CHECK ) ;
2016-09-14 12:34:37 -07:00
if ( lambda_form - > is_a ( SystemDictionary : : LambdaForm_klass ( ) ) ) {
2019-05-14 11:29:18 -04:00
TempNewSymbol compileToBytecode = SymbolTable : : new_symbol ( " compileToBytecode " ) ;
2016-09-14 12:34:37 -07:00
JavaValue result ( T_VOID ) ;
JavaCalls : : call_special ( & result , lambda_form , SystemDictionary : : LambdaForm_klass ( ) , compileToBytecode , vmSymbols : : void_method_signature ( ) , CHECK ) ;
} else {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG ( IllegalArgumentException ,
err_msg ( " Unexpected type: %s " , lambda_form - > klass ( ) - > external_name ( ) ) )
}
C2V_END
2019-06-04 12:44:53 -07:00
C2V_VMENTRY_0 ( jint , getIdentityHashCode , ( JNIEnv * env , jobject , jobject object ) )
2019-05-01 12:31:29 -07:00
Handle obj = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( object ) , JVMCI_CHECK_0 ) ;
return obj - > identity_hash ( ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , isInternedString , ( JNIEnv * env , jobject , jobject object ) )
2019-05-01 12:31:29 -07:00
Handle str = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( object ) , JVMCI_CHECK_0 ) ;
if ( ! java_lang_String : : is_instance ( str ( ) ) ) {
return false ;
}
int len ;
jchar * name = java_lang_String : : as_unicode_string ( str ( ) , len , CHECK_0 ) ;
return ( StringTable : : lookup ( name , len ) ! = NULL ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , unboxPrimitive , ( JNIEnv * env , jobject , jobject object ) )
2019-05-01 12:31:29 -07:00
if ( object = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Handle box = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( object ) , JVMCI_CHECK_NULL ) ;
BasicType type = java_lang_boxing_object : : basic_type ( box ( ) ) ;
jvalue result ;
if ( java_lang_boxing_object : : get_value ( box ( ) , & result ) = = T_ILLEGAL ) {
return NULL ;
}
JVMCIObject boxResult = JVMCIENV - > create_box ( type , & result , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( boxResult ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , boxPrimitive , ( JNIEnv * env , jobject , jobject object ) )
2019-05-01 12:31:29 -07:00
if ( object = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
JVMCIObject box = JVMCIENV - > wrap ( object ) ;
BasicType type = JVMCIENV - > get_box_type ( box ) ;
if ( type = = T_ILLEGAL ) {
return NULL ;
}
jvalue value = JVMCIENV - > get_boxed_value ( type , box ) ;
JavaValue box_result ( T_OBJECT ) ;
JavaCallArguments jargs ;
Klass * box_klass = NULL ;
Symbol * box_signature = NULL ;
# define BOX_CASE(bt, v, argtype, name) \
case bt : \
jargs . push_ # # argtype ( value . v ) ; \
box_klass = SystemDictionary : : name # # _klass ( ) ; \
box_signature = vmSymbols : : name # # _valueOf_signature ( ) ; \
break
switch ( type ) {
BOX_CASE ( T_BOOLEAN , z , int , Boolean ) ;
BOX_CASE ( T_BYTE , b , int , Byte ) ;
BOX_CASE ( T_CHAR , c , int , Character ) ;
BOX_CASE ( T_SHORT , s , int , Short ) ;
BOX_CASE ( T_INT , i , int , Integer ) ;
BOX_CASE ( T_LONG , j , long , Long ) ;
BOX_CASE ( T_FLOAT , f , float , Float ) ;
BOX_CASE ( T_DOUBLE , d , double , Double ) ;
default :
ShouldNotReachHere ( ) ;
}
# undef BOX_CASE
JavaCalls : : call_static ( & box_result ,
box_klass ,
vmSymbols : : valueOf_name ( ) ,
box_signature , & jargs , CHECK_NULL ) ;
oop hotspot_box = ( oop ) box_result . get_jobject ( ) ;
JVMCIObject result = JVMCIENV - > get_object_constant ( hotspot_box , false ) ;
return JVMCIENV - > get_jobject ( result ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobjectArray , getDeclaredConstructors , ( JNIEnv * env , jobject , jobject holder ) )
2019-05-01 12:31:29 -07:00
if ( holder = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Klass * klass = JVMCIENV - > asKlass ( holder ) ;
if ( ! klass - > is_instance_klass ( ) ) {
JVMCIObjectArray methods = JVMCIENV - > new_ResolvedJavaMethod_array ( 0 , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobjectArray ( methods ) ;
}
InstanceKlass * iklass = InstanceKlass : : cast ( klass ) ;
// Ensure class is linked
iklass - > link_class ( CHECK_NULL ) ;
GrowableArray < Method * > constructors_array ;
for ( int i = 0 ; i < iklass - > methods ( ) - > length ( ) ; i + + ) {
Method * m = iklass - > methods ( ) - > at ( i ) ;
if ( m - > is_initializer ( ) & & ! m - > is_static ( ) ) {
constructors_array . append ( m ) ;
}
}
JVMCIObjectArray methods = JVMCIENV - > new_ResolvedJavaMethod_array ( constructors_array . length ( ) , JVMCI_CHECK_NULL ) ;
for ( int i = 0 ; i < constructors_array . length ( ) ; i + + ) {
2019-11-13 08:23:23 -05:00
methodHandle ctor ( THREAD , constructors_array . at ( i ) ) ;
JVMCIObject method = JVMCIENV - > get_jvmci_method ( ctor , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
JVMCIENV - > put_object_at ( methods , i , method ) ;
}
return JVMCIENV - > get_jobjectArray ( methods ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobjectArray , getDeclaredMethods , ( JNIEnv * env , jobject , jobject holder ) )
2019-05-01 12:31:29 -07:00
if ( holder = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Klass * klass = JVMCIENV - > asKlass ( holder ) ;
if ( ! klass - > is_instance_klass ( ) ) {
JVMCIObjectArray methods = JVMCIENV - > new_ResolvedJavaMethod_array ( 0 , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobjectArray ( methods ) ;
}
InstanceKlass * iklass = InstanceKlass : : cast ( klass ) ;
// Ensure class is linked
iklass - > link_class ( CHECK_NULL ) ;
GrowableArray < Method * > methods_array ;
for ( int i = 0 ; i < iklass - > methods ( ) - > length ( ) ; i + + ) {
Method * m = iklass - > methods ( ) - > at ( i ) ;
if ( ! m - > is_initializer ( ) & & ! m - > is_overpass ( ) ) {
methods_array . append ( m ) ;
}
}
JVMCIObjectArray methods = JVMCIENV - > new_ResolvedJavaMethod_array ( methods_array . length ( ) , JVMCI_CHECK_NULL ) ;
for ( int i = 0 ; i < methods_array . length ( ) ; i + + ) {
2019-11-13 08:23:23 -05:00
methodHandle mh ( THREAD , methods_array . at ( i ) ) ;
JVMCIObject method = JVMCIENV - > get_jvmci_method ( mh , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
JVMCIENV - > put_object_at ( methods , i , method ) ;
}
return JVMCIENV - > get_jobjectArray ( methods ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , readFieldValue , ( JNIEnv * env , jobject , jobject object , jobject field , jboolean is_volatile ) )
2019-05-01 12:31:29 -07:00
if ( object = = NULL | | field = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
JVMCIObject field_object = JVMCIENV - > wrap ( field ) ;
JVMCIObject java_type = JVMCIENV - > get_HotSpotResolvedJavaFieldImpl_type ( field_object ) ;
int modifiers = JVMCIENV - > get_HotSpotResolvedJavaFieldImpl_modifiers ( field_object ) ;
Klass * holder = JVMCIENV - > asKlass ( JVMCIENV - > get_HotSpotResolvedJavaFieldImpl_holder ( field_object ) ) ;
if ( ! holder - > is_instance_klass ( ) ) {
JVMCI_THROW_MSG_0 ( InternalError , err_msg ( " Holder %s must be instance klass " , holder - > external_name ( ) ) ) ;
}
InstanceKlass * ik = InstanceKlass : : cast ( holder ) ;
BasicType constant_type ;
if ( JVMCIENV - > isa_HotSpotResolvedPrimitiveType ( java_type ) ) {
constant_type = JVMCIENV - > kindToBasicType ( JVMCIENV - > get_HotSpotResolvedPrimitiveType_kind ( java_type ) , JVMCI_CHECK_NULL ) ;
} else {
constant_type = T_OBJECT ;
}
int displacement = JVMCIENV - > get_HotSpotResolvedJavaFieldImpl_offset ( field_object ) ;
fieldDescriptor fd ;
if ( ! ik - > find_local_field_from_offset ( displacement , ( modifiers & JVM_ACC_STATIC ) ! = 0 , & fd ) ) {
JVMCI_THROW_MSG_0 ( InternalError , err_msg ( " Can't find field with displacement %d " , displacement ) ) ;
}
JVMCIObject base = JVMCIENV - > wrap ( object ) ;
Handle obj ;
if ( JVMCIENV - > isa_HotSpotObjectConstantImpl ( base ) ) {
obj = JVMCIENV - > asConstant ( base , JVMCI_CHECK_NULL ) ;
} else if ( JVMCIENV - > isa_HotSpotResolvedObjectTypeImpl ( base ) ) {
Klass * klass = JVMCIENV - > asKlass ( base ) ;
obj = Handle ( THREAD , klass - > java_mirror ( ) ) ;
} else {
JVMCI_THROW_MSG_NULL ( IllegalArgumentException ,
err_msg ( " Unexpected type: %s " , JVMCIENV - > klass_name ( base ) ) ) ;
}
jlong value = 0 ;
JVMCIObject kind ;
switch ( constant_type ) {
case T_OBJECT : {
oop object = is_volatile ? obj - > obj_field_acquire ( displacement ) : obj - > obj_field ( displacement ) ;
JVMCIObject result = JVMCIENV - > get_object_constant ( object ) ;
if ( result . is_null ( ) ) {
return JVMCIENV - > get_jobject ( JVMCIENV - > get_JavaConstant_NULL_POINTER ( ) ) ;
}
return JVMCIENV - > get_jobject ( result ) ;
}
case T_FLOAT : {
float f = is_volatile ? obj - > float_field_acquire ( displacement ) : obj - > float_field ( displacement ) ;
JVMCIObject result = JVMCIENV - > call_JavaConstant_forFloat ( f , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
}
case T_DOUBLE : {
double f = is_volatile ? obj - > double_field_acquire ( displacement ) : obj - > double_field ( displacement ) ;
JVMCIObject result = JVMCIENV - > call_JavaConstant_forDouble ( f , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
}
case T_BOOLEAN : value = is_volatile ? obj - > bool_field_acquire ( displacement ) : obj - > bool_field ( displacement ) ; break ;
case T_BYTE : value = is_volatile ? obj - > byte_field_acquire ( displacement ) : obj - > byte_field ( displacement ) ; break ;
case T_SHORT : value = is_volatile ? obj - > short_field_acquire ( displacement ) : obj - > short_field ( displacement ) ; break ;
case T_CHAR : value = is_volatile ? obj - > char_field_acquire ( displacement ) : obj - > char_field ( displacement ) ; break ;
case T_INT : value = is_volatile ? obj - > int_field_acquire ( displacement ) : obj - > int_field ( displacement ) ; break ;
case T_LONG : value = is_volatile ? obj - > long_field_acquire ( displacement ) : obj - > long_field ( displacement ) ; break ;
default :
ShouldNotReachHere ( ) ;
}
JVMCIObject result = JVMCIENV - > call_PrimitiveConstant_forTypeChar ( type2char ( constant_type ) , value , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , isInstance , ( JNIEnv * env , jobject , jobject holder , jobject object ) )
2019-05-01 12:31:29 -07:00
if ( object = = NULL | | holder = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Handle obj = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( object ) , JVMCI_CHECK_0 ) ;
Klass * klass = JVMCIENV - > asKlass ( JVMCIENV - > wrap ( holder ) ) ;
return obj - > is_a ( klass ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , isAssignableFrom , ( JNIEnv * env , jobject , jobject holder , jobject otherHolder ) )
2019-05-01 12:31:29 -07:00
if ( holder = = NULL | | otherHolder = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Klass * klass = JVMCIENV - > asKlass ( JVMCIENV - > wrap ( holder ) ) ;
Klass * otherKlass = JVMCIENV - > asKlass ( JVMCIENV - > wrap ( otherHolder ) ) ;
return otherKlass - > is_subtype_of ( klass ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , isTrustedForIntrinsics , ( JNIEnv * env , jobject , jobject holder ) )
2019-05-01 12:31:29 -07:00
if ( holder = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
InstanceKlass * ik = InstanceKlass : : cast ( JVMCIENV - > asKlass ( JVMCIENV - > wrap ( holder ) ) ) ;
2019-10-29 15:35:06 -07:00
if ( ik - > class_loader_data ( ) - > is_boot_class_loader_data ( ) | | ik - > class_loader_data ( ) - > is_platform_class_loader_data ( ) ) {
2019-05-01 12:31:29 -07:00
return true ;
}
return false ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , asJavaType , ( JNIEnv * env , jobject , jobject object ) )
2019-05-01 12:31:29 -07:00
if ( object = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Handle obj = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( object ) , JVMCI_CHECK_NULL ) ;
if ( java_lang_Class : : is_instance ( obj ( ) ) ) {
if ( java_lang_Class : : is_primitive ( obj ( ) ) ) {
JVMCIObject type = JVMCIENV - > get_jvmci_primitive_type ( java_lang_Class : : primitive_type ( obj ( ) ) ) ;
return JVMCIENV - > get_jobject ( type ) ;
}
Klass * klass = java_lang_Class : : as_Klass ( obj ( ) ) ;
JVMCIKlassHandle klass_handle ( THREAD ) ;
klass_handle = klass ;
JVMCIObject type = JVMCIENV - > get_jvmci_type ( klass_handle , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( type ) ;
}
return NULL ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , asString , ( JNIEnv * env , jobject , jobject object ) )
2019-05-01 12:31:29 -07:00
if ( object = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Handle obj = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( object ) , JVMCI_CHECK_NULL ) ;
const char * str = java_lang_String : : as_utf8_string ( obj ( ) ) ;
JVMCIObject result = JVMCIENV - > create_string ( str , JVMCI_CHECK_NULL ) ;
return JVMCIENV - > get_jobject ( result ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jboolean , equals , ( JNIEnv * env , jobject , jobject x , jlong xHandle , jobject y , jlong yHandle ) )
2019-05-01 12:31:29 -07:00
if ( x = = NULL | | y = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
return JVMCIENV - > resolve_handle ( xHandle ) = = JVMCIENV - > resolve_handle ( yHandle ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getJavaMirror , ( JNIEnv * env , jobject , jobject object ) )
2019-05-01 12:31:29 -07:00
if ( object = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
JVMCIObject base_object = JVMCIENV - > wrap ( object ) ;
Handle mirror ;
if ( JVMCIENV - > isa_HotSpotResolvedObjectTypeImpl ( base_object ) ) {
mirror = Handle ( THREAD , JVMCIENV - > asKlass ( base_object ) - > java_mirror ( ) ) ;
} else if ( JVMCIENV - > isa_HotSpotResolvedPrimitiveType ( base_object ) ) {
mirror = JVMCIENV - > asConstant ( JVMCIENV - > get_HotSpotResolvedPrimitiveType_mirror ( base_object ) , JVMCI_CHECK_NULL ) ;
} else {
JVMCI_THROW_MSG_NULL ( IllegalArgumentException ,
err_msg ( " Unexpected type: %s " , JVMCIENV - > klass_name ( base_object ) ) ) ;
}
JVMCIObject result = JVMCIENV - > get_object_constant ( mirror ( ) ) ;
return JVMCIENV - > get_jobject ( result ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , getArrayLength , ( JNIEnv * env , jobject , jobject x ) )
2019-05-01 12:31:29 -07:00
if ( x = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Handle xobj = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( x ) , JVMCI_CHECK_0 ) ;
if ( xobj - > klass ( ) - > is_array_klass ( ) ) {
return arrayOop ( xobj ( ) ) - > length ( ) ;
}
return - 1 ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , readArrayElement , ( JNIEnv * env , jobject , jobject x , int index ) )
2019-05-01 12:31:29 -07:00
if ( x = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Handle xobj = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( x ) , JVMCI_CHECK_NULL ) ;
if ( xobj - > klass ( ) - > is_array_klass ( ) ) {
arrayOop array = arrayOop ( xobj ( ) ) ;
BasicType element_type = ArrayKlass : : cast ( array - > klass ( ) ) - > element_type ( ) ;
if ( index < 0 | | index > = array - > length ( ) ) {
return NULL ;
}
JVMCIObject result ;
if ( element_type = = T_OBJECT ) {
result = JVMCIENV - > get_object_constant ( objArrayOop ( xobj ( ) ) - > obj_at ( index ) ) ;
if ( result . is_null ( ) ) {
result = JVMCIENV - > get_JavaConstant_NULL_POINTER ( ) ;
}
} else {
jvalue value ;
switch ( element_type ) {
case T_DOUBLE : value . d = typeArrayOop ( xobj ( ) ) - > double_at ( index ) ; break ;
case T_FLOAT : value . f = typeArrayOop ( xobj ( ) ) - > float_at ( index ) ; break ;
case T_LONG : value . j = typeArrayOop ( xobj ( ) ) - > long_at ( index ) ; break ;
case T_INT : value . i = typeArrayOop ( xobj ( ) ) - > int_at ( index ) ; break ;
case T_SHORT : value . s = typeArrayOop ( xobj ( ) ) - > short_at ( index ) ; break ;
case T_CHAR : value . c = typeArrayOop ( xobj ( ) ) - > char_at ( index ) ; break ;
case T_BYTE : value . b = typeArrayOop ( xobj ( ) ) - > byte_at ( index ) ; break ;
case T_BOOLEAN : value . z = typeArrayOop ( xobj ( ) ) - > byte_at ( index ) & 1 ; break ;
default : ShouldNotReachHere ( ) ;
}
result = JVMCIENV - > create_box ( element_type , & value , JVMCI_CHECK_NULL ) ;
}
assert ( ! result . is_null ( ) , " must have a value " ) ;
return JVMCIENV - > get_jobject ( result ) ;
}
return NULL ; ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , arrayBaseOffset , ( JNIEnv * env , jobject , jobject kind ) )
2019-05-01 12:31:29 -07:00
if ( kind = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
2016-09-14 12:34:37 -07:00
}
2019-05-01 12:31:29 -07:00
BasicType type = JVMCIENV - > kindToBasicType ( JVMCIENV - > wrap ( kind ) , JVMCI_CHECK_0 ) ;
return arrayOopDesc : : header_size ( type ) * HeapWordSize ;
2016-09-14 12:34:37 -07:00
C2V_END
2015-10-08 12:49:30 -10:00
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , arrayIndexScale , ( JNIEnv * env , jobject , jobject kind ) )
2019-05-01 12:31:29 -07:00
if ( kind = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
BasicType type = JVMCIENV - > kindToBasicType ( JVMCIENV - > wrap ( kind ) , JVMCI_CHECK_0 ) ;
return type2aelembytes ( type ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jbyte , getByte , ( JNIEnv * env , jobject , jobject x , long displacement ) )
2019-05-01 12:31:29 -07:00
if ( x = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Handle xobj = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( x ) , JVMCI_CHECK_0 ) ;
return xobj - > byte_field ( displacement ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jshort , getShort , ( JNIEnv * env , jobject , jobject x , long displacement ) )
2019-05-01 12:31:29 -07:00
if ( x = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Handle xobj = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( x ) , JVMCI_CHECK_0 ) ;
return xobj - > short_field ( displacement ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jint , getInt , ( JNIEnv * env , jobject , jobject x , long displacement ) )
2019-05-01 12:31:29 -07:00
if ( x = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Handle xobj = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( x ) , JVMCI_CHECK_0 ) ;
return xobj - > int_field ( displacement ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jlong , getLong , ( JNIEnv * env , jobject , jobject x , long displacement ) )
2019-05-01 12:31:29 -07:00
if ( x = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Handle xobj = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( x ) , JVMCI_CHECK_0 ) ;
return xobj - > long_field ( displacement ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , getObject , ( JNIEnv * env , jobject , jobject x , long displacement ) )
2019-05-01 12:31:29 -07:00
if ( x = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Handle xobj = JVMCIENV - > asConstant ( JVMCIENV - > wrap ( x ) , JVMCI_CHECK_0 ) ;
oop res = xobj - > obj_field ( displacement ) ;
JVMCIObject result = JVMCIENV - > get_object_constant ( res ) ;
return JVMCIENV - > get_jobject ( result ) ;
}
C2V_VMENTRY ( void , deleteGlobalHandle , ( JNIEnv * env , jobject , jlong h ) )
jobject handle = ( jobject ) ( address ) h ;
if ( handle ! = NULL ) {
2019-07-18 09:15:26 -07:00
JVMCI : : destroy_global ( handle ) ;
2019-05-01 12:31:29 -07:00
}
}
2019-05-06 20:05:19 -07:00
static void requireJVMCINativeLibrary ( JVMCI_TRAPS ) {
2019-05-01 12:31:29 -07:00
if ( ! UseJVMCINativeLibrary ) {
2019-05-06 20:05:19 -07:00
JVMCI_THROW_MSG ( UnsupportedOperationException , " JVMCI shared library is not enabled (requires -XX:+UseJVMCINativeLibrary) " ) ;
2019-05-01 12:31:29 -07:00
}
2019-05-06 20:05:19 -07:00
}
static JavaVM * requireNativeLibraryJavaVM ( const char * caller , JVMCI_TRAPS ) {
JavaVM * javaVM = JVMCIEnv : : get_shared_library_javavm ( ) ;
if ( javaVM = = NULL ) {
JVMCI_THROW_MSG_NULL ( IllegalStateException , err_msg ( " Require JVMCI shared library to be initialized in %s " , caller ) ) ;
2019-05-01 12:31:29 -07:00
}
2019-05-06 20:05:19 -07:00
return javaVM ;
}
C2V_VMENTRY_NULL ( jlongArray , registerNativeMethods , ( JNIEnv * env , jobject , jclass mirror ) )
requireJVMCINativeLibrary ( JVMCI_CHECK_NULL ) ;
requireInHotSpot ( " registerNativeMethods " , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
void * shared_library = JVMCIEnv : : get_shared_library_handle ( ) ;
if ( shared_library = = NULL ) {
// Ensure the JVMCI shared library runtime is initialized.
2019-05-06 20:05:19 -07:00
JVMCIEnv __peer_jvmci_env__ ( thread , false , __FILE__ , __LINE__ ) ;
2019-05-01 12:31:29 -07:00
JVMCIEnv * peerEnv = & __peer_jvmci_env__ ;
HandleMark hm ;
JVMCIRuntime * runtime = JVMCI : : compiler_runtime ( ) ;
JVMCIObject receiver = runtime - > get_HotSpotJVMCIRuntime ( peerEnv ) ;
if ( peerEnv - > has_pending_exception ( ) ) {
peerEnv - > describe_pending_exception ( true ) ;
}
shared_library = JVMCIEnv : : get_shared_library_handle ( ) ;
2019-05-06 20:05:19 -07:00
if ( shared_library = = NULL ) {
JVMCI_THROW_MSG_0 ( InternalError , " Error initializing JVMCI runtime " ) ;
}
2019-05-01 12:31:29 -07:00
}
if ( mirror = = NULL ) {
JVMCI_THROW_0 ( NullPointerException ) ;
}
Klass * klass = java_lang_Class : : as_Klass ( JNIHandles : : resolve ( mirror ) ) ;
if ( klass = = NULL | | ! klass - > is_instance_klass ( ) ) {
JVMCI_THROW_MSG_0 ( IllegalArgumentException , " clazz is for primitive type " ) ;
}
InstanceKlass * iklass = InstanceKlass : : cast ( klass ) ;
for ( int i = 0 ; i < iklass - > methods ( ) - > length ( ) ; i + + ) {
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , iklass - > methods ( ) - > at ( i ) ) ;
2019-05-01 12:31:29 -07:00
if ( method - > is_native ( ) ) {
// Compute argument size
int args_size = 1 // JNIEnv
+ ( method - > is_static ( ) ? 1 : 0 ) // class for static methods
+ method - > size_of_parameters ( ) ; // actual parameters
// 1) Try JNI short style
stringStream st ;
char * pure_name = NativeLookup : : pure_jni_name ( method ) ;
os : : print_jni_name_prefix_on ( & st , args_size ) ;
st . print_raw ( pure_name ) ;
os : : print_jni_name_suffix_on ( & st , args_size ) ;
char * jni_name = st . as_string ( ) ;
address entry = ( address ) os : : dll_lookup ( shared_library , jni_name ) ;
if ( entry = = NULL ) {
// 2) Try JNI long style
st . reset ( ) ;
char * long_name = NativeLookup : : long_jni_name ( method ) ;
os : : print_jni_name_prefix_on ( & st , args_size ) ;
st . print_raw ( pure_name ) ;
st . print_raw ( long_name ) ;
os : : print_jni_name_suffix_on ( & st , args_size ) ;
2019-05-06 20:05:19 -07:00
char * jni_long_name = st . as_string ( ) ;
entry = ( address ) os : : dll_lookup ( shared_library , jni_long_name ) ;
if ( entry = = NULL ) {
JVMCI_THROW_MSG_0 ( UnsatisfiedLinkError , err_msg ( " %s [neither %s nor %s exist in %s] " ,
method - > name_and_sig_as_C_string ( ) ,
jni_name , jni_long_name , JVMCIEnv : : get_shared_library_path ( ) ) ) ;
}
2019-05-01 12:31:29 -07:00
}
2019-05-06 20:05:19 -07:00
2019-05-01 12:31:29 -07:00
if ( method - > has_native_function ( ) & & entry ! = method - > native_function ( ) ) {
2019-05-06 20:05:19 -07:00
JVMCI_THROW_MSG_0 ( UnsatisfiedLinkError , err_msg ( " %s [cannot re-link from " PTR_FORMAT " to " PTR_FORMAT " ] " ,
method - > name_and_sig_as_C_string ( ) , p2i ( method - > native_function ( ) ) , p2i ( entry ) ) ) ;
2019-05-01 12:31:29 -07:00
}
method - > set_native_function ( entry , Method : : native_bind_event_is_interesting ) ;
2019-11-11 12:11:34 -05:00
log_debug ( jni , resolve ) ( " [Dynamic-linking native method %s.%s ... JNI] " ,
method - > method_holder ( ) - > external_name ( ) ,
method - > name ( ) - > as_C_string ( ) ) ;
2019-05-01 12:31:29 -07:00
}
}
JavaVM * javaVM = JVMCIEnv : : get_shared_library_javavm ( ) ;
JVMCIPrimitiveArray result = JVMCIENV - > new_longArray ( 4 , JVMCI_CHECK_NULL ) ;
JVMCIENV - > put_long_at ( result , 0 , ( jlong ) ( address ) javaVM ) ;
JVMCIENV - > put_long_at ( result , 1 , ( jlong ) ( address ) javaVM - > functions - > reserved0 ) ;
JVMCIENV - > put_long_at ( result , 2 , ( jlong ) ( address ) javaVM - > functions - > reserved1 ) ;
JVMCIENV - > put_long_at ( result , 3 , ( jlong ) ( address ) javaVM - > functions - > reserved2 ) ;
return ( jlongArray ) JVMCIENV - > get_jobject ( result ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_PREFIX ( jboolean , isCurrentThreadAttached , ( JNIEnv * env , jobject c2vm ) )
if ( base_thread = = NULL ) {
// Called from unattached JVMCI shared library thread
return false ;
}
JVMCITraceMark jtm ( " isCurrentThreadAttached " ) ;
assert ( base_thread - > is_Java_thread ( ) , " just checking " ) ;
JavaThread * thread = ( JavaThread * ) base_thread ;
if ( thread - > jni_environment ( ) = = env ) {
C2V_BLOCK ( jboolean , isCurrentThreadAttached , ( JNIEnv * env , jobject ) )
requireJVMCINativeLibrary ( JVMCI_CHECK_0 ) ;
JavaVM * javaVM = requireNativeLibraryJavaVM ( " isCurrentThreadAttached " , JVMCI_CHECK_0 ) ;
JNIEnv * peerEnv ;
return javaVM - > GetEnv ( ( void * * ) & peerEnv , JNI_VERSION_1_2 ) = = JNI_OK ;
}
return true ;
C2V_END
2019-10-24 16:58:39 -07:00
C2V_VMENTRY_PREFIX ( jlong , getCurrentJavaThread , ( JNIEnv * env , jobject c2vm ) )
if ( base_thread = = NULL ) {
// Called from unattached JVMCI shared library thread
return 0L ;
}
JVMCITraceMark jtm ( " getCurrentJavaThread " ) ;
assert ( base_thread - > is_Java_thread ( ) , " just checking " ) ;
return ( jlong ) p2i ( base_thread ) ;
C2V_END
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_PREFIX ( jboolean , attachCurrentThread , ( JNIEnv * env , jobject c2vm , jboolean as_daemon ) )
if ( base_thread = = NULL ) {
// Called from unattached JVMCI shared library thread
extern struct JavaVM_ main_vm ;
JNIEnv * hotspotEnv ;
jint res = as_daemon ? main_vm . AttachCurrentThreadAsDaemon ( ( void * * ) & hotspotEnv , NULL ) :
main_vm . AttachCurrentThread ( ( void * * ) & hotspotEnv , NULL ) ;
if ( res ! = JNI_OK ) {
JNI_THROW_ ( " attachCurrentThread " , InternalError , err_msg ( " Trying to attach thread returned %d " , res ) , false ) ;
}
return true ;
}
JVMCITraceMark jtm ( " attachCurrentThread " ) ;
assert ( base_thread - > is_Java_thread ( ) , " just checking " ) ; \
JavaThread * thread = ( JavaThread * ) base_thread ;
if ( thread - > jni_environment ( ) = = env ) {
// Called from HotSpot
C2V_BLOCK ( jboolean , attachCurrentThread , ( JNIEnv * env , jobject , jboolean ) )
requireJVMCINativeLibrary ( JVMCI_CHECK_0 ) ;
JavaVM * javaVM = requireNativeLibraryJavaVM ( " attachCurrentThread " , JVMCI_CHECK_0 ) ;
JavaVMAttachArgs attach_args ;
attach_args . version = JNI_VERSION_1_2 ;
attach_args . name = thread - > name ( ) ;
attach_args . group = NULL ;
JNIEnv * peerEnv ;
if ( javaVM - > GetEnv ( ( void * * ) & peerEnv , JNI_VERSION_1_2 ) = = JNI_OK ) {
return false ;
}
jint res = as_daemon ? javaVM - > AttachCurrentThreadAsDaemon ( ( void * * ) & peerEnv , & attach_args ) :
javaVM - > AttachCurrentThread ( ( void * * ) & peerEnv , & attach_args ) ;
if ( res = = JNI_OK ) {
guarantee ( peerEnv ! = NULL , " must be " ) ;
return true ;
}
JVMCI_THROW_MSG_0 ( InternalError , err_msg ( " Error %d while attaching %s " , res , attach_args . name ) ) ;
}
// Called from JVMCI shared library
return false ;
C2V_END
C2V_VMENTRY_PREFIX ( void , detachCurrentThread , ( JNIEnv * env , jobject c2vm ) )
if ( base_thread = = NULL ) {
// Called from unattached JVMCI shared library thread
JNI_THROW ( " detachCurrentThread " , IllegalStateException , err_msg ( " Cannot detach non-attached thread " ) ) ;
}
JVMCITraceMark jtm ( " detachCurrentThread " ) ;
assert ( base_thread - > is_Java_thread ( ) , " just checking " ) ; \
JavaThread * thread = ( JavaThread * ) base_thread ;
if ( thread - > jni_environment ( ) = = env ) {
// Called from HotSpot
C2V_BLOCK ( void , detachCurrentThread , ( JNIEnv * env , jobject ) )
requireJVMCINativeLibrary ( JVMCI_CHECK ) ;
requireInHotSpot ( " detachCurrentThread " , JVMCI_CHECK ) ;
JavaVM * javaVM = requireNativeLibraryJavaVM ( " detachCurrentThread " , JVMCI_CHECK ) ;
JNIEnv * peerEnv ;
if ( javaVM - > GetEnv ( ( void * * ) & peerEnv , JNI_VERSION_1_2 ) ! = JNI_OK ) {
JVMCI_THROW_MSG ( IllegalStateException , err_msg ( " Cannot detach non-attached thread: %s " , thread - > name ( ) ) ) ;
}
jint res = javaVM - > DetachCurrentThread ( ) ;
if ( res ! = JNI_OK ) {
JVMCI_THROW_MSG ( InternalError , err_msg ( " Error %d while attaching %s " , res , thread - > name ( ) ) ) ;
}
} else {
// Called from attached JVMCI shared library thread
extern struct JavaVM_ main_vm ;
jint res = main_vm . DetachCurrentThread ( ) ;
if ( res ! = JNI_OK ) {
JNI_THROW ( " detachCurrentThread " , InternalError , err_msg ( " Cannot detach non-attached thread " ) ) ;
}
}
C2V_END
C2V_VMENTRY_0 ( jlong , translate , ( JNIEnv * env , jobject , jobject obj_handle ) )
requireJVMCINativeLibrary ( JVMCI_CHECK_0 ) ;
2019-05-01 12:31:29 -07:00
if ( obj_handle = = NULL ) {
return 0L ;
}
2019-05-06 20:05:19 -07:00
JVMCIEnv __peer_jvmci_env__ ( thread , ! JVMCIENV - > is_hotspot ( ) , __FILE__ , __LINE__ ) ;
2019-05-01 12:31:29 -07:00
JVMCIEnv * peerEnv = & __peer_jvmci_env__ ;
JVMCIEnv * thisEnv = JVMCIENV ;
JVMCIObject obj = thisEnv - > wrap ( obj_handle ) ;
JVMCIObject result ;
if ( thisEnv - > isa_HotSpotResolvedJavaMethodImpl ( obj ) ) {
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , thisEnv - > asMethod ( obj ) ) ;
2019-05-01 12:31:29 -07:00
result = peerEnv - > get_jvmci_method ( method , JVMCI_CHECK_0 ) ;
} else if ( thisEnv - > isa_HotSpotResolvedObjectTypeImpl ( obj ) ) {
Klass * klass = thisEnv - > asKlass ( obj ) ;
JVMCIKlassHandle klass_handle ( THREAD ) ;
klass_handle = klass ;
result = peerEnv - > get_jvmci_type ( klass_handle , JVMCI_CHECK_0 ) ;
} else if ( thisEnv - > isa_HotSpotResolvedPrimitiveType ( obj ) ) {
BasicType type = JVMCIENV - > kindToBasicType ( JVMCIENV - > get_HotSpotResolvedPrimitiveType_kind ( obj ) , JVMCI_CHECK_0 ) ;
result = peerEnv - > get_jvmci_primitive_type ( type ) ;
} else if ( thisEnv - > isa_IndirectHotSpotObjectConstantImpl ( obj ) | |
thisEnv - > isa_DirectHotSpotObjectConstantImpl ( obj ) ) {
Handle constant = thisEnv - > asConstant ( obj , JVMCI_CHECK_0 ) ;
result = peerEnv - > get_object_constant ( constant ( ) ) ;
} else if ( thisEnv - > isa_HotSpotNmethod ( obj ) ) {
nmethod * nm = thisEnv - > asNmethod ( obj ) ;
if ( nm ! = NULL ) {
JVMCINMethodData * data = nm - > jvmci_nmethod_data ( ) ;
if ( data ! = NULL ) {
if ( peerEnv - > is_hotspot ( ) ) {
// Only the mirror in the HotSpot heap is accessible
// through JVMCINMethodData
2019-06-20 10:32:25 -07:00
oop nmethod_mirror = data - > get_nmethod_mirror ( nm , /* phantom_ref */ true ) ;
2019-05-01 12:31:29 -07:00
if ( nmethod_mirror ! = NULL ) {
result = HotSpotJVMCI : : wrap ( nmethod_mirror ) ;
}
}
}
}
if ( result . is_null ( ) ) {
JVMCIObject methodObject = thisEnv - > get_HotSpotNmethod_method ( obj ) ;
2019-11-13 08:23:23 -05:00
methodHandle mh ( THREAD , thisEnv - > asMethod ( methodObject ) ) ;
2019-05-01 12:31:29 -07:00
jboolean isDefault = thisEnv - > get_HotSpotNmethod_isDefault ( obj ) ;
jlong compileIdSnapshot = thisEnv - > get_HotSpotNmethod_compileIdSnapshot ( obj ) ;
JVMCIObject name_string = thisEnv - > get_InstalledCode_name ( obj ) ;
const char * cstring = name_string . is_null ( ) ? NULL : thisEnv - > as_utf8_string ( name_string ) ;
// Create a new HotSpotNmethod instance in the peer runtime
2019-11-13 08:23:23 -05:00
result = peerEnv - > new_HotSpotNmethod ( mh , cstring , isDefault , compileIdSnapshot , JVMCI_CHECK_0 ) ;
2019-05-01 12:31:29 -07:00
if ( nm = = NULL ) {
// nmethod must have been unloaded
} else {
// Link the new HotSpotNmethod to the nmethod
peerEnv - > initialize_installed_code ( result , nm , JVMCI_CHECK_0 ) ;
// Only HotSpotNmethod instances in the HotSpot heap are tracked directly by the runtime.
if ( peerEnv - > is_hotspot ( ) ) {
JVMCINMethodData * data = nm - > jvmci_nmethod_data ( ) ;
if ( data = = NULL ) {
JVMCI_THROW_MSG_0 ( IllegalArgumentException , " Cannot set HotSpotNmethod mirror for default nmethod " ) ;
}
2019-06-20 10:32:25 -07:00
if ( data - > get_nmethod_mirror ( nm , /* phantom_ref */ false ) ! = NULL ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_0 ( IllegalArgumentException , " Cannot overwrite existing HotSpotNmethod mirror for nmethod " ) ;
}
oop nmethod_mirror = HotSpotJVMCI : : resolve ( result ) ;
data - > set_nmethod_mirror ( nm , nmethod_mirror ) ;
}
}
}
} else {
JVMCI_THROW_MSG_0 ( IllegalArgumentException ,
err_msg ( " Cannot translate object of type: %s " , thisEnv - > klass_name ( obj ) ) ) ;
}
return ( jlong ) peerEnv - > make_global ( result ) . as_jobject ( ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , unhand , ( JNIEnv * env , jobject , jlong obj_handle ) )
requireJVMCINativeLibrary ( JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
if ( obj_handle = = 0L ) {
return NULL ;
}
jobject global_handle = ( jobject ) obj_handle ;
JVMCIObject global_handle_obj = JVMCIENV - > wrap ( ( jobject ) obj_handle ) ;
jobject result = JVMCIENV - > make_local ( global_handle_obj ) . as_jobject ( ) ;
JVMCIENV - > destroy_global ( global_handle_obj ) ;
return result ;
}
C2V_VMENTRY ( void , updateHotSpotNmethod , ( JNIEnv * env , jobject , jobject code_handle ) )
JVMCIObject code = JVMCIENV - > wrap ( code_handle ) ;
// Execute this operation for the side effect of updating the InstalledCode state
JVMCIENV - > asNmethod ( code ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jbyteArray , getCode , ( JNIEnv * env , jobject , jobject code_handle ) )
2019-05-01 12:31:29 -07:00
JVMCIObject code = JVMCIENV - > wrap ( code_handle ) ;
CodeBlob * cb = JVMCIENV - > asCodeBlob ( code ) ;
if ( cb = = NULL ) {
return NULL ;
}
int code_size = cb - > code_size ( ) ;
JVMCIPrimitiveArray result = JVMCIENV - > new_byteArray ( code_size , JVMCI_CHECK_NULL ) ;
JVMCIENV - > copy_bytes_from ( ( jbyte * ) cb - > code_begin ( ) , result , 0 , code_size ) ;
return JVMCIENV - > get_jbyteArray ( result ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , asReflectionExecutable , ( JNIEnv * env , jobject , jobject jvmci_method ) )
requireInHotSpot ( " asReflectionExecutable " , JVMCI_CHECK_NULL ) ;
2019-11-13 08:23:23 -05:00
methodHandle m ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2018-11-21 22:02:17 +01:00
oop executable ;
if ( m - > is_initializer ( ) ) {
if ( m - > is_static_initializer ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_NULL ( IllegalArgumentException ,
" Cannot create java.lang.reflect.Method for class initializer " ) ;
2018-11-21 22:02:17 +01:00
}
executable = Reflection : : new_constructor ( m , CHECK_NULL ) ;
} else {
executable = Reflection : : new_method ( m , false , CHECK_NULL ) ;
}
2019-05-01 12:31:29 -07:00
return JNIHandles : : make_local ( THREAD , executable ) ;
2018-11-21 22:02:17 +01:00
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobject , asReflectionField , ( JNIEnv * env , jobject , jobject jvmci_type , jint index ) )
requireInHotSpot ( " asReflectionField " , JVMCI_CHECK_NULL ) ;
2019-05-01 12:31:29 -07:00
Klass * klass = JVMCIENV - > asKlass ( jvmci_type ) ;
2018-11-21 22:02:17 +01:00
if ( ! klass - > is_instance_klass ( ) ) {
2019-05-01 12:31:29 -07:00
JVMCI_THROW_MSG_NULL ( IllegalArgumentException ,
2018-11-21 22:02:17 +01:00
err_msg ( " Expected non-primitive type, got %s " , klass - > external_name ( ) ) ) ;
}
InstanceKlass * iklass = InstanceKlass : : cast ( klass ) ;
Array < u2 > * fields = iklass - > fields ( ) ;
2019-05-01 12:31:29 -07:00
if ( index < 0 | | index > fields - > length ( ) ) {
JVMCI_THROW_MSG_NULL ( IllegalArgumentException ,
2018-11-21 22:02:17 +01:00
err_msg ( " Field index %d out of bounds for %s " , index , klass - > external_name ( ) ) ) ;
}
fieldDescriptor fd ( iklass , index ) ;
oop reflected = Reflection : : new_field ( & fd , CHECK_NULL ) ;
return JNIHandles : : make_local ( env , reflected ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_NULL ( jobjectArray , getFailedSpeculations , ( JNIEnv * env , jobject , jlong failed_speculations_address , jobjectArray current ) )
2019-05-01 12:31:29 -07:00
FailedSpeculation * head = * ( ( FailedSpeculation * * ) ( address ) failed_speculations_address ) ;
int result_length = 0 ;
for ( FailedSpeculation * fs = head ; fs ! = NULL ; fs = fs - > next ( ) ) {
result_length + + ;
}
int current_length = 0 ;
JVMCIObjectArray current_array = NULL ;
if ( current ! = NULL ) {
current_array = JVMCIENV - > wrap ( current ) ;
current_length = JVMCIENV - > get_length ( current_array ) ;
if ( current_length = = result_length ) {
// No new failures
return current ;
}
}
JVMCIObjectArray result = JVMCIENV - > new_byte_array_array ( result_length , JVMCI_CHECK_NULL ) ;
int result_index = 0 ;
for ( FailedSpeculation * fs = head ; result_index < result_length ; fs = fs - > next ( ) ) {
assert ( fs ! = NULL , " npe " ) ;
JVMCIPrimitiveArray entry ;
if ( result_index < current_length ) {
entry = ( JVMCIPrimitiveArray ) JVMCIENV - > get_object_at ( current_array , result_index ) ;
} else {
entry = JVMCIENV - > new_byteArray ( fs - > data_len ( ) , JVMCI_CHECK_NULL ) ;
JVMCIENV - > copy_bytes_from ( ( jbyte * ) fs - > data ( ) , entry , 0 , fs - > data_len ( ) ) ;
}
JVMCIENV - > put_object_at ( result , result_index + + , entry ) ;
}
return JVMCIENV - > get_jobjectArray ( result ) ;
}
2019-05-06 20:05:19 -07:00
C2V_VMENTRY_0 ( jlong , getFailedSpeculationsAddress , ( JNIEnv * env , jobject , jobject jvmci_method ) )
2019-11-13 08:23:23 -05:00
methodHandle method ( THREAD , JVMCIENV - > asMethod ( jvmci_method ) ) ;
2019-05-01 12:31:29 -07:00
MethodData * method_data = method - > method_data ( ) ;
if ( method_data = = NULL ) {
ClassLoaderData * loader_data = method - > method_holder ( ) - > class_loader_data ( ) ;
method_data = MethodData : : allocate ( loader_data , method , CHECK_0 ) ;
method - > set_method_data ( method_data ) ;
}
return ( jlong ) method_data - > get_failed_speculations_address ( ) ;
}
C2V_VMENTRY ( void , releaseFailedSpeculations , ( JNIEnv * env , jobject , jlong failed_speculations_address ) )
FailedSpeculation : : free_failed_speculations ( ( FailedSpeculation * * ) ( address ) failed_speculations_address ) ;
}
2019-06-04 12:44:53 -07:00
C2V_VMENTRY_0 ( jboolean , addFailedSpeculation , ( JNIEnv * env , jobject , jlong failed_speculations_address , jbyteArray speculation_obj ) )
2019-05-01 12:31:29 -07:00
JVMCIPrimitiveArray speculation_handle = JVMCIENV - > wrap ( speculation_obj ) ;
int speculation_len = JVMCIENV - > get_length ( speculation_handle ) ;
char * speculation = NEW_RESOURCE_ARRAY ( char , speculation_len ) ;
JVMCIENV - > copy_bytes_to ( speculation_handle , ( jbyte * ) speculation , 0 , speculation_len ) ;
return FailedSpeculation : : add_failed_speculation ( NULL , ( FailedSpeculation * * ) ( address ) failed_speculations_address , ( address ) speculation , speculation_len ) ;
}
2019-06-21 16:21:13 -07:00
C2V_VMENTRY ( void , callSystemExit , ( JNIEnv * env , jobject , jint status ) )
JavaValue result ( T_VOID ) ;
JavaCallArguments jargs ( 1 ) ;
jargs . push_int ( status ) ;
JavaCalls : : call_static ( & result ,
SystemDictionary : : System_klass ( ) ,
vmSymbols : : exit_method_name ( ) ,
vmSymbols : : int_void_signature ( ) ,
& jargs ,
CHECK ) ;
}
2015-10-08 12:49:30 -10:00
# define CC (char*) /*cast a literal from (const char*)*/
# define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
2018-03-07 19:32:54 -08:00
# define STRING "Ljava / lang / String;"
# define OBJECT "Ljava / lang / Object;"
# define CLASS "Ljava / lang / Class;"
2019-05-01 12:31:29 -07:00
# define OBJECTCONSTANT "Ljdk / vm / ci / hotspot / HotSpotObjectConstantImpl;"
# define HANDLECONSTANT "Ljdk / vm / ci / hotspot / IndirectHotSpotObjectConstantImpl;"
2018-03-07 19:32:54 -08:00
# define EXECUTABLE "Ljava / lang / reflect / Executable;"
# define STACK_TRACE_ELEMENT "Ljava / lang / StackTraceElement;"
# define INSTALLED_CODE "Ljdk / vm / ci / code / InstalledCode;"
# define TARGET_DESCRIPTION "Ljdk / vm / ci / code / TargetDescription;"
# define BYTECODE_FRAME "Ljdk / vm / ci / code / BytecodeFrame;"
2019-05-01 12:31:29 -07:00
# define JAVACONSTANT "Ljdk / vm / ci / meta / JavaConstant;"
2018-03-07 19:32:54 -08:00
# define INSPECTED_FRAME_VISITOR "Ljdk / vm / ci / code / stack / InspectedFrameVisitor;"
# define RESOLVED_METHOD "Ljdk / vm / ci / meta / ResolvedJavaMethod;"
# define HS_RESOLVED_METHOD "Ljdk / vm / ci / hotspot / HotSpotResolvedJavaMethodImpl;"
# define HS_RESOLVED_KLASS "Ljdk / vm / ci / hotspot / HotSpotResolvedObjectTypeImpl;"
2019-05-01 12:31:29 -07:00
# define HS_RESOLVED_TYPE "Ljdk / vm / ci / hotspot / HotSpotResolvedJavaType;"
# define HS_RESOLVED_FIELD "Ljdk / vm / ci / hotspot / HotSpotResolvedJavaField;"
# define HS_INSTALLED_CODE "Ljdk / vm / ci / hotspot / HotSpotInstalledCode;"
# define HS_NMETHOD "Ljdk / vm / ci / hotspot / HotSpotNmethod;"
2018-03-07 19:32:54 -08:00
# define HS_CONSTANT_POOL "Ljdk / vm / ci / hotspot / HotSpotConstantPool;"
# define HS_COMPILED_CODE "Ljdk / vm / ci / hotspot / HotSpotCompiledCode;"
# define HS_CONFIG "Ljdk / vm / ci / hotspot / HotSpotVMConfig;"
# define HS_METADATA "Ljdk / vm / ci / hotspot / HotSpotMetaData;"
# define HS_STACK_FRAME_REF "Ljdk / vm / ci / hotspot / HotSpotStackFrameReference;"
# define HS_SPECULATION_LOG "Ljdk / vm / ci / hotspot / HotSpotSpeculationLog;"
2019-05-01 12:31:29 -07:00
# define METASPACE_OBJECT "Ljdk / vm / ci / hotspot / MetaspaceObject;"
2018-11-21 22:02:17 +01:00
# define REFLECTION_EXECUTABLE "Ljava / lang / reflect / Executable;"
# define REFLECTION_FIELD "Ljava / lang / reflect / Field;"
2018-03-07 19:32:54 -08:00
# define METASPACE_METHOD_DATA "J"
2015-10-08 12:49:30 -10:00
JNINativeMethod CompilerToVM : : methods [ ] = {
2016-04-01 01:34:00 -07:00
{ CC " getBytecode " , CC " ( " HS_RESOLVED_METHOD " )[B " , FN_PTR ( getBytecode ) } ,
{ CC " getExceptionTableStart " , CC " ( " HS_RESOLVED_METHOD " )J " , FN_PTR ( getExceptionTableStart ) } ,
{ CC " getExceptionTableLength " , CC " ( " HS_RESOLVED_METHOD " )I " , FN_PTR ( getExceptionTableLength ) } ,
{ CC " findUniqueConcreteMethod " , CC " ( " HS_RESOLVED_KLASS HS_RESOLVED_METHOD " ) " HS_RESOLVED_METHOD , FN_PTR ( findUniqueConcreteMethod ) } ,
{ CC " getImplementor " , CC " ( " HS_RESOLVED_KLASS " ) " HS_RESOLVED_KLASS , FN_PTR ( getImplementor ) } ,
{ CC " getStackTraceElement " , CC " ( " HS_RESOLVED_METHOD " I) " STACK_TRACE_ELEMENT , FN_PTR ( getStackTraceElement ) } ,
{ CC " methodIsIgnoredBySecurityStackWalk " , CC " ( " HS_RESOLVED_METHOD " )Z " , FN_PTR ( methodIsIgnoredBySecurityStackWalk ) } ,
2017-11-06 12:17:59 +01:00
{ CC " setNotInlinableOrCompilable " , CC " ( " HS_RESOLVED_METHOD " )V " , FN_PTR ( setNotInlinableOrCompilable ) } ,
2017-01-22 21:40:59 +01:00
{ CC " isCompilable " , CC " ( " HS_RESOLVED_METHOD " )Z " , FN_PTR ( isCompilable ) } ,
{ CC " hasNeverInlineDirective " , CC " ( " HS_RESOLVED_METHOD " )Z " , FN_PTR ( hasNeverInlineDirective ) } ,
2016-04-01 01:34:00 -07:00
{ CC " shouldInlineMethod " , CC " ( " HS_RESOLVED_METHOD " )Z " , FN_PTR ( shouldInlineMethod ) } ,
2019-05-01 12:31:29 -07:00
{ CC " lookupType " , CC " ( " STRING HS_RESOLVED_KLASS " Z) " HS_RESOLVED_TYPE , FN_PTR ( lookupType ) } ,
2019-06-21 16:21:13 -07:00
{ CC " getArrayType " , CC " ( " HS_RESOLVED_TYPE " ) " HS_RESOLVED_KLASS , FN_PTR ( getArrayType ) } ,
2019-05-01 12:31:29 -07:00
{ CC " lookupClass " , CC " ( " CLASS " ) " HS_RESOLVED_TYPE , FN_PTR ( lookupClass ) } ,
2016-04-01 01:34:00 -07:00
{ CC " lookupNameInPool " , CC " ( " HS_CONSTANT_POOL " I) " STRING , FN_PTR ( lookupNameInPool ) } ,
{ CC " lookupNameAndTypeRefIndexInPool " , CC " ( " HS_CONSTANT_POOL " I)I " , FN_PTR ( lookupNameAndTypeRefIndexInPool ) } ,
{ CC " lookupSignatureInPool " , CC " ( " HS_CONSTANT_POOL " I) " STRING , FN_PTR ( lookupSignatureInPool ) } ,
{ CC " lookupKlassRefIndexInPool " , CC " ( " HS_CONSTANT_POOL " I)I " , FN_PTR ( lookupKlassRefIndexInPool ) } ,
{ CC " lookupKlassInPool " , CC " ( " HS_CONSTANT_POOL " I)Ljava/lang/Object; " , FN_PTR ( lookupKlassInPool ) } ,
2019-05-01 12:31:29 -07:00
{ CC " lookupAppendixInPool " , CC " ( " HS_CONSTANT_POOL " I) " OBJECTCONSTANT , FN_PTR ( lookupAppendixInPool ) } ,
2016-04-01 01:34:00 -07:00
{ CC " lookupMethodInPool " , CC " ( " HS_CONSTANT_POOL " IB) " HS_RESOLVED_METHOD , FN_PTR ( lookupMethodInPool ) } ,
{ CC " constantPoolRemapInstructionOperandFromCache " , CC " ( " HS_CONSTANT_POOL " I)I " , FN_PTR ( constantPoolRemapInstructionOperandFromCache ) } ,
2019-05-01 12:31:29 -07:00
{ CC " resolvePossiblyCachedConstantInPool " , CC " ( " HS_CONSTANT_POOL " I) " OBJECTCONSTANT , FN_PTR ( resolvePossiblyCachedConstantInPool ) } ,
2016-04-01 01:34:00 -07:00
{ CC " resolveTypeInPool " , CC " ( " HS_CONSTANT_POOL " I) " HS_RESOLVED_KLASS , FN_PTR ( resolveTypeInPool ) } ,
2017-02-06 10:45:11 +01:00
{ CC " resolveFieldInPool " , CC " ( " HS_CONSTANT_POOL " I " HS_RESOLVED_METHOD " B[I) " HS_RESOLVED_KLASS , FN_PTR ( resolveFieldInPool ) } ,
2016-04-01 01:34:00 -07:00
{ CC " resolveInvokeDynamicInPool " , CC " ( " HS_CONSTANT_POOL " I)V " , FN_PTR ( resolveInvokeDynamicInPool ) } ,
{ CC " resolveInvokeHandleInPool " , CC " ( " HS_CONSTANT_POOL " I)V " , FN_PTR ( resolveInvokeHandleInPool ) } ,
2017-10-19 19:23:48 -07:00
{ CC " isResolvedInvokeHandleInPool " , CC " ( " HS_CONSTANT_POOL " I)I " , FN_PTR ( isResolvedInvokeHandleInPool ) } ,
2016-04-01 01:34:00 -07:00
{ CC " resolveMethod " , CC " ( " HS_RESOLVED_KLASS HS_RESOLVED_METHOD HS_RESOLVED_KLASS " ) " HS_RESOLVED_METHOD , FN_PTR ( resolveMethod ) } ,
2016-08-23 15:16:45 +00:00
{ CC " getSignaturePolymorphicHolders " , CC " ()[ " STRING , FN_PTR ( getSignaturePolymorphicHolders ) } ,
2016-04-01 01:34:00 -07:00
{ CC " getVtableIndexForInterfaceMethod " , CC " ( " HS_RESOLVED_KLASS HS_RESOLVED_METHOD " )I " , FN_PTR ( getVtableIndexForInterfaceMethod ) } ,
{ CC " getClassInitializer " , CC " ( " HS_RESOLVED_KLASS " ) " HS_RESOLVED_METHOD , FN_PTR ( getClassInitializer ) } ,
{ CC " hasFinalizableSubclass " , CC " ( " HS_RESOLVED_KLASS " )Z " , FN_PTR ( hasFinalizableSubclass ) } ,
{ CC " getMaxCallTargetOffset " , CC " (J)J " , FN_PTR ( getMaxCallTargetOffset ) } ,
2016-09-14 12:34:37 -07:00
{ CC " asResolvedJavaMethod " , CC " ( " EXECUTABLE " ) " HS_RESOLVED_METHOD , FN_PTR ( asResolvedJavaMethod ) } ,
2019-05-01 12:31:29 -07:00
{ CC " getResolvedJavaMethod " , CC " ( " OBJECTCONSTANT " J) " HS_RESOLVED_METHOD , FN_PTR ( getResolvedJavaMethod ) } ,
{ CC " getConstantPool " , CC " ( " METASPACE_OBJECT " ) " HS_CONSTANT_POOL , FN_PTR ( getConstantPool ) } ,
{ CC " getResolvedJavaType0 " , CC " (Ljava/lang/Object;JZ) " HS_RESOLVED_KLASS , FN_PTR ( getResolvedJavaType0 ) } ,
2016-06-16 16:41:50 +00:00
{ CC " readConfiguration " , CC " ()[ " OBJECT , FN_PTR ( readConfiguration ) } ,
2019-05-01 12:31:29 -07:00
{ CC " installCode " , CC " ( " TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE " J[B)I " , FN_PTR ( installCode ) } ,
2016-04-01 01:34:00 -07:00
{ CC " getMetadata " , CC " ( " TARGET_DESCRIPTION HS_COMPILED_CODE HS_METADATA " )I " , FN_PTR ( getMetadata ) } ,
{ CC " resetCompilationStatistics " , CC " ()V " , FN_PTR ( resetCompilationStatistics ) } ,
{ CC " disassembleCodeBlob " , CC " ( " INSTALLED_CODE " ) " STRING , FN_PTR ( disassembleCodeBlob ) } ,
2019-05-01 12:31:29 -07:00
{ CC " executeHotSpotNmethod " , CC " ([ " OBJECT HS_NMETHOD " ) " OBJECT , FN_PTR ( executeHotSpotNmethod ) } ,
2016-04-01 01:34:00 -07:00
{ CC " getLineNumberTable " , CC " ( " HS_RESOLVED_METHOD " )[J " , FN_PTR ( getLineNumberTable ) } ,
{ CC " getLocalVariableTableStart " , CC " ( " HS_RESOLVED_METHOD " )J " , FN_PTR ( getLocalVariableTableStart ) } ,
{ CC " getLocalVariableTableLength " , CC " ( " HS_RESOLVED_METHOD " )I " , FN_PTR ( getLocalVariableTableLength ) } ,
{ CC " reprofile " , CC " ( " HS_RESOLVED_METHOD " )V " , FN_PTR ( reprofile ) } ,
2019-05-01 12:31:29 -07:00
{ CC " invalidateHotSpotNmethod " , CC " ( " HS_NMETHOD " )V " , FN_PTR ( invalidateHotSpotNmethod ) } ,
{ CC " readUncompressedOop " , CC " (J) " OBJECTCONSTANT , FN_PTR ( readUncompressedOop ) } ,
2016-04-01 01:34:00 -07:00
{ CC " collectCounters " , CC " ()[J " , FN_PTR ( collectCounters ) } ,
2019-06-04 12:44:53 -07:00
{ CC " getCountersSize " , CC " ()I " , FN_PTR ( getCountersSize ) } ,
2019-09-24 03:28:42 -04:00
{ CC " setCountersSize " , CC " (I)V " , FN_PTR ( setCountersSize ) } ,
2016-04-01 01:34:00 -07:00
{ CC " allocateCompileId " , CC " ( " HS_RESOLVED_METHOD " I)I " , FN_PTR ( allocateCompileId ) } ,
{ CC " isMature " , CC " ( " METASPACE_METHOD_DATA " )Z " , FN_PTR ( isMature ) } ,
{ CC " hasCompiledCodeForOSR " , CC " ( " HS_RESOLVED_METHOD " II)Z " , FN_PTR ( hasCompiledCodeForOSR ) } ,
{ CC " getSymbol " , CC " (J) " STRING , FN_PTR ( getSymbol ) } ,
2018-03-07 19:32:54 -08:00
{ CC " iterateFrames " , CC " ([ " RESOLVED_METHOD " [ " RESOLVED_METHOD " I " INSPECTED_FRAME_VISITOR " ) " OBJECT , FN_PTR ( iterateFrames ) } ,
2016-04-01 01:34:00 -07:00
{ CC " materializeVirtualObjects " , CC " ( " HS_STACK_FRAME_REF " Z)V " , FN_PTR ( materializeVirtualObjects ) } ,
{ CC " shouldDebugNonSafepoints " , CC " ()Z " , FN_PTR ( shouldDebugNonSafepoints ) } ,
2019-05-06 20:05:19 -07:00
{ CC " writeDebugOutput " , CC " ([BIIZZ)I " , FN_PTR ( writeDebugOutput ) } ,
2016-04-01 01:34:00 -07:00
{ CC " flushDebugOutput " , CC " ()V " , FN_PTR ( flushDebugOutput ) } ,
{ CC " methodDataProfileDataSize " , CC " (JI)I " , FN_PTR ( methodDataProfileDataSize ) } ,
2016-12-11 19:07:04 -08:00
{ CC " getFingerprint " , CC " (J)J " , FN_PTR ( getFingerprint ) } ,
2017-06-16 12:18:46 -07:00
{ CC " getHostClass " , CC " ( " HS_RESOLVED_KLASS " ) " HS_RESOLVED_KLASS , FN_PTR ( getHostClass ) } ,
2016-04-01 01:34:00 -07:00
{ CC " interpreterFrameSize " , CC " ( " BYTECODE_FRAME " )I " , FN_PTR ( interpreterFrameSize ) } ,
2019-05-01 12:31:29 -07:00
{ CC " compileToBytecode " , CC " ( " OBJECTCONSTANT " )V " , FN_PTR ( compileToBytecode ) } ,
2017-02-06 10:45:11 +01:00
{ CC " getFlagValue " , CC " ( " STRING " ) " OBJECT , FN_PTR ( getFlagValue ) } ,
2019-05-01 12:31:29 -07:00
{ CC " getObjectAtAddress " , CC " (J) " OBJECT , FN_PTR ( getObjectAtAddress ) } ,
{ CC " getInterfaces " , CC " ( " HS_RESOLVED_KLASS " )[ " HS_RESOLVED_KLASS , FN_PTR ( getInterfaces ) } ,
{ CC " getComponentType " , CC " ( " HS_RESOLVED_KLASS " ) " HS_RESOLVED_TYPE , FN_PTR ( getComponentType ) } ,
{ CC " ensureInitialized " , CC " ( " HS_RESOLVED_KLASS " )V " , FN_PTR ( ensureInitialized ) } ,
{ CC " getIdentityHashCode " , CC " ( " OBJECTCONSTANT " )I " , FN_PTR ( getIdentityHashCode ) } ,
{ CC " isInternedString " , CC " ( " OBJECTCONSTANT " )Z " , FN_PTR ( isInternedString ) } ,
{ CC " unboxPrimitive " , CC " ( " OBJECTCONSTANT " ) " OBJECT , FN_PTR ( unboxPrimitive ) } ,
{ CC " boxPrimitive " , CC " ( " OBJECT " ) " OBJECTCONSTANT , FN_PTR ( boxPrimitive ) } ,
{ CC " getDeclaredConstructors " , CC " ( " HS_RESOLVED_KLASS " )[ " RESOLVED_METHOD , FN_PTR ( getDeclaredConstructors ) } ,
{ CC " getDeclaredMethods " , CC " ( " HS_RESOLVED_KLASS " )[ " RESOLVED_METHOD , FN_PTR ( getDeclaredMethods ) } ,
{ CC " readFieldValue " , CC " ( " HS_RESOLVED_KLASS HS_RESOLVED_FIELD " Z) " JAVACONSTANT , FN_PTR ( readFieldValue ) } ,
{ CC " readFieldValue " , CC " ( " OBJECTCONSTANT HS_RESOLVED_FIELD " Z) " JAVACONSTANT , FN_PTR ( readFieldValue ) } ,
{ CC " isInstance " , CC " ( " HS_RESOLVED_KLASS OBJECTCONSTANT " )Z " , FN_PTR ( isInstance ) } ,
{ CC " isAssignableFrom " , CC " ( " HS_RESOLVED_KLASS HS_RESOLVED_KLASS " )Z " , FN_PTR ( isAssignableFrom ) } ,
{ CC " isTrustedForIntrinsics " , CC " ( " HS_RESOLVED_KLASS " )Z " , FN_PTR ( isTrustedForIntrinsics ) } ,
{ CC " asJavaType " , CC " ( " OBJECTCONSTANT " ) " HS_RESOLVED_TYPE , FN_PTR ( asJavaType ) } ,
{ CC " asString " , CC " ( " OBJECTCONSTANT " ) " STRING , FN_PTR ( asString ) } ,
{ CC " equals " , CC " ( " OBJECTCONSTANT " J " OBJECTCONSTANT " J)Z " , FN_PTR ( equals ) } ,
{ CC " getJavaMirror " , CC " ( " HS_RESOLVED_TYPE " ) " OBJECTCONSTANT , FN_PTR ( getJavaMirror ) } ,
{ CC " getArrayLength " , CC " ( " OBJECTCONSTANT " )I " , FN_PTR ( getArrayLength ) } ,
{ CC " readArrayElement " , CC " ( " OBJECTCONSTANT " I)Ljava/lang/Object; " , FN_PTR ( readArrayElement ) } ,
{ CC " arrayBaseOffset " , CC " (Ljdk/vm/ci/meta/JavaKind;)I " , FN_PTR ( arrayBaseOffset ) } ,
{ CC " arrayIndexScale " , CC " (Ljdk/vm/ci/meta/JavaKind;)I " , FN_PTR ( arrayIndexScale ) } ,
{ CC " getByte " , CC " ( " OBJECTCONSTANT " J)B " , FN_PTR ( getByte ) } ,
{ CC " getShort " , CC " ( " OBJECTCONSTANT " J)S " , FN_PTR ( getShort ) } ,
{ CC " getInt " , CC " ( " OBJECTCONSTANT " J)I " , FN_PTR ( getInt ) } ,
{ CC " getLong " , CC " ( " OBJECTCONSTANT " J)J " , FN_PTR ( getLong ) } ,
{ CC " getObject " , CC " ( " OBJECTCONSTANT " J) " OBJECTCONSTANT , FN_PTR ( getObject ) } ,
{ CC " deleteGlobalHandle " , CC " (J)V " , FN_PTR ( deleteGlobalHandle ) } ,
{ CC " registerNativeMethods " , CC " ( " CLASS " )[J " , FN_PTR ( registerNativeMethods ) } ,
2019-05-06 20:05:19 -07:00
{ CC " isCurrentThreadAttached " , CC " ()Z " , FN_PTR ( isCurrentThreadAttached ) } ,
2019-10-24 16:58:39 -07:00
{ CC " getCurrentJavaThread " , CC " ()J " , FN_PTR ( getCurrentJavaThread ) } ,
2019-05-06 20:05:19 -07:00
{ CC " attachCurrentThread " , CC " (Z)Z " , FN_PTR ( attachCurrentThread ) } ,
{ CC " detachCurrentThread " , CC " ()V " , FN_PTR ( detachCurrentThread ) } ,
2019-05-01 12:31:29 -07:00
{ CC " translate " , CC " ( " OBJECT " )J " , FN_PTR ( translate ) } ,
{ CC " unhand " , CC " (J) " OBJECT , FN_PTR ( unhand ) } ,
{ CC " updateHotSpotNmethod " , CC " ( " HS_NMETHOD " )V " , FN_PTR ( updateHotSpotNmethod ) } ,
{ CC " getCode " , CC " ( " HS_INSTALLED_CODE " )[B " , FN_PTR ( getCode ) } ,
2018-11-21 22:02:17 +01:00
{ CC " asReflectionExecutable " , CC " ( " HS_RESOLVED_METHOD " ) " REFLECTION_EXECUTABLE , FN_PTR ( asReflectionExecutable ) } ,
{ CC " asReflectionField " , CC " ( " HS_RESOLVED_KLASS " I) " REFLECTION_FIELD , FN_PTR ( asReflectionField ) } ,
2019-05-01 12:31:29 -07:00
{ CC " getFailedSpeculations " , CC " (J[[B)[[B " , FN_PTR ( getFailedSpeculations ) } ,
{ CC " getFailedSpeculationsAddress " , CC " ( " HS_RESOLVED_METHOD " )J " , FN_PTR ( getFailedSpeculationsAddress ) } ,
{ CC " releaseFailedSpeculations " , CC " (J)V " , FN_PTR ( releaseFailedSpeculations ) } ,
{ CC " addFailedSpeculation " , CC " (J[B)Z " , FN_PTR ( addFailedSpeculation ) } ,
2019-06-21 16:21:13 -07:00
{ CC " callSystemExit " , CC " (I)V " , FN_PTR ( callSystemExit ) } ,
2015-10-08 12:49:30 -10:00
} ;
int CompilerToVM : : methods_count ( ) {
return sizeof ( methods ) / sizeof ( JNINativeMethod ) ;
}