RFC: PATCH: icedtea6 Zero and Shark update
Gary Benson
gbenson at redhat.com
Fri May 7 06:09:21 PDT 2010
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 aab184d452dc ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/cpu/zero/vm/frame_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.cpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.cpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/cpu/zero/vm/frame_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.hpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.hpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/cpu/zero/vm/stack_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/stack_zero.cpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.cpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/cpu/zero/vm/stack_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/cpu/zero/vm/stack_zero.inline.hpp
--- a/ports/hotspot/src/cpu/zero/vm/stack_zero.inline.hpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.inline.hpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Fri May 07 13:07:19 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 aab184d452dc 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 12:02:50 2010 +0100
+++ b/ports/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/share/vm/shark/sharkBuilder.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/share/vm/shark/sharkBuilder.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/share/vm/shark/sharkStack.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkStack.cpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkStack.cpp Fri May 07 13:07:19 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 aab184d452dc ports/hotspot/src/share/vm/shark/sharkStack.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkStack.hpp Fri May 07 12:02:50 2010 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkStack.hpp Fri May 07 13:07:19 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