src/share/vm/runtime/sharedRuntime.cpp
Print this page
*** 54,63 ****
--- 54,64 ----
#include "runtime/javaCalls.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vframeArray.hpp"
+ #include "trace/tracing.hpp"
#include "utilities/copy.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/hashtable.inline.hpp"
#include "utilities/macros.hpp"
*** 480,491 ****
if (nm->is_deopt_pc(return_address)) {
// If we come here because of a stack overflow, the stack may be
// unguarded. Reguard the stack otherwise if we return to the
// deopt blob and the stack bang causes a stack overflow we
// crash.
! bool guard_pages_enabled = thread->stack_yellow_zone_enabled();
if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
assert(guard_pages_enabled, "stack banging in deopt blob may cause crash");
return SharedRuntime::deopt_blob()->unpack_with_exception();
} else {
return nm->exception_begin();
}
--- 481,495 ----
if (nm->is_deopt_pc(return_address)) {
// If we come here because of a stack overflow, the stack may be
// unguarded. Reguard the stack otherwise if we return to the
// deopt blob and the stack bang causes a stack overflow we
// crash.
! bool guard_pages_enabled = thread->stack_guards_enabled();
if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
+ if (thread->reserved_stack_activation() != (intptr_t*) thread->stack_base()) {
+ thread->set_reserved_stack_activation((intptr_t*) thread->stack_base());
+ }
assert(guard_pages_enabled, "stack banging in deopt blob may cause crash");
return SharedRuntime::deopt_blob()->unpack_with_exception();
} else {
return nm->exception_begin();
}
*** 761,782 ****
// cache sites (when the callee activation is not yet set up) so we are at a call site
throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException());
JRT_END
JRT_ENTRY(void, SharedRuntime::throw_StackOverflowError(JavaThread* thread))
// We avoid using the normal exception construction in this case because
// it performs an upcall to Java, and we're already out of stack space.
Klass* k = SystemDictionary::StackOverflowError_klass();
oop exception_oop = InstanceKlass::cast(k)->allocate_instance(CHECK);
Handle exception (thread, exception_oop);
if (StackTraceInThrowable) {
java_lang_Throwable::fill_in_stack_trace(exception);
}
// Increment counter for hs_err file reporting
Atomic::inc(&Exceptions::_stack_overflow_errors);
throw_and_post_jvmti_exception(thread, exception);
! JRT_END
#if INCLUDE_JVMCI
address SharedRuntime::deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason) {
assert(deopt_reason > Deoptimization::Reason_none && deopt_reason < Deoptimization::Reason_LIMIT, "invalid deopt reason");
thread->set_jvmci_implicit_exception_pc(pc);
--- 765,799 ----
// cache sites (when the callee activation is not yet set up) so we are at a call site
throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException());
JRT_END
JRT_ENTRY(void, SharedRuntime::throw_StackOverflowError(JavaThread* thread))
+ throw_StackOverflowError_common(thread, false);
+ JRT_END
+
+ JRT_ENTRY(void, SharedRuntime::throw_delayed_StackOverflowError(JavaThread* thread))
+ throw_StackOverflowError_common(thread, true);
+ JRT_END
+
+ void SharedRuntime::throw_StackOverflowError_common(JavaThread* thread, bool delayed) {
// We avoid using the normal exception construction in this case because
// it performs an upcall to Java, and we're already out of stack space.
+ Thread* THREAD = thread;
Klass* k = SystemDictionary::StackOverflowError_klass();
oop exception_oop = InstanceKlass::cast(k)->allocate_instance(CHECK);
+ if (delayed) {
+ java_lang_Throwable::set_message(exception_oop,
+ Universe::delayed_stack_overflow_error_message());
+ }
Handle exception (thread, exception_oop);
if (StackTraceInThrowable) {
java_lang_Throwable::fill_in_stack_trace(exception);
}
// Increment counter for hs_err file reporting
Atomic::inc(&Exceptions::_stack_overflow_errors);
throw_and_post_jvmti_exception(thread, exception);
! }
#if INCLUDE_JVMCI
address SharedRuntime::deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason) {
assert(deopt_reason > Deoptimization::Reason_none && deopt_reason < Deoptimization::Reason_LIMIT, "invalid deopt reason");
thread->set_jvmci_implicit_exception_pc(pc);
*** 2928,2932 ****
--- 2945,3015 ----
void AdapterHandlerLibrary::print_statistics() {
_adapters->print_statistics();
}
#endif /* PRODUCT */
+
+ 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();
+ thread->set_reserved_stack_activation((intptr_t*)thread->stack_base());
+ JRT_END
+
+ frame SharedRuntime::look_for_reserved_stack_annotated_method(JavaThread* thread, frame fr) {
+ frame activation;
+ int decode_offset = 0;
+ nmethod* nm = NULL;
+ frame prv_fr = fr;
+ int count = 1;
+
+ assert(fr.is_java_frame(), "Must start on Java frame");
+
+ while (!fr.is_first_frame()) {
+ Method* method = NULL;
+ // Compiled java method case.
+ if (decode_offset != 0) {
+ DebugInfoReadStream stream(nm, decode_offset);
+ decode_offset = stream.read_int();
+ method = (Method*)nm->metadata_at(stream.read_int());
+ } else {
+ if (fr.is_first_java_frame()) break;
+ address pc = fr.pc();
+ if (fr.is_interpreted_frame()) {
+ method = fr.interpreter_frame_method();
+ prv_fr = fr;
+ fr = fr.java_sender();
+ } else {
+ CodeBlob* cb = fr.cb();
+ prv_fr = fr;
+ fr = fr.java_sender();
+ if (cb == NULL || !cb->is_nmethod()) {
+ continue;
+ }
+ nm = (nmethod*)cb;
+ if (nm->method()->is_native()) {
+ method = nm->method();
+ } else {
+ PcDesc* pd = nm->pc_desc_at(pc);
+ assert(pd != NULL, "PcDesc must not be NULL");
+ decode_offset = pd->scope_decode_offset();
+ // if decode_offset is not equal to 0, it will execute the
+ // "compiled java method case" at the beginning of the loop.
+ continue;
+ }
+ }
+ }
+ if (method->has_reserved_stack_access()) {
+ ResourceMark rm(thread);
+ activation = prv_fr;
+ warning("Potentially dangerous stack overflow in "
+ "ReservedStackAccess annotated method %s [%d]",
+ method->name_and_sig_as_C_string(), count++);
+ EventReservedStackActivation event;
+ if (event.should_commit()) {
+ event.set_method(method);
+ event.commit();
+ }
+ }
+ }
+ return activation;
+ }
+