8194490: [JVMCI] Move iterateFrames to C++

Reviewed-by: kvn, never, dnsimon
This commit is contained in:
Gilles Duboscq 2018-03-07 19:32:54 -08:00
parent 2c0c55bb7e
commit 597c6ac736
11 changed files with 157 additions and 350 deletions

View file

@ -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)},