6939182: Zero JNI handles fix
Summary: Zero will exit with an error when invoked with -Xcheck:jni.
Reviewed-by: twisti, kamg
Contributed-by: Gary Benson <gbenson@redhat.com>
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Apr 29 17:53:58 2010 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri Apr 30 04:27:25 2010 -0700
@@ -833,7 +833,7 @@
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;
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp Thu Apr 29 17:53:58 2010 -0700
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp Fri Apr 30 04:27:25 2010 -0700
@@ -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 @@
"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 @@
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);
--- a/hotspot/src/cpu/zero/vm/frame_zero.hpp Thu Apr 29 17:53:58 2010 -0700
+++ b/hotspot/src/cpu/zero/vm/frame_zero.hpp Fri Apr 30 04:27:25 2010 -0700
@@ -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();
}
--- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Thu Apr 29 17:53:58 2010 -0700
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Fri Apr 30 04:27:25 2010 -0700
@@ -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 @@
// 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 @@
// 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 {
--- a/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp Thu Apr 29 17:53:58 2010 -0700
+++ b/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp Fri Apr 30 04:27:25 2010 -0700
@@ -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;
}
--- a/hotspot/src/cpu/zero/vm/stack_zero.cpp Thu Apr 29 17:53:58 2010 -0700
+++ b/hotspot/src/cpu/zero/vm/stack_zero.cpp Fri Apr 30 04:27:25 2010 -0700
@@ -32,6 +32,7 @@
// 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 @@
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 @@
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
--- a/hotspot/src/cpu/zero/vm/stack_zero.hpp Thu Apr 29 17:53:58 2010 -0700
+++ b/hotspot/src/cpu/zero/vm/stack_zero.hpp Fri Apr 30 04:27:25 2010 -0700
@@ -95,6 +95,9 @@
static void handle_overflow(TRAPS);
public:
+ void zap(int c) PRODUCT_RETURN;
+
+ public:
static ByteSize base_offset() {
return byte_offset_of(ZeroStack, _base);
}
--- a/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp Thu Apr 29 17:53:58 2010 -0700
+++ b/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp Fri Apr 30 04:27:25 2010 -0700
@@ -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* fp, intptr_t* sp) {
+ frame_anchor()->set(sp, NULL, fp);
}
- void set_last_Java_frame(ZeroFrame* frame) {
- frame_anchor()->set_last_Java_sp((intptr_t *) frame);
+
+ 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: