mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 12:34:32 +02:00
8156922: [ppc] Implement template interpreter stack overflow checks as on x86/sparc
Reviewed-by: dlong, dholmes, simonis, coleenp
This commit is contained in:
parent
1fae073d9c
commit
618f5131e6
3 changed files with 53 additions and 17 deletions
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2015 SAP SE. All rights reserved.
|
* Copyright (c) 2015, 2016 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -562,10 +562,16 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actually we should never reach here since we do stack overflow checks before pushing any frame.
|
|
||||||
address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
|
address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
|
||||||
address entry = __ pc();
|
address entry = __ pc();
|
||||||
__ unimplemented("generate_StackOverflowError_handler");
|
|
||||||
|
// Expression stack must be empty before entering the VM if an
|
||||||
|
// exception happened.
|
||||||
|
__ empty_expression_stack();
|
||||||
|
// Throw exception.
|
||||||
|
__ call_VM(noreg,
|
||||||
|
CAST_FROM_FN_PTR(address,
|
||||||
|
InterpreterRuntime::throw_StackOverflowError));
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -944,7 +950,7 @@ void TemplateInterpreterGenerator::lock_method(Register Rflags, Register Rscratc
|
||||||
// The top most frame needs an abi space of 112 bytes. This space is needed,
|
// The top most frame needs an abi space of 112 bytes. This space is needed,
|
||||||
// since we call to c. The c function may spill their arguments to the caller
|
// since we call to c. The c function may spill their arguments to the caller
|
||||||
// frame. When we call to java, we don't need these spill slots. In order to save
|
// frame. When we call to java, we don't need these spill slots. In order to save
|
||||||
// space on the stack, we resize the caller. However, java local reside in
|
// space on the stack, we resize the caller. However, java locals reside in
|
||||||
// the caller frame and the frame has to be increased. The frame_size for the
|
// the caller frame and the frame has to be increased. The frame_size for the
|
||||||
// current frame was calculated based on max_stack as size for the expression
|
// current frame was calculated based on max_stack as size for the expression
|
||||||
// stack. At the call, just a part of the expression stack might be used.
|
// stack. At the call, just a part of the expression stack might be used.
|
||||||
|
@ -1007,7 +1013,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
|
||||||
// parent_frame_resize = (locals-parameters) - (ESP-SP-ABI48) Rounded to frame alignment size.
|
// parent_frame_resize = (locals-parameters) - (ESP-SP-ABI48) Rounded to frame alignment size.
|
||||||
// Enlarge by locals-parameters (not in case of native_call), shrink by ESP-SP-ABI48.
|
// Enlarge by locals-parameters (not in case of native_call), shrink by ESP-SP-ABI48.
|
||||||
|
|
||||||
{
|
if (!native_call) {
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Stack overflow check
|
// Stack overflow check
|
||||||
|
|
||||||
|
@ -1047,7 +1053,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
|
||||||
__ addi(R26_monitor, R1_SP, - frame::ijava_state_size);
|
__ addi(R26_monitor, R1_SP, - frame::ijava_state_size);
|
||||||
__ addi(R15_esp, R26_monitor, - Interpreter::stackElementSize);
|
__ addi(R15_esp, R26_monitor, - Interpreter::stackElementSize);
|
||||||
|
|
||||||
// Get mirror and store it in the frame as GC root for this Method*
|
// Get mirror and store it in the frame as GC root for this Method*.
|
||||||
__ load_mirror(R12_scratch2, R19_method);
|
__ load_mirror(R12_scratch2, R19_method);
|
||||||
|
|
||||||
// Store values.
|
// Store values.
|
||||||
|
@ -1133,6 +1139,29 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
|
||||||
|
// Quick & dirty stack overflow checking: bang the stack & handle trap.
|
||||||
|
// Note that we do the banging after the frame is setup, since the exception
|
||||||
|
// handling code expects to find a valid interpreter frame on the stack.
|
||||||
|
// Doing the banging earlier fails if the caller frame is not an interpreter
|
||||||
|
// frame.
|
||||||
|
// (Also, the exception throwing code expects to unlock any synchronized
|
||||||
|
// method receiever, so do the banging after locking the receiver.)
|
||||||
|
|
||||||
|
// Bang each page in the shadow zone. We can't assume it's been done for
|
||||||
|
// an interpreter frame with greater than a page of locals, so each page
|
||||||
|
// needs to be checked. Only true for non-native.
|
||||||
|
if (UseStackBanging) {
|
||||||
|
const int page_size = os::vm_page_size();
|
||||||
|
const int n_shadow_pages = ((int)JavaThread::stack_shadow_zone_size()) / page_size;
|
||||||
|
const int start_page = native_call ? n_shadow_pages : 1;
|
||||||
|
BLOCK_COMMENT("bang_stack_shadow_pages:");
|
||||||
|
for (int pages = start_page; pages <= n_shadow_pages; pages++) {
|
||||||
|
__ bang_stack_with_offset(pages*page_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Interpreter stub for calling a native method. (asm interpreter)
|
// Interpreter stub for calling a native method. (asm interpreter)
|
||||||
// This sets up a somewhat different looking stack for calling the
|
// This sets up a somewhat different looking stack for calling the
|
||||||
// native method than the typical interpreter frame setup.
|
// native method than the typical interpreter frame setup.
|
||||||
|
@ -1156,7 +1185,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||||
// This is not a full-blown interpreter frame, but in particular, the
|
// This is not a full-blown interpreter frame, but in particular, the
|
||||||
// following registers are valid after this:
|
// following registers are valid after this:
|
||||||
// - R19_method
|
// - R19_method
|
||||||
// - R18_local (points to start of argumuments to native function)
|
// - R18_local (points to start of arguments to native function)
|
||||||
//
|
//
|
||||||
// abstract stack (grows up)
|
// abstract stack (grows up)
|
||||||
// [ IJava (caller of JNI callee) ] <-- ASP
|
// [ IJava (caller of JNI callee) ] <-- ASP
|
||||||
|
@ -1207,6 +1236,11 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||||
generate_counter_incr(&invocation_counter_overflow, NULL, NULL);
|
generate_counter_incr(&invocation_counter_overflow, NULL, NULL);
|
||||||
|
|
||||||
BIND(continue_after_compile);
|
BIND(continue_after_compile);
|
||||||
|
}
|
||||||
|
|
||||||
|
bang_stack_shadow_pages(true);
|
||||||
|
|
||||||
|
if (inc_counter) {
|
||||||
// Reset the _do_not_unlock_if_synchronized flag.
|
// Reset the _do_not_unlock_if_synchronized flag.
|
||||||
if (synchronized) {
|
if (synchronized) {
|
||||||
__ li(R0, 0);
|
__ li(R0, 0);
|
||||||
|
@ -1595,6 +1629,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||||
Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
|
Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
|
||||||
Rsize_of_locals = R5_ARG3; // Written by generate_fixed_frame.
|
Rsize_of_locals = R5_ARG3; // Written by generate_fixed_frame.
|
||||||
|
|
||||||
|
// Does also a stack check to assure this frame fits on the stack.
|
||||||
generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
|
generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
@ -1651,7 +1686,11 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||||
}
|
}
|
||||||
|
|
||||||
__ bind(profile_method_continue);
|
__ bind(profile_method_continue);
|
||||||
|
}
|
||||||
|
|
||||||
|
bang_stack_shadow_pages(false);
|
||||||
|
|
||||||
|
if (inc_counter || ProfileInterpreter) {
|
||||||
// Reset the _do_not_unlock_if_synchronized flag.
|
// Reset the _do_not_unlock_if_synchronized flag.
|
||||||
if (synchronized) {
|
if (synchronized) {
|
||||||
__ li(R0, 0);
|
__ li(R0, 0);
|
||||||
|
|
|
@ -1336,12 +1336,10 @@ bool os::stack_shadow_pages_available(Thread *thread, const methodHandle& method
|
||||||
const int framesize_in_bytes =
|
const int framesize_in_bytes =
|
||||||
Interpreter::size_top_interpreter_activation(method()) * wordSize;
|
Interpreter::size_top_interpreter_activation(method()) * wordSize;
|
||||||
|
|
||||||
assert((thread->stack_base() - thread->stack_size()) +
|
address limit = ((JavaThread*)thread)->stack_end() +
|
||||||
(JavaThread::stack_guard_zone_size() +
|
(JavaThread::stack_guard_zone_size() + JavaThread::stack_shadow_zone_size());
|
||||||
JavaThread::stack_shadow_zone_size() + framesize_in_bytes) ==
|
|
||||||
((JavaThread*)thread)->stack_overflow_limit() + framesize_in_bytes, "sanity");
|
|
||||||
|
|
||||||
return (sp > ((JavaThread*)thread)->stack_overflow_limit() + framesize_in_bytes);
|
return sp > (limit + framesize_in_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t os::page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned) {
|
size_t os::page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned) {
|
||||||
|
|
|
@ -1371,10 +1371,10 @@ class JavaThread: public Thread {
|
||||||
// | reserved pages |
|
// | reserved pages |
|
||||||
// | |
|
// | |
|
||||||
// -- <-- stack_reserved_zone_base() --- ---
|
// -- <-- stack_reserved_zone_base() --- ---
|
||||||
// /|\ shadow
|
// /|\ shadow <-- stack_overflow_limit() (somewhere in here)
|
||||||
// | zone
|
// | zone
|
||||||
// \|/ size
|
// \|/ size
|
||||||
// some untouched memory --- <-- stack_overflow_limit()
|
// some untouched memory ---
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// --
|
// --
|
||||||
|
@ -1522,9 +1522,8 @@ class JavaThread: public Thread {
|
||||||
|
|
||||||
address stack_overflow_limit() { return _stack_overflow_limit; }
|
address stack_overflow_limit() { return _stack_overflow_limit; }
|
||||||
void set_stack_overflow_limit() {
|
void set_stack_overflow_limit() {
|
||||||
_stack_overflow_limit = stack_end() +
|
_stack_overflow_limit =
|
||||||
(JavaThread::stack_guard_zone_size() +
|
stack_end() + MAX2(JavaThread::stack_guard_zone_size(), JavaThread::stack_shadow_zone_size());
|
||||||
JavaThread::stack_shadow_zone_size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Misc. accessors/mutators
|
// Misc. accessors/mutators
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue