8152065: TraceBytecodes breaks the interpreter expression stack

Move trace_bytecode to InterpreterRuntime and make trace_bytecode an IRT_LEAF so that safepoints are not allowed.

Reviewed-by: jiangli, dholmes, dcubed
This commit is contained in:
Coleen Phillimore 2016-03-18 15:14:22 -04:00
parent 6e0466f618
commit 1954276b28
11 changed files with 33 additions and 73 deletions

View File

@ -1967,7 +1967,7 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) {
__ push(RegSet::range(r0, r15), sp);
__ mov(c_rarg2, r0); // Pass itos
__ call_VM(noreg,
CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode),
CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode),
c_rarg1, c_rarg2, c_rarg3);
__ pop(RegSet::range(r0, r15), sp);
__ pop(state);

View File

@ -2211,7 +2211,7 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) {
__ ld(R6_ARG4, tsize*Interpreter::stackElementSize, R15_esp);
__ ld(R5_ARG3, Interpreter::stackElementSize, R15_esp);
__ mflr(R31);
__ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), /* unused */ R4_ARG2, R5_ARG3, R6_ARG4, false);
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode), /* unused */ R4_ARG2, R5_ARG3, R6_ARG4, false);
__ mtlr(R31);
__ pop(state);

View File

@ -1966,7 +1966,7 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) {
// Pass a 0 (not used in sparc) and the top of stack to the bytecode tracer
__ mov( Otos_l2, G3_scratch );
__ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), G0, Otos_l1, G3_scratch);
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode), G0, Otos_l1, G3_scratch);
__ mov(Lscratch, O7); // restore return address
__ pop(state);
__ retl();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -54,44 +54,6 @@
// <- sender sp
// ------------------------------ Asm interpreter ----------------------------------------
// ------------------------------ C++ interpreter ----------------------------------------
//
// Layout of C++ interpreter frame: (While executing in BytecodeInterpreter::run)
//
// <- SP (current esp/rsp)
// [local variables ] BytecodeInterpreter::run local variables
// ... BytecodeInterpreter::run local variables
// [local variables ] BytecodeInterpreter::run local variables
// [old frame pointer ] fp [ BytecodeInterpreter::run's ebp/rbp ]
// [return pc ] (return to frame manager)
// [interpreter_state* ] (arg to BytecodeInterpreter::run) --------------
// [expression stack ] <- last_Java_sp |
// [... ] * <- interpreter_state.stack |
// [expression stack ] * <- interpreter_state.stack_base |
// [monitors ] \ |
// ... | monitor block size |
// [monitors ] / <- interpreter_state.monitor_base |
// [struct interpretState ] <-----------------------------------------|
// [return pc ] (return to callee of frame manager [1]
// [locals and parameters ]
// <- sender sp
// [1] When the C++ interpreter calls a new method it returns to the frame
// manager which allocates a new frame on the stack. In that case there
// is no real callee of this newly allocated frame. The frame manager is
// aware of the additional frame(s) and will pop them as nested calls
// complete. However, to make it look good in the debugger the frame
// manager actually installs a dummy pc pointing to RecursiveInterpreterActivation
// with a fake interpreter_state* parameter to make it easy to debug
// nested calls.
// Note that contrary to the layout for the assembly interpreter the
// expression stack allocated for the C++ interpreter is full sized.
// However this is not as bad as it seems as the interpreter frame_manager
// will truncate the unused space on successive method calls.
//
// ------------------------------ C++ interpreter ----------------------------------------
public:
enum {
pc_return_offset = 0,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -296,7 +296,7 @@ void InterpreterMacroAssembler::call_VM_base(Register oop_result,
Label L;
cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
jcc(Assembler::equal, L);
stop("InterpreterMacroAssembler::call_VM_leaf_base:"
stop("InterpreterMacroAssembler::call_VM_base:"
" last_sp != NULL");
bind(L);
}

View File

@ -1830,7 +1830,7 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) {
__ push(state); // save tosca
// pass tosca registers as arguments & call tracer
__ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), rcx, rax, rdx);
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode), rcx, rax, rdx);
__ mov(rcx, rax); // make sure return address is not destroyed by pop(state)
__ pop(state); // restore tosca
@ -1847,7 +1847,7 @@ address TemplateInterpreterGenerator::generate_trace_code(TosState state) {
__ movflt(xmm3, xmm0); // Pass ftos
#endif
__ call_VM(noreg,
CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode),
CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode),
c_rarg1, c_rarg2, c_rarg3);
__ pop(c_rarg3);
__ pop(c_rarg2);

