--- old/src/cpu/x86/vm/interp_masm_x86.cpp 2017-04-12 14:36:17.722875637 -0400 +++ new/src/cpu/x86/vm/interp_masm_x86.cpp 2017-04-12 14:36:17.078872443 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1080,7 +1080,6 @@ call_VM_leaf( CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), rthread); - push(rthread); call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_delayed_StackOverflowError)); should_not_reach_here(); --- old/src/share/vm/code/compiledMethod.cpp 2017-04-12 14:36:20.234888093 -0400 +++ new/src/share/vm/code/compiledMethod.cpp 2017-04-12 14:36:19.494884424 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -214,6 +214,14 @@ guarantee(pd != NULL, "scope must be present"); return new ScopeDesc(this, pd->scope_decode_offset(), pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(), + pd->return_oop()); +} + +ScopeDesc* CompiledMethod::scope_desc_near(address pc) { + PcDesc* pd = pc_desc_near(pc); + guarantee(pd != NULL, "scope must be present"); + return new ScopeDesc(this, pd->scope_decode_offset(), + pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(), pd->return_oop()); } --- old/src/share/vm/code/compiledMethod.hpp 2017-04-12 14:36:22.754900589 -0400 +++ new/src/share/vm/code/compiledMethod.hpp 2017-04-12 14:36:21.786895789 -0400 @@ -213,11 +213,12 @@ // ScopeDesc retrieval operation PcDesc* pc_desc_at(address pc) { return find_pc_desc(pc, false); } - // pc_desc_near returns the first PcDesc at or after the givne pc. + // pc_desc_near returns the first PcDesc at or after the given pc. PcDesc* pc_desc_near(address pc) { return find_pc_desc(pc, true); } // ScopeDesc for an instruction ScopeDesc* scope_desc_at(address pc); + ScopeDesc* scope_desc_near(address pc); bool is_at_poll_return(address pc); bool is_at_poll_or_poll_return(address pc); --- old/src/share/vm/opto/compile.cpp 2017-04-12 14:36:25.158912510 -0400 +++ new/src/share/vm/opto/compile.cpp 2017-04-12 14:36:24.430908900 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -992,7 +992,8 @@ _print_inlining_output(NULL), _allowed_reasons(0), _interpreter_frame_size(0), - _max_node_limit(MaxNodeLimit) { + _max_node_limit(MaxNodeLimit), + _has_reserved_stack_access(false) { C = this; TraceTime t1(NULL, &_t_totalCompilation, CITime, false); --- old/src/share/vm/runtime/sharedRuntime.cpp 2017-04-12 14:36:27.386923558 -0400 +++ new/src/share/vm/runtime/sharedRuntime.cpp 2017-04-12 14:36:26.762920464 -0400 @@ -3125,11 +3125,14 @@ JRT_LEAF(void, SharedRuntime::enable_stack_reserved_zone(JavaThread* thread)) assert(thread->is_Java_thread(), "Only Java threads have a stack reserved zone"); - thread->enable_stack_reserved_zone(); + if (thread->stack_reserved_zone_disabled()) { + thread->enable_stack_reserved_zone(); + } thread->set_reserved_stack_activation(thread->stack_base()); JRT_END frame SharedRuntime::look_for_reserved_stack_annotated_method(JavaThread* thread, frame fr) { + ResourceMark rm(thread); frame activation; CompiledMethod* nm = NULL; int count = 1; @@ -3138,17 +3141,28 @@ while (true) { Method* method = NULL; + bool found = false; if (fr.is_interpreted_frame()) { method = fr.interpreter_frame_method(); + if (method != NULL && method->has_reserved_stack_access()) { + found = true; + } } else { CodeBlob* cb = fr.cb(); if (cb != NULL && cb->is_compiled()) { nm = cb->as_compiled_method(); method = nm->method(); + // scope_desc_near() must be used, instead of scope_desc_at() because on + // SPARC, the pcDesc can be on the delay slot after the call instruction. + for (ScopeDesc *sd = nm->scope_desc_near(fr.pc()); sd; sd = sd->sender()) { + method = sd->method(); + if (method != NULL && method->has_reserved_stack_access()) { + found = true; + } + } } } - if ((method != NULL) && method->has_reserved_stack_access()) { - ResourceMark rm(thread); + if (found) { activation = fr; warning("Potentially dangerous stack overflow in " "ReservedStackAccess annotated method %s [%d]", --- old/test/runtime/ReservedStack/ReservedStackTest.java 2017-04-12 14:36:29.550934289 -0400 +++ new/test/runtime/ReservedStack/ReservedStackTest.java 2017-04-12 14:36:28.898931056 -0400 @@ -26,8 +26,7 @@ * @library /test/lib * @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.vm.annotation - * @run main/othervm -Xint ReservedStackTest - * @run main/othervm -XX:-Inline -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest + * @run main/othervm -XX:InlineSmallCode=4 -XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread ReservedStackTest */ /* The exclusion of java.util.concurrent.locks.AbstractOwnableSynchronizer.setExclusiveOwnerThread() @@ -161,6 +160,7 @@ } catch (StackOverflowError e) { soe = e; stackOverflowErrorReceived = true; + throw e; } } @@ -194,13 +194,10 @@ decounter = deframe; test.initialize(); recursiveCall(); - System.out.println("Framework got StackOverflowError at frame = " + counter); - System.out.println("Test started execution at frame = " + (counter - deframe)); String result = test.getResult(); // The feature is not fully implemented on all platforms, // corruptions are still possible. if (isSupportedPlatform && !result.contains("PASSED")) { - System.out.println(result); throw new Error(result); } else { // Either the test passed or this platform is not supported. @@ -289,7 +286,7 @@ public static void main(String[] args) throws Exception { initIsSupportedPlatform(); - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { // Each iteration has to be executed by a new thread. The test // relies on the random size area pushed by the VM at the beginning // of the stack of each Java thread it creates.