Updated Zero and Shark; disabled ARM interpreter
Gary Benson
gbenson at redhat.com
Mon May 10 03:48:08 PDT 2010
Hi all,
After discussing this with xranby and doko on IRC it was decided to
commit the Zero and Shark update and to disable the ARM interpreter
until it is updated.
This commit fixes PR icedtea/323, and updates Shark to use the new
stack overflow detection code that was committed to Zero on Friday.
Cheers,
Gary
Gary Benson wrote:
> Hi all,
>
> Building on my commit of this morning, this patch adds the new frame
> anchor code to Zero and Shark to fix PR icedtea/323. It also updates
> Shark to use the new stack overflow code that Zero now has.
>
> Committing this will break the ARM interpreter, which needs updating.
> Currently last_Java_sp is set to the address of the top Zero frame
> wherever the frame anchor is set up. It needs changing such that
> last_Java_sp is set to the thread->zero_stack()->sp() (and the new
> field last_Java_fp gets set to what last_Java_sp used to be set to).
>
> There is a deoptimizer sefault (PR icedtea/484) which cannot be
> applied to icedtea6 until this patch is applied. That change will
> also require work on the ARM interpreter. I've kept that separate
> from this commit so as not to break two things at once.
>
> What are people's opinions on this? Should I commit now, or should
> I wait? I guess I need to hear from Ed (unless anybody else is able
> to make the ARM interpreter changes?)
>
> Cheers,
> Gary
>
> --
> http://gbenson.net/
-------------- next part --------------
diff -r 373a443db017 ChangeLog
--- a/ChangeLog Fri May 07 16:57:27 2010 -0400
+++ b/ChangeLog Mon May 10 11:43:10 2010 +0100
@@ -1,3 +1,83 @@
+2010-05-10 Gary Benson <gbenson at redhat.com>
+
+ PR icedtea/323
+ * ports/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp
+ (JavaFrameAnchor::_last_Java_fp): New field.
+ (JavaFrameAnchor::clear): Also clear the above.
+ (JavaFrameAnchor::set): New method.
+ (JavaFrameAnchor::copy): Use the above.
+ (JavaFrameAnchor::set_lat_Java_sp): Removed.
+ (JavaFrameAnchor::last_Java_fp): New method.
+ (JavaFrameAnchor::last_Java_fp_offset): Likewise.
+ * ports/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp
+ (JavaThread::last_Java_fp): Likewise.
+ (JavaThread::last_Java_fp_offset): Likewise.
+ (JavaThread::set_last_Java_frame): Use new new frame anchor code.
+ (JavaThread::reset_last_Java_frame): Likewise.
+ (JavaThread::pd_last_frame): Likewise.
+ * ports/hotspot/src/cpu/zero/vm/frame_zero.hpp
+ (frame::frame): Flipped arguments.
+ (frame::_fp): Replaced with...
+ (frame::_zeroframe): New field.
+ (frame::fp): Updated.
+ (frame::zeroframe): Likewise.
+ * ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp
+ (frame::frame): Likewise.
+ (frame::sender_sp): Likewise.
+ (frame::id): Likewise.
+ * ports/hotspot/src/cpu/zero/vm/frame_zero.cpp
+ (frame::sender_for_entry_frame): Likewise.
+ (frame::sender_for_nonentry_frame): Likewise.
+ (frame::zero_print_on_error): Likewise.
+ * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
+ (AbstractInterpreter::layout_activation): Use new frame
+ anchor code.
+
+ * ports/hotspot/src/cpu/zero/vm/stack_zero.hpp
+ (ZeroStack::suggest_size): New method.
+ (ZeroStack::total_words): Likewise.
+ (ZeroStack::abi_stack_available): Likewise.
+ (ZeroStack::zap): Likewise.
+ * ports/hotspot/src/cpu/zero/vm/stack_zero.inline.hpp
+ (ZeroStack::abi_stack_available): New method.
+ (ZeroStack::overflow_check): Use the above.
+ * ports/hotspot/src/cpu/zero/vm/stack_zero.cpp
+ (ZeroStack::suggest_size): New method.
+ (ZeroStack::zap): Likewise.
+ (ZeroStack::handle_overflow): Use new frame anchor code.
+ * ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp
+ (StubGenerator::call_stub): Use ZeroStack::suggest_size.
+
+ * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp
+ (SharkBuilder::throw_StackOverflowError): New method.
+ * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp
+ (SharkBuilder::throw_StackOverflowError): Likewise.
+ * ports/hotspot/src/share/vm/shark/sharkStack.hpp
+ (SharkStack::initialize): Removed argument.
+ (SharkStack::CreateStackOverflowCheck): Updated.
+ (SharkStack::CreateCheckStack): Removed method.
+ (SharkStack::frame_anchor_addr): Likewise.
+ (SharkStack::last_Java_sp_addr): New method.
+ (SharkStack::last_Java_fp_addr): New method.
+ (SharkStack::CreateSetLastJavaFrame): Use new frame anchor code.
+ (SharkStack::CreateResetLastJavaFrame): Likewise.
+ (SharkStack::CreateAssertLastJavaSPIsNull): New method.
+ * ports/hotspot/src/share/vm/shark/sharkStack.cpp
+ (SharkStack::initialize): Updated for new stack overflow code.
+ (SharkStack::CreateStackOverflowCheck): Likewise.
+ (SharkStack::CreateCheckStack): Removed.
+ (SharkStackWithNormalFrame::SharkStackWithNormalFrame): Updated
+ for new stack overflow code.
+ (SharkStackWithNativeFrame::SharkStackWithNativeFrame): Likewise.
+ (SharkStack::CreateAssertLastJavaSPIsNull): New method.
+
+ * ports/hotspot/make/linux/makefiles/zeroshark.make
+ (CFLAGS): Remove -DHOTSPOT_ASM until the ARM interpreter
+ and JIT are updated to use the new frame anchor code.
+
+ * ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp
+ (SharkNativeWrapper::initialize): Whitespace fix.
+
2010-05-07 Deepak Bhole <dbhole at redhat.com>
* plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
diff -r 373a443db017 ports/hotspot/make/linux/makefiles/zeroshark.make
--- a/ports/hotspot/make/linux/makefiles/zeroshark.make Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/make/linux/makefiles/zeroshark.make Mon May 10 11:43:10 2010 +0100
@@ -31,7 +31,8 @@
Obj_Files += cppInterpreter_arm.o
Obj_Files += thumb2.o
-CFLAGS += -DHOTSPOT_ASM
+#XXX disabled until it has the updated frame anchor code
+#CFLAGS += -DHOTSPOT_ASM
%.o: %.S
@echo Assembling $<
diff -r 373a443db017 ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Mon May 10 11:43:10 2010 +0100
@@ -840,7 +840,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;
diff -r 373a443db017 ports/hotspot/src/cpu/zero/vm/frame_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.cpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.cpp Mon May 10 11:43:10 2010 +0100
@@ -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
@@ -48,14 +48,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 {
@@ -176,8 +176,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);
diff -r 373a443db017 ports/hotspot/src/cpu/zero/vm/frame_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.hpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.hpp Mon May 10 11:43:10 2010 +0100
@@ -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();
}
diff -r 373a443db017 ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Mon May 10 11:43:10 2010 +0100
@@ -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 {
diff -r 373a443db017 ports/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp Mon May 10 11:43:10 2010 +0100
@@ -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,10 @@
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;
}
+
+ static ByteSize last_Java_fp_offset() {
+ return byte_offset_of(JavaFrameAnchor, _last_Java_fp);
+ }
diff -r 373a443db017 ports/hotspot/src/cpu/zero/vm/stack_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/stack_zero.cpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.cpp Mon May 10 11:43:10 2010 +0100
@@ -26,12 +26,18 @@
#include "incls/_precompiled.incl"
#include "incls/_stack_zero.cpp.incl"
+int ZeroStack::suggest_size(Thread *thread) const {
+ assert(needs_setup(), "already set up");
+ return align_size_down(abi_stack_available(thread) / 2, wordSize);
+}
+
void ZeroStack::handle_overflow(TRAPS) {
JavaThread *thread = (JavaThread *) THREAD;
// 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 +50,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 +78,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
diff -r 373a443db017 ports/hotspot/src/cpu/zero/vm/stack_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp Mon May 10 11:43:10 2010 +0100
@@ -42,6 +42,8 @@
return _base == NULL;
}
+ int suggest_size(Thread *thread) const;
+
void setup(void *mem, size_t size) {
assert(needs_setup(), "already set up");
assert(!(size & WordAlignmentMask), "unaligned");
@@ -67,6 +69,9 @@
_sp = new_sp;
}
+ int total_words() const {
+ return _top - _base;
+ }
int available_words() const {
return _sp - _base;
}
@@ -89,12 +94,16 @@
int shadow_pages_size() const {
return _shadow_pages_size;
}
+ int abi_stack_available(Thread *thread) const;
public:
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);
}
diff -r 373a443db017 ports/hotspot/src/cpu/zero/vm/stack_zero.inline.hpp
--- a/ports/hotspot/src/cpu/zero/vm/stack_zero.inline.hpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.inline.hpp Mon May 10 11:43:10 2010 +0100
@@ -25,19 +25,24 @@
// This function should match SharkStack::CreateStackOverflowCheck
inline void ZeroStack::overflow_check(int required_words, TRAPS) {
- JavaThread *thread = (JavaThread *) THREAD;
-
// Check the Zero stack
- if (required_words > available_words()) {
+ if (available_words() < required_words) {
handle_overflow(THREAD);
return;
}
// Check the ABI stack
- address stack_top = thread->stack_base() - thread->stack_size();
- int free_stack = ((address) &stack_top) - stack_top;
- if (free_stack < shadow_pages_size()) {
+ if (abi_stack_available(THREAD) < 0) {
handle_overflow(THREAD);
return;
}
}
+
+// This method returns the amount of ABI stack available for us
+// to use under normal circumstances. Note that the returned
+// value can be negative.
+inline int ZeroStack::abi_stack_available(Thread *thread) const {
+ int stack_used = thread->stack_base() - (address) &stack_used;
+ int stack_free = thread->stack_size() - stack_used;
+ return stack_free - shadow_pages_size();
+}
diff -r 373a443db017 ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Mon May 10 11:43:10 2010 +0100
@@ -51,10 +51,7 @@
// Set up the stack if necessary
bool stack_needs_teardown = false;
if (stack->needs_setup()) {
- size_t stack_used = thread->stack_base() - (address) &stack_used;
- size_t stack_free = thread->stack_size() - stack_used;
- size_t zero_stack_size = align_size_down(stack_free / 2, wordSize);
-
+ size_t zero_stack_size = stack->suggest_size(thread);
stack->setup(alloca(zero_stack_size), zero_stack_size);
stack_needs_teardown = true;
}
diff -r 373a443db017 ports/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp
--- a/ports/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp Mon May 10 11:43:10 2010 +0100
@@ -68,19 +68,30 @@
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:
+ static ByteSize last_Java_fp_offset() {
+ return byte_offset_of(JavaThread, _anchor) +
+ JavaFrameAnchor::last_Java_fp_offset();
}
public:
diff -r 373a443db017 ports/hotspot/src/share/vm/shark/sharkBuilder.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Mon May 10 11:43:10 2010 +0100
@@ -319,13 +319,17 @@
return make_function((address) SharedRuntime::OSR_migration_end, "C", "v");
}
-// Uncommon trap
+// Semi-VM calls
+
+Value* SharkBuilder::throw_StackOverflowError() {
+ return make_function((address) ZeroStack::handle_overflow, "T", "v");
+}
Value* SharkBuilder::uncommon_trap() {
return make_function((address) SharkRuntime::uncommon_trap, "Ti", "v");
}
-// Native-Java transition.
+// Native-Java transition
Value* SharkBuilder::check_special_condition_for_native_trans() {
return make_function(
diff -r 373a443db017 ports/hotspot/src/share/vm/shark/sharkBuilder.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Mon May 10 11:43:10 2010 +0100
@@ -125,12 +125,13 @@
llvm::Value* unsafe_field_offset_to_byte_offset();
llvm::Value* osr_migration_end();
- // Intrinsics and external functions, part 3: Uncommon trap.
- // This is a special case in that it is invoked like a non-VM
- // call but it does VM call stuff. This is acceptable so long
- // as the method that calls uncommon_trap returns to its caller
- // immediately that uncommon_trap returns.
+ // Intrinsics and external functions, part 3: semi-VM calls.
+ // These are special cases that do VM call stuff but are invoked
+ // as though they were normal calls. This is acceptable so long
+ // as the method that calls them returns to its immediately that
+ // the semi VM call returns.
public:
+ llvm::Value* throw_StackOverflowError();
llvm::Value* uncommon_trap();
// Intrinsics and external functions, part 4: Native-Java transition.
diff -r 373a443db017 ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Mon May 10 11:43:10 2010 +0100
@@ -99,7 +99,7 @@
builder()->CreateStore(
builder()->CreateInlineOop(
JNIHandles::make_local(
- target()->method_holder()->klass_part()->java_mirror())),
+ target()->method_holder()->klass_part()->java_mirror())),
oop_tmp_slot());
param_types.push_back(box_type);
diff -r 373a443db017 ports/hotspot/src/share/vm/shark/sharkStack.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkStack.cpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkStack.cpp Mon May 10 11:43:10 2010 +0100
@@ -28,7 +28,9 @@
using namespace llvm;
-void SharkStack::initialize(Value* method, bool setup_sp_and_method) {
+void SharkStack::initialize(Value* method) {
+ bool setup_sp_and_method = (method != NULL);
+
int locals_words = max_locals();
int extra_locals = locals_words - arg_size();
int header_words = SharkFrame::header_words;
@@ -42,7 +44,7 @@
Value *stack_pointer = builder()->CreateSub(
CreateLoadStackPointer(),
LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize));
- CreateStackOverflowCheck(stack_pointer, method);
+ CreateStackOverflowCheck(stack_pointer);
if (setup_sp_and_method)
CreateStoreStackPointer(stack_pointer);
@@ -94,61 +96,48 @@
builder()->CreatePtrToInt(fp, SharkType::intptr_type()));
}
-// Check that a stack overflow is not imminent, bailing to the
-// interpreter to throw a StackOverflowError if one is while
-// we still have some stack left to do it with. This function
-// should mirror CppInterpreter::stack_overflow_imminent.
-void SharkStack::CreateStackOverflowCheck(Value* sp, Value* method) {
- BasicBlock *overflow = CreateBlock("overflow_imminent");
+// This function should match ZeroStack::overflow_check
+void SharkStack::CreateStackOverflowCheck(Value* sp) {
+ BasicBlock *zero_ok = CreateBlock("zero_stack_ok");
+ BasicBlock *overflow = CreateBlock("stack_overflow");
BasicBlock *abi_ok = CreateBlock("abi_stack_ok");
- BasicBlock *zero_ok = CreateBlock("zero_stack_ok");
+
+ // Check the Zero stack
+ builder()->CreateCondBr(
+ builder()->CreateICmpULT(sp, stack_base()),
+ overflow, zero_ok);
// Check the ABI stack
- CreateCheckStack(
- builder()->CreateSub(
- builder()->CreateValueOfStructEntry(
- thread(),
- Thread::stack_base_offset(),
- SharkType::intptr_type(),
- "abi_base"),
- builder()->CreateValueOfStructEntry(
- thread(),
- Thread::stack_size_offset(),
- SharkType::intptr_type(),
- "abi_size")),
+ builder()->SetInsertPoint(zero_ok);
+ Value *stack_top = builder()->CreateSub(
+ builder()->CreateValueOfStructEntry(
+ thread(),
+ Thread::stack_base_offset(),
+ SharkType::intptr_type(),
+ "abi_base"),
+ builder()->CreateValueOfStructEntry(
+ thread(),
+ Thread::stack_size_offset(),
+ SharkType::intptr_type(),
+ "abi_size"));
+ Value *free_stack = builder()->CreateSub(
builder()->CreatePtrToInt(
builder()->CreateGetFrameAddress(),
SharkType::intptr_type(),
- "abi_pointer"),
+ "abi_sp"),
+ stack_top);
+ builder()->CreateCondBr(
+ builder()->CreateICmpULT(
+ free_stack,
+ LLVMValue::intptr_constant(StackShadowPages * os::vm_page_size())),
overflow, abi_ok);
- // Check the Zero stack
- builder()->SetInsertPoint(abi_ok);
- CreateCheckStack(stack_base(), sp, overflow, zero_ok);
-
- // Bail to the interpreter if an overflow is imminent
+ // Handle overflows
builder()->SetInsertPoint(overflow);
- builder()->CreateCall3(
- builder()->CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) interpreter_entry_point()),
- PointerType::getUnqual(SharkType::entry_point_type())),
- method,
- LLVMValue::intptr_constant(0),
- thread());
+ builder()->CreateCall(builder()->throw_StackOverflowError(), thread());
builder()->CreateRetVoid();
- builder()->SetInsertPoint(zero_ok);
-}
-
-void SharkStack::CreateCheckStack(Value* base,
- Value* sp,
- BasicBlock* overflow,
- BasicBlock* no_overflow) {
- builder()->CreateCondBr(
- builder()->CreateICmpULT(
- builder()->CreateSub(sp, base),
- LLVMValue::intptr_constant(StackShadowPages * os::vm_page_size())),
- overflow, no_overflow);
+ builder()->SetInsertPoint(abi_ok);
}
Value* SharkStack::CreatePopFrame(int result_slots) {
@@ -202,12 +191,12 @@
// be set during each decache, so it is not necessary to do them
// at the time the frame is created. However, we set them for
// non-PRODUCT builds to make crash dumps easier to understand.
- initialize(method, NOT_PRODUCT(true) PRODUCT_ONLY(false));
+ initialize(PRODUCT_ONLY(NULL) NOT_PRODUCT(method));
}
SharkStackWithNativeFrame::SharkStackWithNativeFrame(SharkNativeWrapper* wrp,
Value* method)
: SharkStack(wrp), _wrapper(wrp) {
- initialize(method, true);
+ initialize(method);
}
int SharkStackWithNormalFrame::arg_size() const {
@@ -251,3 +240,24 @@
address SharkStackWithNativeFrame::interpreter_entry_point() const {
return (address) CppInterpreter::native_entry;
}
+
+#ifndef PRODUCT
+void SharkStack::CreateAssertLastJavaSPIsNull() const {
+#ifdef ASSERT
+ BasicBlock *fail = CreateBlock("assert_failed");
+ BasicBlock *pass = CreateBlock("assert_ok");
+
+ builder()->CreateCondBr(
+ builder()->CreateICmpEQ(
+ builder()->CreateLoad(last_Java_sp_addr()),
+ LLVMValue::intptr_constant(0)),
+ pass, fail);
+
+ builder()->SetInsertPoint(fail);
+ builder()->CreateShouldNotReachHere(__FILE__, __LINE__);
+ builder()->CreateUnreachable();
+
+ builder()->SetInsertPoint(pass);
+#endif // ASSERT
+}
+#endif // !PRODUCT
diff -r 373a443db017 ports/hotspot/src/share/vm/shark/sharkStack.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkStack.hpp Fri May 07 16:57:27 2010 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkStack.hpp Mon May 10 11:43:10 2010 +0100
@@ -40,16 +40,10 @@
: SharkCompileInvariants(parent) {}
protected:
- void initialize(llvm::Value* method, bool setup_sp_and_method);
+ void initialize(llvm::Value* method);
protected:
- void CreateStackOverflowCheck(llvm::Value* sp, llvm::Value* method);
-
- private:
- void CreateCheckStack(llvm::Value* base,
- llvm::Value* sp,
- llvm::BasicBlock* overflow,
- llvm::BasicBlock* no_overflow);
+ void CreateStackOverflowCheck(llvm::Value* sp);
// Properties of the method being compiled
protected:
@@ -114,24 +108,39 @@
// Interface with the frame anchor
private:
- llvm::Value* frame_anchor_addr() const {
+ llvm::Value* last_Java_sp_addr() const {
return builder()->CreateAddressOfStructEntry(
thread(),
JavaThread::last_Java_sp_offset(),
llvm::PointerType::getUnqual(SharkType::intptr_type()),
- "frame_anchor_addr");
+ "last_Java_sp_addr");
+ }
+ llvm::Value* last_Java_fp_addr() const {
+ return builder()->CreateAddressOfStructEntry(
+ thread(),
+ JavaThread::last_Java_fp_offset(),
+ llvm::PointerType::getUnqual(SharkType::intptr_type()),
+ "last_Java_fp_addr");
}
public:
- llvm::StoreInst* CreateSetLastJavaFrame() {
- return builder()->CreateStore(
- CreateLoadFramePointer(), frame_anchor_addr());
+ void CreateSetLastJavaFrame() {
+ // Note that whenever _last_Java_sp != NULL other anchor fields
+ // must be valid. The profiler apparently depends on this.
+ NOT_PRODUCT(CreateAssertLastJavaSPIsNull());
+ builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr());
+ // XXX There's last_Java_pc as well, but I don't think anything uses it
+ // Also XXX: should we fence here? Zero doesn't...
+ builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr());
+ // Also also XXX: we could probably cache the sp (and the fp we know??)
}
- llvm::StoreInst* CreateResetLastJavaFrame() {
- return builder()->CreateStore(
- LLVMValue::intptr_constant(0), frame_anchor_addr());
+ void CreateResetLastJavaFrame() {
+ builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr());
}
+ private:
+ void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN;
+
// Our method's frame
private:
llvm::Value* _frame;
More information about the distro-pkg-dev
mailing list