6951784: Zero deoptimizer changes
The way Zero currently handles deoptimization can lead to methods being freed while they are still being executed. Reviewed-by: twisti
This commit is contained in:
parent
71599d89d4
commit
b8491bb9fe
@ -37,15 +37,18 @@
|
||||
thread->reset_last_Java_frame(); \
|
||||
fixup_after_potential_safepoint()
|
||||
|
||||
void CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
int CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
JavaThread *thread = (JavaThread *) THREAD;
|
||||
|
||||
// Allocate and initialize our frame.
|
||||
InterpreterFrame *frame = InterpreterFrame::build(method, CHECK);
|
||||
InterpreterFrame *frame = InterpreterFrame::build(method, CHECK_0);
|
||||
thread->push_zero_frame(frame);
|
||||
|
||||
// Execute those bytecodes!
|
||||
main_loop(0, THREAD);
|
||||
|
||||
// No deoptimized frames on the stack
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CppInterpreter::main_loop(int recurse, TRAPS) {
|
||||
@ -165,7 +168,7 @@ void CppInterpreter::main_loop(int recurse, TRAPS) {
|
||||
stack->push(result[-i]);
|
||||
}
|
||||
|
||||
void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
int CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
// Make sure method is native and not abstract
|
||||
assert(method->is_native() && !method->is_abstract(), "should be");
|
||||
|
||||
@ -173,7 +176,7 @@ void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
ZeroStack *stack = thread->zero_stack();
|
||||
|
||||
// Allocate and initialize our frame
|
||||
InterpreterFrame *frame = InterpreterFrame::build(method, CHECK);
|
||||
InterpreterFrame *frame = InterpreterFrame::build(method, CHECK_0);
|
||||
thread->push_zero_frame(frame);
|
||||
interpreterState istate = frame->interpreter_state();
|
||||
intptr_t *locals = istate->locals();
|
||||
@ -430,25 +433,26 @@ void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
// No deoptimized frames on the stack
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
int CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
JavaThread *thread = (JavaThread *) THREAD;
|
||||
ZeroStack *stack = thread->zero_stack();
|
||||
intptr_t *locals = stack->sp();
|
||||
|
||||
// Drop into the slow path if we need a safepoint check
|
||||
if (SafepointSynchronize::do_call_back()) {
|
||||
normal_entry(method, 0, THREAD);
|
||||
return;
|
||||
return normal_entry(method, 0, THREAD);
|
||||
}
|
||||
|
||||
// Load the object pointer and drop into the slow path
|
||||
// if we have a NullPointerException
|
||||
oop object = LOCALS_OBJECT(0);
|
||||
if (object == NULL) {
|
||||
normal_entry(method, 0, THREAD);
|
||||
return;
|
||||
return normal_entry(method, 0, THREAD);
|
||||
}
|
||||
|
||||
// Read the field index from the bytecode, which looks like this:
|
||||
@ -470,15 +474,14 @@ void CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
constantPoolCacheOop cache = method->constants()->cache();
|
||||
ConstantPoolCacheEntry* entry = cache->entry_at(index);
|
||||
if (!entry->is_resolved(Bytecodes::_getfield)) {
|
||||
normal_entry(method, 0, THREAD);
|
||||
return;
|
||||
return normal_entry(method, 0, THREAD);
|
||||
}
|
||||
|
||||
// Get the result and push it onto the stack
|
||||
switch (entry->flag_state()) {
|
||||
case ltos:
|
||||
case dtos:
|
||||
stack->overflow_check(1, CHECK);
|
||||
stack->overflow_check(1, CHECK_0);
|
||||
stack->alloc(wordSize);
|
||||
break;
|
||||
}
|
||||
@ -558,20 +561,25 @@ void CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
// No deoptimized frames on the stack
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CppInterpreter::empty_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
int CppInterpreter::empty_entry(methodOop method, intptr_t UNUSED, TRAPS) {
|
||||
JavaThread *thread = (JavaThread *) THREAD;
|
||||
ZeroStack *stack = thread->zero_stack();
|
||||
|
||||
// Drop into the slow path if we need a safepoint check
|
||||
if (SafepointSynchronize::do_call_back()) {
|
||||
normal_entry(method, 0, THREAD);
|
||||
return;
|
||||
return normal_entry(method, 0, THREAD);
|
||||
}
|
||||
|
||||
// Pop our parameters
|
||||
stack->set_sp(stack->sp() + method->size_of_parameters());
|
||||
|
||||
// No deoptimized frames on the stack
|
||||
return 0;
|
||||
}
|
||||
|
||||
InterpreterFrame *InterpreterFrame::build(const methodOop method, TRAPS) {
|
||||
|
@ -29,10 +29,10 @@
|
||||
|
||||
public:
|
||||
// Method entries
|
||||
static void normal_entry(methodOop method, intptr_t UNUSED, TRAPS);
|
||||
static void native_entry(methodOop method, intptr_t UNUSED, TRAPS);
|
||||
static void accessor_entry(methodOop method, intptr_t UNUSED, TRAPS);
|
||||
static void empty_entry(methodOop method, intptr_t UNUSED, TRAPS);
|
||||
static int normal_entry(methodOop method, intptr_t UNUSED, TRAPS);
|
||||
static int native_entry(methodOop method, intptr_t UNUSED, TRAPS);
|
||||
static int accessor_entry(methodOop method, intptr_t UNUSED, TRAPS);
|
||||
static int empty_entry(methodOop method, intptr_t UNUSED, TRAPS);
|
||||
|
||||
public:
|
||||
// Main loop of normal_entry
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2008, 2009 Red Hat, Inc.
|
||||
* Copyright 2008, 2009, 2010 Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,20 +41,30 @@ class ZeroEntry {
|
||||
}
|
||||
|
||||
private:
|
||||
typedef void (*NormalEntryFunc)(methodOop method,
|
||||
intptr_t base_pc,
|
||||
TRAPS);
|
||||
typedef void (*OSREntryFunc)(methodOop method,
|
||||
address osr_buf,
|
||||
intptr_t base_pc,
|
||||
TRAPS);
|
||||
typedef int (*NormalEntryFunc)(methodOop method,
|
||||
intptr_t base_pc,
|
||||
TRAPS);
|
||||
typedef int (*OSREntryFunc)(methodOop method,
|
||||
address osr_buf,
|
||||
intptr_t base_pc,
|
||||
TRAPS);
|
||||
|
||||
public:
|
||||
void invoke(methodOop method, TRAPS) const {
|
||||
((NormalEntryFunc) entry_point())(method, (intptr_t) this, THREAD);
|
||||
maybe_deoptimize(
|
||||
((NormalEntryFunc) entry_point())(method, (intptr_t) this, THREAD),
|
||||
THREAD);
|
||||
}
|
||||
void invoke_osr(methodOop method, address osr_buf, TRAPS) const {
|
||||
((OSREntryFunc) entry_point())(method, osr_buf, (intptr_t) this, THREAD);
|
||||
maybe_deoptimize(
|
||||
((OSREntryFunc) entry_point())(method, osr_buf, (intptr_t) this, THREAD),
|
||||
THREAD);
|
||||
}
|
||||
|
||||
private:
|
||||
static void maybe_deoptimize(int deoptimized_frames, TRAPS) {
|
||||
if (deoptimized_frames)
|
||||
CppInterpreter::main_loop(deoptimized_frames - 1, THREAD);
|
||||
}
|
||||
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user