提交 f460abc5 编写于 作者: T twisti

6939182: Zero JNI handles fix

Summary: Zero will exit with an error when invoked with -Xcheck:jni.
Reviewed-by: twisti, kamg
Contributed-by: NGary Benson <gbenson@redhat.com>
上级 5358ec07
...@@ -833,7 +833,7 @@ int AbstractInterpreter::layout_activation(methodOop method, ...@@ -833,7 +833,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
int callee_extra_locals = callee_locals - callee_param_count; int callee_extra_locals = callee_locals - callee_param_count;
if (interpreter_frame) { 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(); interpreterState istate = interpreter_frame->get_interpreterState();
intptr_t *monitor_base = (intptr_t*) istate; intptr_t *monitor_base = (intptr_t*) istate;
intptr_t *stack_base = monitor_base - monitor_words; intptr_t *stack_base = monitor_base - monitor_words;
......
/* /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * 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. * 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
...@@ -44,14 +44,14 @@ frame frame::sender_for_entry_frame(RegisterMap *map) const { ...@@ -44,14 +44,14 @@ frame frame::sender_for_entry_frame(RegisterMap *map) const {
"sender should be next Java frame"); "sender should be next Java frame");
map->clear(); map->clear();
assert(map->include_argument_oops(), "should be set by 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 { frame frame::sender_for_nonentry_frame(RegisterMap *map) const {
assert(zeroframe()->is_interpreter_frame() || assert(zeroframe()->is_interpreter_frame() ||
zeroframe()->is_shark_frame() || zeroframe()->is_shark_frame() ||
zeroframe()->is_fake_stub_frame(), "wrong type of 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 { frame frame::sender(RegisterMap* map) const {
...@@ -172,8 +172,8 @@ void frame::zero_print_on_error(int frame_index, ...@@ -172,8 +172,8 @@ void frame::zero_print_on_error(int frame_index,
char *valuebuf = buf + buflen; char *valuebuf = buf + buflen;
// Print each word of the frame // Print each word of the frame
for (intptr_t *addr = fp(); addr <= sp(); addr++) { for (intptr_t *addr = sp(); addr <= fp(); addr++) {
int offset = sp() - addr; int offset = fp() - addr;
// Fill in default values, then try and improve them // Fill in default values, then try and improve them
snprintf(fieldbuf, buflen, "word[%d]", offset); snprintf(fieldbuf, buflen, "word[%d]", offset);
......
/* /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * 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. * 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
...@@ -32,17 +32,18 @@ ...@@ -32,17 +32,18 @@
// Constructor // Constructor
public: 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: private:
intptr_t* _fp; ZeroFrame* _zeroframe;
public: public:
const ZeroFrame *zeroframe() const {
return _zeroframe;
}
intptr_t* fp() const { intptr_t* fp() const {
return _fp; return (intptr_t *) zeroframe();
} }
#ifdef CC_INTERP #ifdef CC_INTERP
...@@ -50,10 +51,6 @@ ...@@ -50,10 +51,6 @@
#endif // CC_INTERP #endif // CC_INTERP
public: public:
const ZeroFrame *zeroframe() const {
return (ZeroFrame *) sp();
}
const EntryFrame *zero_entryframe() const { const EntryFrame *zero_entryframe() const {
return zeroframe()->as_entry_frame(); return zeroframe()->as_entry_frame();
} }
......
/* /*
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. * 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. * 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
...@@ -26,16 +26,16 @@ ...@@ -26,16 +26,16 @@
// Constructors // Constructors
inline frame::frame() { inline frame::frame() {
_zeroframe = NULL;
_sp = NULL; _sp = NULL;
_fp = NULL;
_pc = NULL; _pc = NULL;
_cb = NULL; _cb = NULL;
_deopt_state = unknown; _deopt_state = unknown;
} }
inline frame::frame(intptr_t* sp, intptr_t* fp) { inline frame::frame(ZeroFrame* zf, intptr_t* sp) {
_zeroframe = zf;
_sp = sp; _sp = sp;
_fp = fp;
switch (zeroframe()->type()) { switch (zeroframe()->type()) {
case ZeroFrame::ENTRY_FRAME: case ZeroFrame::ENTRY_FRAME:
_pc = StubRoutines::call_stub_return_pc(); _pc = StubRoutines::call_stub_return_pc();
...@@ -66,7 +66,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) { ...@@ -66,7 +66,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) {
// Accessors // Accessors
inline intptr_t* frame::sender_sp() const { inline intptr_t* frame::sender_sp() const {
return (intptr_t *) zeroframe()->next(); return fp() + 1;
} }
inline intptr_t* frame::link() const { inline intptr_t* frame::link() const {
...@@ -120,7 +120,7 @@ inline jint frame::interpreter_frame_expression_stack_direction() { ...@@ -120,7 +120,7 @@ inline jint frame::interpreter_frame_expression_stack_direction() {
// we can distinguish identity and younger/older relationship. NULL // we can distinguish identity and younger/older relationship. NULL
// represents an invalid (incomparable) frame. // represents an invalid (incomparable) frame.
inline intptr_t* frame::id() const { inline intptr_t* frame::id() const {
return sp(); return fp();
} }
inline JavaCallWrapper* frame::entry_frame_call_wrapper() const { inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
......
/* /*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. * 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. * 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
...@@ -23,21 +23,31 @@ ...@@ -23,21 +23,31 @@
* *
*/ */
private:
ZeroFrame* volatile _last_Java_fp;
public: public:
// Each arch must define reset, save, restore // Each arch must define reset, save, restore
// These are used by objects that only care about: // These are used by objects that only care about:
// 1 - initializing a new state (thread creation, javaCalls) // 1 - initializing a new state (thread creation, javaCalls)
// 2 - saving a current state (javaCalls) // 2 - saving a current state (javaCalls)
// 3 - restoring an old 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() { void clear() {
// clearing _last_Java_sp must be first // clearing _last_Java_sp must be first
_last_Java_sp = NULL; _last_Java_sp = NULL;
// fence? // fence?
_last_Java_fp = NULL;
_last_Java_pc = NULL; _last_Java_pc = NULL;
} }
void copy(JavaFrameAnchor* src) { 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" // 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 // We must clear _last_Java_sp before copying the rest of the new
// data // data
...@@ -46,13 +56,14 @@ ...@@ -46,13 +56,14 @@
// previous version (pd_cache_state) don't NULL _last_Java_sp // previous version (pd_cache_state) don't NULL _last_Java_sp
// unless the value is changing // unless the value is changing
// //
if (_last_Java_sp != src->_last_Java_sp) if (_last_Java_sp != sp)
_last_Java_sp = NULL; _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 // Must be last so profiler will always see valid frame if
// has_last_frame() is true // has_last_frame() is true
_last_Java_sp = src->_last_Java_sp; _last_Java_sp = sp;
} }
bool walkable() { bool walkable() {
...@@ -67,6 +78,6 @@ ...@@ -67,6 +78,6 @@
return _last_Java_sp; return _last_Java_sp;
} }
void set_last_Java_sp(intptr_t* sp) { ZeroFrame* last_Java_fp() const {
_last_Java_sp = sp; return _last_Java_fp;
} }
...@@ -32,6 +32,7 @@ void ZeroStack::handle_overflow(TRAPS) { ...@@ -32,6 +32,7 @@ void ZeroStack::handle_overflow(TRAPS) {
// Set up the frame anchor if it isn't already // Set up the frame anchor if it isn't already
bool has_last_Java_frame = thread->has_last_Java_frame(); bool has_last_Java_frame = thread->has_last_Java_frame();
if (!has_last_Java_frame) { if (!has_last_Java_frame) {
intptr_t *sp = thread->zero_stack()->sp();
ZeroFrame *frame = thread->top_zero_frame(); ZeroFrame *frame = thread->top_zero_frame();
while (frame) { while (frame) {
if (frame->is_shark_frame()) if (frame->is_shark_frame())
...@@ -44,13 +45,14 @@ void ZeroStack::handle_overflow(TRAPS) { ...@@ -44,13 +45,14 @@ void ZeroStack::handle_overflow(TRAPS) {
break; break;
} }
sp = ((intptr_t *) frame) + 1;
frame = frame->next(); frame = frame->next();
} }
if (frame == NULL) if (frame == NULL)
fatal("unrecoverable stack overflow"); fatal("unrecoverable stack overflow");
thread->set_last_Java_frame(frame); thread->set_last_Java_frame(frame, sp);
} }
// Throw the exception // Throw the exception
...@@ -71,3 +73,9 @@ void ZeroStack::handle_overflow(TRAPS) { ...@@ -71,3 +73,9 @@ void ZeroStack::handle_overflow(TRAPS) {
if (!has_last_Java_frame) if (!has_last_Java_frame)
thread->reset_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 { ...@@ -94,6 +94,9 @@ class ZeroStack {
void overflow_check(int required_words, TRAPS); void overflow_check(int required_words, TRAPS);
static void handle_overflow(TRAPS); static void handle_overflow(TRAPS);
public:
void zap(int c) PRODUCT_RETURN;
public: public:
static ByteSize base_offset() { static ByteSize base_offset() {
return byte_offset_of(ZeroStack, _base); return byte_offset_of(ZeroStack, _base);
......
...@@ -68,19 +68,24 @@ ...@@ -68,19 +68,24 @@
public: public:
void set_last_Java_frame() { 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() { void reset_last_Java_frame() {
set_last_Java_frame(NULL); frame_anchor()->zap();
} }
void set_last_Java_frame(ZeroFrame* frame) { void set_last_Java_frame(ZeroFrame* fp, intptr_t* sp) {
frame_anchor()->set_last_Java_sp((intptr_t *) frame); frame_anchor()->set(sp, NULL, fp);
}
public:
ZeroFrame* last_Java_fp() {
return frame_anchor()->last_Java_fp();
} }
private: private:
frame pd_last_frame() { frame pd_last_frame() {
assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); 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: public:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册