mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8194490: [JVMCI] Move iterateFrames
to C++
Reviewed-by: kvn, never, dnsimon
This commit is contained in:
parent
2c0c55bb7e
commit
597c6ac736
11 changed files with 157 additions and 350 deletions
|
@ -1376,53 +1376,40 @@ bool matches(jobjectArray methods, Method* method) {
|
|||
return false;
|
||||
}
|
||||
|
||||
C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv*, jobject compilerToVM, jobject hs_frame, jobjectArray methods, jint initialSkip))
|
||||
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);
|
||||
methodHandle method = callinfo.selected_method();
|
||||
assert(method.not_null(), "should have thrown exception");
|
||||
|
||||
// Invoke the method
|
||||
JavaCalls::call(result, method, args, CHECK);
|
||||
}
|
||||
|
||||
C2V_VMENTRY(jobject, iterateFrames, (JNIEnv*, jobject compilerToVM, jobjectArray initial_methods, jobjectArray match_methods, jint initialSkip, jobject visitor_handle))
|
||||
ResourceMark rm;
|
||||
|
||||
if (!thread->has_last_Java_frame()) return NULL;
|
||||
Handle result = HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
|
||||
if (!thread->has_last_Java_frame()) {
|
||||
return NULL;
|
||||
}
|
||||
Handle visitor(THREAD, JNIHandles::resolve_non_null(visitor_handle));
|
||||
Handle frame_reference = HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
|
||||
HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);
|
||||
|
||||
StackFrameStream fst(thread);
|
||||
if (hs_frame != NULL) {
|
||||
// look for the correct stack frame if one is given
|
||||
intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame);
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
jobjectArray methods = initial_methods;
|
||||
|
||||
int frame_number = 0;
|
||||
vframe* vf = vframe::new_vframe(fst.current(), fst.register_map(), thread);
|
||||
if (hs_frame != NULL) {
|
||||
// look for the correct vframe within the stack frame if one is given
|
||||
int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame);
|
||||
while (frame_number < last_frame_number) {
|
||||
if (vf->is_top()) {
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "invalid frame number")
|
||||
}
|
||||
vf = vf->sender();
|
||||
frame_number ++;
|
||||
}
|
||||
// move one frame forward
|
||||
if (vf->is_top()) {
|
||||
if (fst.is_done()) {
|
||||
return NULL;
|
||||
}
|
||||
fst.next();
|
||||
vf = vframe::new_vframe(fst.current(), fst.register_map(), thread);
|
||||
frame_number = 0;
|
||||
} else {
|
||||
vf = vf->sender();
|
||||
frame_number++;
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
// look for the given method
|
||||
bool realloc_called = false;
|
||||
while (true) {
|
||||
StackValueCollection* locals = NULL;
|
||||
if (vf->is_compiled_frame()) {
|
||||
|
@ -1430,13 +1417,28 @@ C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv*, jobject compilerToVM, jobject
|
|||
compiledVFrame* cvf = compiledVFrame::cast(vf);
|
||||
if (methods == NULL || matches(methods, cvf->method())) {
|
||||
if (initialSkip > 0) {
|
||||
initialSkip --;
|
||||
initialSkip--;
|
||||
} else {
|
||||
ScopeDesc* scope = cvf->scope();
|
||||
// native wrappers do not have a scope
|
||||
if (scope != NULL && scope->objects() != NULL) {
|
||||
bool realloc_failures = Deoptimization::realloc_objects(thread, fst.current(), scope->objects(), CHECK_NULL);
|
||||
Deoptimization::reassign_fields(fst.current(), fst.register_map(), scope->objects(), realloc_failures, false);
|
||||
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());
|
||||
int ii = 0;
|
||||
for (int i = 0; i < scope->objects()->length(); i++) {
|
||||
ObjectValue* sv = (ObjectValue*) scope->objects()->at(i);
|
||||
if (sv->value().is_null()) {
|
||||
objects->at_put(ii++, sv);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool realloc_failures = Deoptimization::realloc_objects(thread, fst.current(), objects, CHECK_NULL);
|
||||
Deoptimization::reassign_fields(fst.current(), fst.register_map(), objects, realloc_failures, false);
|
||||
realloc_called = true;
|
||||
|
||||
GrowableArray<ScopeValue*>* local_values = scope->locals();
|
||||
assert(local_values != NULL, "NULL locals");
|
||||
|
@ -1448,15 +1450,15 @@ C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv*, jobject compilerToVM, jobject
|
|||
array->bool_at_put(i, true);
|
||||
}
|
||||
}
|
||||
HotSpotStackFrameReference::set_localIsVirtual(result, array());
|
||||
HotSpotStackFrameReference::set_localIsVirtual(frame_reference, array());
|
||||
} else {
|
||||
HotSpotStackFrameReference::set_localIsVirtual(result, NULL);
|
||||
HotSpotStackFrameReference::set_localIsVirtual(frame_reference, NULL);
|
||||
}
|
||||
|
||||
locals = cvf->locals();
|
||||
HotSpotStackFrameReference::set_bci(result, cvf->bci());
|
||||
HotSpotStackFrameReference::set_bci(frame_reference, cvf->bci());
|
||||
oop method = CompilerToVM::get_jvmci_method(cvf->method(), CHECK_NULL);
|
||||
HotSpotStackFrameReference::set_method(result, method);
|
||||
HotSpotStackFrameReference::set_method(frame_reference, method);
|
||||
}
|
||||
}
|
||||
} else if (vf->is_interpreted_frame()) {
|
||||
|
@ -1464,22 +1466,23 @@ C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv*, jobject compilerToVM, jobject
|
|||
interpretedVFrame* ivf = interpretedVFrame::cast(vf);
|
||||
if (methods == NULL || matches(methods, ivf->method())) {
|
||||
if (initialSkip > 0) {
|
||||
initialSkip --;
|
||||
initialSkip--;
|
||||
} else {
|
||||
locals = ivf->locals();
|
||||
HotSpotStackFrameReference::set_bci(result, ivf->bci());
|
||||
HotSpotStackFrameReference::set_bci(frame_reference, ivf->bci());
|
||||
oop method = CompilerToVM::get_jvmci_method(ivf->method(), CHECK_NULL);
|
||||
HotSpotStackFrameReference::set_method(result, method);
|
||||
HotSpotStackFrameReference::set_localIsVirtual(result, NULL);
|
||||
HotSpotStackFrameReference::set_method(frame_reference, method);
|
||||
HotSpotStackFrameReference::set_localIsVirtual(frame_reference, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// locals != NULL means that we found a matching frame and result is already partially initialized
|
||||
if (locals != NULL) {
|
||||
HotSpotStackFrameReference::set_compilerToVM(result, JNIHandles::resolve(compilerToVM));
|
||||
HotSpotStackFrameReference::set_stackPointer(result, (jlong) fst.current()->sp());
|
||||
HotSpotStackFrameReference::set_frameNumber(result, frame_number);
|
||||
methods = match_methods;
|
||||
HotSpotStackFrameReference::set_compilerToVM(frame_reference, JNIHandles::resolve(compilerToVM));
|
||||
HotSpotStackFrameReference::set_stackPointer(frame_reference, (jlong) fst.current()->sp());
|
||||
HotSpotStackFrameReference::set_frameNumber(frame_reference, frame_number);
|
||||
|
||||
// initialize the locals array
|
||||
objArrayOop array_oop = oopFactory::new_objectArray(locals->size(), CHECK_NULL);
|
||||
|
@ -1490,9 +1493,41 @@ C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv*, jobject compilerToVM, jobject
|
|||
array->obj_at_put(i, locals->at(i)->get_obj()());
|
||||
}
|
||||
}
|
||||
HotSpotStackFrameReference::set_locals(result, array());
|
||||
HotSpotStackFrameReference::set_locals(frame_reference, array());
|
||||
HotSpotStackFrameReference::set_objectsMaterialized(frame_reference, JNI_FALSE);
|
||||
|
||||
return JNIHandles::make_local(thread, result());
|
||||
JavaValue result(T_OBJECT);
|
||||
JavaCallArguments args(visitor);
|
||||
args.push_oop(frame_reference);
|
||||
call_interface(&result, SystemDictionary::InspectedFrameVisitor_klass(), vmSymbols::visitFrame_name(), vmSymbols::visitFrame_signature(), &args, CHECK_NULL);
|
||||
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");
|
||||
if (HotSpotStackFrameReference::objectsMaterialized(frame_reference) == JNI_TRUE) {
|
||||
// the frame has been deoptimized, we need to re-synchronize the frame and vframe
|
||||
intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(frame_reference);
|
||||
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");
|
||||
}
|
||||
}
|
||||
frame_reference = HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
|
||||
HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);
|
||||
}
|
||||
|
||||
if (vf->is_top()) {
|
||||
|
@ -1712,6 +1747,7 @@ C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv*, jobject, jobject hs_frame
|
|||
array->obj_at_put(i, locals->at(i)->get_obj()());
|
||||
}
|
||||
}
|
||||
HotSpotStackFrameReference::set_objectsMaterialized(hs_frame, JNI_TRUE);
|
||||
C2V_END
|
||||
|
||||
C2V_VMENTRY(void, writeDebugOutput, (JNIEnv*, jobject, jbyteArray bytes, jint offset, jint length))
|
||||
|
@ -1826,24 +1862,25 @@ C2V_END
|
|||
#define CC (char*) /*cast a literal from (const char*)*/
|
||||
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
|
||||
|
||||
#define STRING "Ljava/lang/String;"
|
||||
#define OBJECT "Ljava/lang/Object;"
|
||||
#define CLASS "Ljava/lang/Class;"
|
||||
#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;"
|
||||
#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;"
|
||||
#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;"
|
||||
#define METASPACE_METHOD_DATA "J"
|
||||
#define STRING "Ljava/lang/String;"
|
||||
#define OBJECT "Ljava/lang/Object;"
|
||||
#define CLASS "Ljava/lang/Class;"
|
||||
#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;"
|
||||
#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;"
|
||||
#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;"
|
||||
#define METASPACE_METHOD_DATA "J"
|
||||
|
||||
JNINativeMethod CompilerToVM::methods[] = {
|
||||
{CC "getBytecode", CC "(" HS_RESOLVED_METHOD ")[B", FN_PTR(getBytecode)},
|
||||
|
@ -1899,7 +1936,7 @@ JNINativeMethod CompilerToVM::methods[] = {
|
|||
{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)},
|
||||
{CC "getNextStackFrame", CC "(" HS_STACK_FRAME_REF "[" RESOLVED_METHOD "I)" HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)},
|
||||
{CC "iterateFrames", CC "([" RESOLVED_METHOD "[" RESOLVED_METHOD "I" INSPECTED_FRAME_VISITOR ")" OBJECT, FN_PTR(iterateFrames)},
|
||||
{CC "materializeVirtualObjects", CC "(" HS_STACK_FRAME_REF "Z)V", FN_PTR(materializeVirtualObjects)},
|
||||
{CC "shouldDebugNonSafepoints", CC "()Z", FN_PTR(shouldDebugNonSafepoints)},
|
||||
{CC "writeDebugOutput", CC "([BII)V", FN_PTR(writeDebugOutput)},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue