# HG changeset patch # User never # Date 1453489866 28800 # Fri Jan 22 11:11:06 2016 -0800 # Node ID 9dc2fff656d22156a15c6ae9d4ec93073cc9e17d # Parent 3a91a2e9466597e0673971e30123e4844d18540b 8146424: runtime/ReservedStack/ReservedStackTest.java triggers: assert(thread->deopt_mark() == __null) failed: no stack overflow from deopt blob/uncommon trap diff --git a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java @@ -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; @@ -604,4 +605,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 --git a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java @@ -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; @@ -185,6 +186,10 @@ runtime.getCompilerToVM().notifyCompilationStatistics(id, (HotSpotResolvedJavaMethodImpl) method, osr, processedBytecodes, time, timeUnitsPerSecond, installedCode); } + public int interpreterFrameSize(BytecodeFrame pos) { + return runtime.getCompilerToVM().interpreterFrameSize(pos); + } + /** * Resets all compilation statistics. */ diff --git a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java --- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -973,11 +973,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; + @HotSpotVMField(name = "CompilerToVM::Data::vm_page_size", type = "int", get = HotSpotVMField.Type.VALUE) @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 --git a/src/share/vm/jvmci/jvmciCompilerToVM.cpp b/src/share/vm/jvmci/jvmciCompilerToVM.cpp --- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp +++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp @@ -149,6 +149,8 @@ jbyte* CompilerToVM::Data::cardtable_start_address; int CompilerToVM::Data::cardtable_shift; +int CompilerToVM::Data::vm_page_size; + void CompilerToVM::Data::initialize() { InstanceKlass_vtable_start_offset = InstanceKlass::vtable_start_offset(); InstanceKlass_vtable_length_offset = InstanceKlass::vtable_length_offset() * HeapWordSize; @@ -198,6 +200,8 @@ ShouldNotReachHere(); break; } + + vm_page_size = os::vm_page_size(); } /** @@ -1388,6 +1392,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)) @@ -1398,6 +1438,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;" @@ -1468,6 +1509,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() { diff --git a/src/share/vm/jvmci/jvmciCompilerToVM.hpp b/src/share/vm/jvmci/jvmciCompilerToVM.hpp --- a/src/share/vm/jvmci/jvmciCompilerToVM.hpp +++ b/src/share/vm/jvmci/jvmciCompilerToVM.hpp @@ -63,6 +63,8 @@ static jbyte* cardtable_start_address; static int cardtable_shift; + static int vm_page_size; + public: static void initialize(); }; diff --git a/src/share/vm/jvmci/vmStructs_jvmci.cpp b/src/share/vm/jvmci/vmStructs_jvmci.cpp --- a/src/share/vm/jvmci/vmStructs_jvmci.cpp +++ b/src/share/vm/jvmci/vmStructs_jvmci.cpp @@ -74,6 +74,8 @@ static_field(CompilerToVM::Data, cardtable_start_address, jbyte*) \ static_field(CompilerToVM::Data, cardtable_shift, int) \ \ + static_field(CompilerToVM::Data, vm_page_size, int) \ + \ static_field(Abstract_VM_Version, _features, uint64_t) \ \ nonstatic_field(Array, _length, int) \