View File

@ -138,11 +138,11 @@
BytecodeHistogram::_counters[(Bytecodes::Code)opcode]++; \
if (StopInterpreterAt && StopInterpreterAt == BytecodeCounter::_counter_value) os::breakpoint(); \
if (TraceBytecodes) { \
CALL_VM((void)SharedRuntime::trace_bytecode(THREAD, 0, \
topOfStack[Interpreter::expr_index_at(1)], \
topOfStack[Interpreter::expr_index_at(2)]), \
handle_exception); \
} \
CALL_VM((void)InterpreterRuntime::trace_bytecode(THREAD, 0, \
topOfStack[Interpreter::expr_index_at(1)], \
topOfStack[Interpreter::expr_index_at(2)]), \
handle_exception); \
} \
}
#endif

View File

@ -173,9 +173,6 @@ IRT_END
IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size))
// Note: no oopHandle for pool & klass needed since they are not used
// anymore after new_objArray() and no GC can happen before.
// (This may have to change if this code changes!)
Klass* klass = pool->klass_at(index, CHECK);
objArrayOop obj = oopFactory::new_objArray(klass, size, CHECK);
thread->set_vm_result(obj);
@ -1414,3 +1411,17 @@ IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread,
}
IRT_END
#endif // INCLUDE_JVMTI
#ifndef PRODUCT
// This must be a IRT_LEAF function because the interpreter must save registers on x86 to
// call this, which changes rsp and makes the interpreter's expression stack not walkable.
// The generated code still uses call_VM because that will set up the frame pointer for
// bcp and method.
IRT_LEAF(intptr_t, InterpreterRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
const frame f = thread->last_frame();
assert(f.is_interpreted_frame(), "must be an interpreted frame");
methodHandle mh(thread, f.interpreter_frame_method());
BytecodeTracer::trace(mh, f.interpreter_frame_bcp(), tos, tos2);
return preserve_this_value;
IRT_END
#endif // !PRODUCT

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -166,6 +166,9 @@ class InterpreterRuntime: AllStatic {
static void popframe_move_outgoing_args(JavaThread* thread, void* src_address, void* dest_address);
#endif
// bytecode tracing is only used by the TraceBytecodes
static intptr_t trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2) PRODUCT_RETURN0;
// Platform dependent stuff
#ifdef TARGET_ARCH_x86
# include "interpreterRT_x86.hpp"

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -991,19 +991,6 @@ address SharedRuntime::native_method_throw_unsatisfied_link_error_entry() {
return CAST_FROM_FN_PTR(address, &throw_unsatisfied_link_error);
}
#ifndef PRODUCT
JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
const frame f = thread->last_frame();
assert(f.is_interpreted_frame(), "must be an interpreted frame");
#ifndef PRODUCT
methodHandle mh(THREAD, f.interpreter_frame_method());
BytecodeTracer::trace(mh, f.interpreter_frame_bcp(), tos, tos2);
#endif // !PRODUCT
return preserve_this_value;
JRT_END
#endif // !PRODUCT
JRT_ENTRY_NO_ASYNC(void, SharedRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
assert(obj->is_oop(), "must be a valid oop");
#if INCLUDE_JVMCI

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -269,9 +269,6 @@ class SharedRuntime: AllStatic {
static address native_method_throw_unsatisfied_link_error_entry();
static address native_method_throw_unsupported_operation_exception_entry();
// bytecode tracing is only used by the TraceBytecodes
static intptr_t trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2) PRODUCT_RETURN0;
static oop retrieve_receiver(Symbol* sig, frame caller);
static void register_finalizer(JavaThread* thread, oopDesc* obj);