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) 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.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
||||
// Actually we should never reach here since we do stack overflow checks before pushing any frame.
|
||||
address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
|
@ -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.
|
||||
// Enlarge by locals-parameters (not in case of native_call), shrink by ESP-SP-ABI48.
|
||||
|
||||
{
|
||||
if (!native_call) {
|
||||
// --------------------------------------------------------------------------
|
||||
// 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(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);
|
||||
|
||||
// Store values.
|
||||
|
@ -1133,6 +1139,29 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
|||
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)
|
||||
// This sets up a somewhat different looking stack for calling the
|
||||
// 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
|
||||
// following registers are valid after this:
|
||||
// - 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)
|
||||
// [ 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);
|
||||
|
||||
BIND(continue_after_compile);
|
||||
}
|
||||
|
||||
bang_stack_shadow_pages(true);
|
||||
|
||||
if (inc_counter) {
|
||||
// Reset the _do_not_unlock_if_synchronized flag.
|
||||
if (synchronized) {
|
||||
__ 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.
|
||||
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);
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
@ -1651,7 +1686,11 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
|
|||
}
|
||||
|
||||
__ bind(profile_method_continue);
|
||||
}
|
||||
|
||||
bang_stack_shadow_pages(false);
|
||||
|
||||
if (inc_counter || ProfileInterpreter) {
|
||||
// Reset the _do_not_unlock_if_synchronized flag.
|
||||
if (synchronized) {
|
||||
__ li(R0, 0);
|
||||
|
|
|
@ -1336,12 +1336,10 @@ bool os::stack_shadow_pages_available(Thread *thread, const methodHandle& method
|
|||
const int framesize_in_bytes =
|
||||
Interpreter::size_top_interpreter_activation(method()) * wordSize;
|
||||
|
||||
assert((thread->stack_base() - thread->stack_size()) +
|
||||
(JavaThread::stack_guard_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size() + framesize_in_bytes) ==
|
||||
((JavaThread*)thread)->stack_overflow_limit() + framesize_in_bytes, "sanity");
|
||||
address limit = ((JavaThread*)thread)->stack_end() +
|
||||
(JavaThread::stack_guard_zone_size() + JavaThread::stack_shadow_zone_size());
|
||||
|
||||
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) {
|
||||
|
|
|
@ -1371,10 +1371,10 @@ class JavaThread: public Thread {
|
|||
// | reserved pages |
|
||||
// | |
|
||||
// -- <-- stack_reserved_zone_base() --- ---
|
||||
// /|\ shadow
|
||||
// /|\ shadow <-- stack_overflow_limit() (somewhere in here)
|
||||
// | zone
|
||||
// \|/ 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; }
|
||||
void set_stack_overflow_limit() {
|
||||
_stack_overflow_limit = stack_end() +
|
||||
(JavaThread::stack_guard_zone_size() +
|
||||
JavaThread::stack_shadow_zone_size());
|
||||
_stack_overflow_limit =
|
||||
stack_end() + MAX2(JavaThread::stack_guard_zone_size(), JavaThread::stack_shadow_zone_size());
|
||||
}
|
||||
|
||||
// Misc. accessors/mutators
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue