# HG changeset patch # User Tom Rodriguez # Date 1453326994 28800 # Node ID bf8a5a6861b1f17bcbeb5802bd1c37402483444e # Parent 5d06abd6d35b9385aaff9af90a6d0cd729c81246 Add CompilerToVM.interpreterFrameSize to support stack banging for deopt diff -r 5d06abd6d35b -r bf8a5a6861b1 jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java --- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Jan 20 11:13:45 2016 +0100 +++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Jan 20 13:56:34 2016 -0800 @@ -29,6 +29,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.code.InvalidInstalledCodeException; import jdk.vm.ci.code.TargetDescription; @@ -587,4 +588,14 @@ * @throws IllegalArgumentException if an out of range position is given */ native int methodDataProfileDataSize(long metaspaceMethodData, int position); + + /** + * Return the amount of native stack required for the interpreter frames represented by + * {@code frame}. This is used when emitting the stack banging code to ensure that there is + * enough space for the frames during deoptimization. + * + * @param frame + * @return the number of bytes required for deoptimization of this frame state + */ + native int interpreterFrameSize(BytecodeFrame frame); } diff -r 5d06abd6d35b -r bf8a5a6861b1 jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java --- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java Wed Jan 20 11:13:45 2016 +0100 +++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java Wed Jan 20 13:56:34 2016 -0800 @@ -25,6 +25,7 @@ import java.lang.reflect.Field; import jdk.vm.ci.code.BailoutException; +import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.code.CodeCacheProvider; import jdk.vm.ci.code.CompiledCode; import jdk.vm.ci.code.InstalledCode; @@ -169,6 +170,10 @@ return runtime.getCompilerToVM().shouldDebugNonSafepoints(); } + public int interpreterFrameSize(BytecodeFrame pos) { + return runtime.getCompilerToVM().interpreterFrameSize(pos); + } + /** * Resets all compilation statistics. */ diff -r 5d06abd6d35b -r bf8a5a6861b1 jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java --- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Wed Jan 20 11:13:45 2016 +0100 +++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Wed Jan 20 13:56:34 2016 -0800 @@ -838,11 +838,12 @@ @HotSpotVMFlag(name = "UseBlockZeroing", archs = {"sparc"}) @Stable public boolean useBlockZeroing; @HotSpotVMFlag(name = "BlockZeroingLowLimit", archs = {"sparc"}) @Stable public int blockZeroingLowLimit; - // offsets, ... @HotSpotVMFlag(name = "StackShadowPages") @Stable public int stackShadowPages; @HotSpotVMFlag(name = "UseStackBanging") @Stable public boolean useStackBanging; @HotSpotVMConstant(name = "STACK_BIAS") @Stable public int stackBias; + @HotSpotVMValue(expression = "os::vm_page_size()") @Stable public int vmPageSize; + // offsets, ... @HotSpotVMField(name = "oopDesc::_mark", type = "markOop", get = HotSpotVMField.Type.OFFSET) @Stable public int markOffset; @HotSpotVMField(name = "oopDesc::_metadata._klass", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int hubOffset; diff -r 5d06abd6d35b -r bf8a5a6861b1 src/share/vm/jvmci/jvmciCompilerToVM.cpp --- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp Wed Jan 20 11:13:45 2016 +0100 +++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp Wed Jan 20 13:56:34 2016 -0800 @@ -1159,6 +1159,42 @@ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Invalid profile data position %d", position)); C2V_END +C2V_VMENTRY(int, interpreterFrameSize, (JNIEnv*, jobject, jobject bytecode_frame_handle)) + if (bytecode_frame_handle == NULL) { + THROW_0(vmSymbols::java_lang_NullPointerException()); + } + + oop top_bytecode_frame = JNIHandles::resolve_non_null(bytecode_frame_handle); + oop bytecode_frame = top_bytecode_frame; + int size = 0; + int callee_parameters = 0; + int callee_locals = 0; + Method* method = getMethodFromHotSpotMethod(BytecodePosition::method(bytecode_frame)); + int extra_args = method->max_stack() - BytecodeFrame::numStack(bytecode_frame); + + while (bytecode_frame != NULL) { + int locks = BytecodeFrame::numLocks(bytecode_frame); + int temps = BytecodeFrame::numStack(bytecode_frame); + bool is_top_frame = (bytecode_frame == top_bytecode_frame); + Method* method = getMethodFromHotSpotMethod(BytecodePosition::method(bytecode_frame)); + + 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; + bytecode_frame = BytecodePosition::caller(bytecode_frame); + } + return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord; +C2V_END + #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) @@ -1169,6 +1205,7 @@ #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;" @@ -1236,6 +1273,7 @@ {CC"writeDebugOutput", CC"([BII)V", FN_PTR(writeDebugOutput)}, {CC"flushDebugOutput", CC"()V", FN_PTR(flushDebugOutput)}, {CC"methodDataProfileDataSize", CC"(JI)I", FN_PTR(methodDataProfileDataSize)}, + {CC"interpreterFrameSize", CC"("BYTECODE_FRAME")I", FN_PTR(interpreterFrameSize)}, }; int CompilerToVM::methods_count() {