6939182: Zero JNI handles fix
Zero will exit with an error when invoked with -Xcheck:jni. Reviewed-by: twisti, kamg
This commit is contained in:
parent
61b9d428d1
commit
55457c9cc7
@ -833,7 +833,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
||||
int callee_extra_locals = callee_locals - callee_param_count;
|
||||
|
||||
if (interpreter_frame) {
|
||||
intptr_t *locals = interpreter_frame->sp() + method->max_locals();
|
||||
intptr_t *locals = interpreter_frame->fp() + method->max_locals();
|
||||
interpreterState istate = interpreter_frame->get_interpreterState();
|
||||
intptr_t *monitor_base = (intptr_t*) istate;
|
||||
intptr_t *stack_base = monitor_base - monitor_words;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2007, 2008, 2009 Red Hat, Inc.
|
||||
* Copyright 2007, 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
|
||||
@ -44,14 +44,14 @@ frame frame::sender_for_entry_frame(RegisterMap *map) const {
|
||||
"sender should be next Java frame");
|
||||
map->clear();
|
||||
assert(map->include_argument_oops(), "should be set by clear");
|
||||
return frame(sender_sp(), sp() + 1);
|
||||
return frame(zeroframe()->next(), sender_sp());
|
||||
}
|
||||
|
||||
frame frame::sender_for_nonentry_frame(RegisterMap *map) const {
|
||||
assert(zeroframe()->is_interpreter_frame() ||
|
||||
zeroframe()->is_shark_frame() ||
|
||||
zeroframe()->is_fake_stub_frame(), "wrong type of frame");
|
||||
return frame(sender_sp(), sp() + 1);
|
||||
return frame(zeroframe()->next(), sender_sp());
|
||||
}
|
||||
|
||||
frame frame::sender(RegisterMap* map) const {
|
||||
@ -172,8 +172,8 @@ void frame::zero_print_on_error(int frame_index,
|
||||
char *valuebuf = buf + buflen;
|
||||
|
||||
// Print each word of the frame
|
||||
for (intptr_t *addr = fp(); addr <= sp(); addr++) {
|
||||
int offset = sp() - addr;
|
||||
for (intptr_t *addr = sp(); addr <= fp(); addr++) {
|
||||
int offset = fp() - addr;
|
||||
|
||||
// Fill in default values, then try and improve them
|
||||
snprintf(fieldbuf, buflen, "word[%d]", offset);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2007, 2008, 2009 Red Hat, Inc.
|
||||
* Copyright 2007, 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
|
||||
@ -32,17 +32,18 @@
|
||||
|
||||
// Constructor
|
||||
public:
|
||||
frame(intptr_t* sp, intptr_t* fp);
|
||||
frame(ZeroFrame* zeroframe, intptr_t* sp);
|
||||
|
||||
// The sp of a Zero frame is the address of the highest word in
|
||||
// that frame. We keep track of the lowest address too, so the
|
||||
// boundaries of the frame are available for debug printing.
|
||||
private:
|
||||
intptr_t* _fp;
|
||||
ZeroFrame* _zeroframe;
|
||||
|
||||
public:
|
||||
const ZeroFrame *zeroframe() const {
|
||||
return _zeroframe;
|
||||
}
|
||||
|
||||
intptr_t* fp() const {
|
||||
return _fp;
|
||||
return (intptr_t *) zeroframe();
|
||||
}
|
||||
|
||||
#ifdef CC_INTERP
|
||||
@ -50,10 +51,6 @@
|
||||
#endif // CC_INTERP
|
||||
|
||||
public:
|
||||
const ZeroFrame *zeroframe() const {
|
||||
return (ZeroFrame *) sp();
|
||||
}
|
||||
|
||||
const EntryFrame *zero_entryframe() const {
|
||||
return zeroframe()->as_entry_frame();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2007, 2008, 2009 Red Hat, Inc.
|
||||
* Copyright 2007, 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
|
||||
@ -26,16 +26,16 @@
|
||||
// Constructors
|
||||
|
||||
inline frame::frame() {
|
||||
_zeroframe = NULL;
|
||||
_sp = NULL;
|
||||
_fp = NULL;
|
||||
_pc = NULL;
|
||||
_cb = NULL;
|
||||
_deopt_state = unknown;
|
||||
}
|
||||
|
||||
inline frame::frame(intptr_t* sp, intptr_t* fp) {
|
||||
inline frame::frame(ZeroFrame* zf, intptr_t* sp) {
|
||||
_zeroframe = zf;
|
||||
_sp = sp;
|
||||
_fp = fp;
|
||||
switch (zeroframe()->type()) {
|
||||
case ZeroFrame::ENTRY_FRAME:
|
||||
_pc = StubRoutines::call_stub_return_pc();
|
||||
@ -66,7 +66,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) {
|
||||
// Accessors
|
||||
|
||||
inline intptr_t* frame::sender_sp() const {
|
||||
return (intptr_t *) zeroframe()->next();
|
||||
return fp() + 1;
|
||||
}
|
||||
|
||||
inline intptr_t* frame::link() const {
|
||||
@ -120,7 +120,7 @@ inline jint frame::interpreter_frame_expression_stack_direction() {
|
||||
// we can distinguish identity and younger/older relationship. NULL
|
||||
// represents an invalid (incomparable) frame.
|
||||
inline intptr_t* frame::id() const {
|
||||
return sp();
|
||||
return fp();
|
||||
}
|
||||
|
||||
inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2007, 2008 Red Hat, Inc.
|
||||
* Copyright 2007, 2008, 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
|
||||
@ -23,21 +23,31 @@
|
||||
*
|
||||
*/
|
||||
|
||||
private:
|
||||
ZeroFrame* volatile _last_Java_fp;
|
||||
|
||||
public:
|
||||
// Each arch must define reset, save, restore
|
||||
// These are used by objects that only care about:
|
||||
// 1 - initializing a new state (thread creation, javaCalls)
|
||||
// 2 - saving a current state (javaCalls)
|
||||
// 3 - restoring an old state (javaCalls)
|
||||
// Note that whenever _last_Java_sp != NULL other anchor fields
|
||||
// must be valid. The profiler apparently depends on this.
|
||||
|
||||
void clear() {
|
||||
// clearing _last_Java_sp must be first
|
||||
_last_Java_sp = NULL;
|
||||
// fence?
|
||||
_last_Java_fp = NULL;
|
||||
_last_Java_pc = NULL;
|
||||
}
|
||||
|
||||
void copy(JavaFrameAnchor* src) {
|
||||
set(src->_last_Java_sp, src->_last_Java_pc, src->_last_Java_fp);
|
||||
}
|
||||
|
||||
void set(intptr_t* sp, address pc, ZeroFrame* fp) {
|
||||
// In order to make sure the transition state is valid for "this"
|
||||
// We must clear _last_Java_sp before copying the rest of the new
|
||||
// data
|
||||
@ -46,13 +56,14 @@
|
||||
// previous version (pd_cache_state) don't NULL _last_Java_sp
|
||||
// unless the value is changing
|
||||
//
|
||||
if (_last_Java_sp != src->_last_Java_sp)
|
||||
if (_last_Java_sp != sp)
|
||||
_last_Java_sp = NULL;
|
||||
|
||||
_last_Java_pc = src->_last_Java_pc;
|
||||
_last_Java_fp = fp;
|
||||
_last_Java_pc = pc;
|
||||
// Must be last so profiler will always see valid frame if
|
||||
// has_last_frame() is true
|
||||
_last_Java_sp = src->_last_Java_sp;
|
||||
_last_Java_sp = sp;
|
||||
}
|
||||
|
||||
bool walkable() {
|
||||
@ -67,6 +78,6 @@
|
||||
return _last_Java_sp;
|
||||
}
|
||||
|
||||
void set_last_Java_sp(intptr_t* sp) {
|
||||
_last_Java_sp = sp;
|
||||
ZeroFrame* last_Java_fp() const {
|
||||
return _last_Java_fp;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ void ZeroStack::handle_overflow(TRAPS) {
|
||||
// Set up the frame anchor if it isn't already
|
||||
bool has_last_Java_frame = thread->has_last_Java_frame();
|
||||
if (!has_last_Java_frame) {
|
||||
intptr_t *sp = thread->zero_stack()->sp();
|
||||
ZeroFrame *frame = thread->top_zero_frame();
|
||||
while (frame) {
|
||||
if (frame->is_shark_frame())
|
||||
@ -44,13 +45,14 @@ void ZeroStack::handle_overflow(TRAPS) {
|
||||
break;
|
||||
}
|
||||
|
||||
sp = ((intptr_t *) frame) + 1;
|
||||
frame = frame->next();
|
||||
}
|
||||
|
||||
if (frame == NULL)
|
||||
fatal("unrecoverable stack overflow");
|
||||
|
||||
thread->set_last_Java_frame(frame);
|
||||
thread->set_last_Java_frame(frame, sp);
|
||||
}
|
||||
|
||||
// Throw the exception
|
||||
@ -71,3 +73,9 @@ void ZeroStack::handle_overflow(TRAPS) {
|
||||
if (!has_last_Java_frame)
|
||||
thread->reset_last_Java_frame();
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void ZeroStack::zap(int c) {
|
||||
memset(_base, c, available_words() * wordSize);
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
@ -94,6 +94,9 @@ class ZeroStack {
|
||||
void overflow_check(int required_words, TRAPS);
|
||||
static void handle_overflow(TRAPS);
|
||||
|
||||
public:
|
||||
void zap(int c) PRODUCT_RETURN;
|
||||
|
||||
public:
|
||||
static ByteSize base_offset() {
|
||||
return byte_offset_of(ZeroStack, _base);
|
||||
|
@ -68,19 +68,24 @@
|
||||
|
||||
public:
|
||||
void set_last_Java_frame() {
|
||||
set_last_Java_frame(top_zero_frame());
|
||||
set_last_Java_frame(top_zero_frame(), zero_stack()->sp());
|
||||
}
|
||||
void reset_last_Java_frame() {
|
||||
set_last_Java_frame(NULL);
|
||||
frame_anchor()->zap();
|
||||
}
|
||||
void set_last_Java_frame(ZeroFrame* frame) {
|
||||
frame_anchor()->set_last_Java_sp((intptr_t *) frame);
|
||||
void set_last_Java_frame(ZeroFrame* fp, intptr_t* sp) {
|
||||
frame_anchor()->set(sp, NULL, fp);
|
||||
}
|
||||
|
||||
public:
|
||||
ZeroFrame* last_Java_fp() {
|
||||
return frame_anchor()->last_Java_fp();
|
||||
}
|
||||
|
||||
private:
|
||||
frame pd_last_frame() {
|
||||
assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
|
||||
return frame(last_Java_sp(), zero_stack()->sp());
|
||||
return frame(last_Java_fp(), last_Java_sp());
|
||||
}
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user