From gbenson at redhat.com Wed May 5 03:30:29 2010 From: gbenson at redhat.com (Gary Benson) Date: Wed, 5 May 2010 11:30:29 +0100 Subject: Disable a broken optimization in Shark Message-ID: <20100505103029.GA5054@redhat.com> Hi all, This commit disables an optimization that Shark cannot currently support. Explained in the code. PR icedtea/481. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r b571e4dc0ca6 -r 540dc0858c17 ChangeLog --- a/ChangeLog Tue May 04 17:50:37 2010 +0100 +++ b/ChangeLog Wed May 05 11:28:27 2010 +0100 @@ -1,3 +1,10 @@ +2010-05-05 Gary Benson + + PR icedtea/481 + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::improve_virtual_call): Disable an + optimization that cannot currently be supported. + 2010-05-04 Andrew John Hughes Move OpenJDK patches to appropriate subdirectory. diff -r b571e4dc0ca6 -r 540dc0858c17 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Tue May 04 17:50:37 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed May 05 11:28:27 2010 +0100 @@ -903,6 +903,18 @@ dest_method->holder() == java_lang_Object_klass()) return dest_method; +#ifdef SHARK_CAN_DEOPTIMIZE_ANYWHERE + // This code can replace a virtual call with a direct call if this + // class is the only one in the entire set of loaded classes that + // implements this method. This makes the compiled code dependent + // on other classes that implement the method not being loaded, a + // condition which is enforced by the dependency tracker. If the + // dependency tracker determines a method has become invalid it + // will mark it for recompilation, causing running copies to be + // deoptimized. Shark currently can't deoptimize arbitrarily like + // that, so this optimization cannot be used. + // http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=481 + // All other interesting cases are instance classes if (!receiver_type->is_instance_klass()) return NULL; @@ -958,6 +970,8 @@ // with non-monomorphic targets if the receiver has an exact // type. We don't mark types this way, so we can't do this. +#endif // SHARK_CAN_DEOPTIMIZE_ANYWHERE + return NULL; } From xerxes at zafena.se Wed May 5 06:05:45 2010 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Wed, 05 May 2010 15:05:45 +0200 Subject: Disable a broken optimization in Shark In-Reply-To: <20100505103029.GA5054@redhat.com> References: <20100505103029.GA5054@redhat.com> Message-ID: <4BE16D29.2000103@zafena.se> On 2010-05-05 12:30, Gary Benson wrote: > Hi all, > > This commit disables an optimization that Shark cannot currently > support. Explained in the code. PR icedtea/481. > > Cheers, > Gary > > This are great, Shark now runs more stable than ever! Forwarded this fix to icedtea6-1.8 release branch http://icedtea.classpath.org/hg/release/icedtea6-1.8/rev/ecef93c7fbb6 Cheers, Xerxes From gbenson at redhat.com Fri May 7 02:56:28 2010 From: gbenson at redhat.com (Gary Benson) Date: Fri, 7 May 2010 10:56:28 +0100 Subject: Updated icedtea6 Zero (somewhat) Message-ID: <20100507095628.GA3408@redhat.com> Hi all, This commit updates Zero in icedtea6 to something closer to what is upstream. Most importantly this includes the new stack overflow code I wrote about here: http://gbenson.net/?p=184 Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 540dc0858c17 ChangeLog --- a/ChangeLog Wed May 05 11:28:27 2010 +0100 +++ b/ChangeLog Fri May 07 10:49:00 2010 +0100 @@ -1,3 +1,53 @@ +2010-05-07 Gary Benson + + * ports/hotspot/src/cpu/zero/vm/stack_zero.hpp + (ZeroStack::_shadow_pages_size): New field. + (ZeroStack::ZeroStack): Initialize the above. + (ZeroStack::shadow_pages_size): New method. + (ZeroStack::overflow_check): Likewise. + (ZeroStack::handle_overflow): Likewise. + * ports/hotspot/src/cpu/zero/vm/stack_zero.inline.hpp: New file. + * ports/hotspot/src/cpu/zero/vm/stack_zero.cpp: Likewise. + * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp + (CppInterpreter::stack_overflow_imminent): Removed. + * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp + (CppInterpreter::stack_overflow_imminent): Likewise. + (CppInterpreter::normal_entry): Use new stack overflow code. + (CppInterpreter::main_loop): Likewise. + (CppInterpreter::native_entry): Likewise. + (InterpreterFrame::build): Likewise. + * ports/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp + (EntryFrame::build): Likewise. + * ports/hotspot/src/cpu/zero/vm/fakeStubFrame_zero.hpp + (FakeStubFrame::build): Likewise. + * ports/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp + (InterpreterFrame::build): Likewise. + * ports/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp + (InterpreterRuntime::slow_signature_handler): Likewise. + * ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp + (StubGenerator::call_stub): Likewise. + (EntryFrame::build): Likewise. + * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp + (SharkRuntime::uncommon_trap): Likewise. + (FakeStubFrame::build): Likewise. + + * ports/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp + (JavaThread::set_last_Java_frame): Refactored. + (JavaThread::reset_last_Java_frame): Likewise. + + * ports/hotspot/src/cpu/zero/vm/disassembler_zero.hpp + (Disassembler::pd_instruction_alignment): Implemented. + (Disassembler::pd_cpu_opts): Likewise. + + * ports/hotspot/src/cpu/zero/vm/globals_zero.hpp: Updated. + * ports/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp: Likewise. + + * ports/hotspot/src/share/vm/includeDB_zero: Updated. + * ports/hotspot/src/share/vm/includeDB_shark: Likewise. + + * ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp + (SharkDecacher::end_frame): Updated for newer HotSpot. + 2010-05-05 Gary Benson PR icedtea/481 diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp --- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri May 07 10:49:00 2010 +0100 @@ -39,21 +39,9 @@ void CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) { JavaThread *thread = (JavaThread *) THREAD; - ZeroStack *stack = thread->zero_stack(); - - // Adjust the caller's stack frame to accomodate any additional - // local variables we have contiguously with our parameters. - int extra_locals = method->max_locals() - method->size_of_parameters(); - if (extra_locals > 0) { - if (extra_locals > stack->available_words()) { - Unimplemented(); - } - for (int i = 0; i < extra_locals; i++) - stack->push(0); - } // Allocate and initialize our frame. - InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread); + InterpreterFrame *frame = InterpreterFrame::build(method, CHECK); thread->push_zero_frame(frame); // Execute those bytecodes! @@ -76,12 +64,6 @@ intptr_t *result = NULL; int result_slots = 0; - // Check we're not about to run out of stack - if (stack_overflow_imminent(thread)) { - CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread)); - goto unwind_and_return; - } - while (true) { // We can set up the frame anchor with everything we want at // this point as we are thread_in_Java and no safepoints can @@ -123,9 +105,9 @@ int monitor_words = frame::interpreter_frame_monitor_size(); // Allocate the space - if (monitor_words > stack->available_words()) { - Unimplemented(); - } + stack->overflow_check(monitor_words, THREAD); + if (HAS_PENDING_EXCEPTION) + break; stack->alloc(monitor_words * wordSize); // Move the expression stack contents @@ -172,8 +154,6 @@ } } - unwind_and_return: - // Unwind the current frame thread->pop_zero_frame(); @@ -193,17 +173,11 @@ ZeroStack *stack = thread->zero_stack(); // Allocate and initialize our frame - InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread); + InterpreterFrame *frame = InterpreterFrame::build(method, CHECK); thread->push_zero_frame(frame); interpreterState istate = frame->interpreter_state(); intptr_t *locals = istate->locals(); - // Check we're not about to run out of stack - if (stack_overflow_imminent(thread)) { - CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread)); - goto unwind_and_return; - } - // Update the invocation counter if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) { InvocationCounter *counter = method->invocation_counter(); @@ -264,9 +238,10 @@ assert(function != NULL, "should be set if signature handler is"); // Build the argument list - if (handler->argument_count() * 2 > stack->available_words()) { - Unimplemented(); - } + stack->overflow_check(handler->argument_count() * 2, THREAD); + if (HAS_PENDING_EXCEPTION) + goto unlock_unwind_and_return; + void **arguments; void *mirror; { arguments = @@ -503,9 +478,7 @@ switch (entry->flag_state()) { case ltos: case dtos: - if (stack->available_words() < 1) { - Unimplemented(); - } + stack->overflow_check(1, CHECK); stack->alloc(wordSize); break; } @@ -601,39 +574,30 @@ stack->set_sp(stack->sp() + method->size_of_parameters()); } -bool CppInterpreter::stack_overflow_imminent(JavaThread *thread) { - // How is the ABI stack? - address stack_top = thread->stack_base() - thread->stack_size(); - int free_stack = os::current_stack_pointer() - stack_top; - if (free_stack < StackShadowPages * os::vm_page_size()) { - return true; +InterpreterFrame *InterpreterFrame::build(const methodOop method, TRAPS) { + JavaThread *thread = (JavaThread *) THREAD; + ZeroStack *stack = thread->zero_stack(); + + // Calculate the size of the frame we'll build, including + // any adjustments to the caller's frame that we'll make. + int extra_locals = 0; + int monitor_words = 0; + int stack_words = 0; + + if (!method->is_native()) { + extra_locals = method->max_locals() - method->size_of_parameters(); + stack_words = method->max_stack(); } + if (method->is_synchronized()) { + monitor_words = frame::interpreter_frame_monitor_size(); + } + stack->overflow_check( + extra_locals + header_words + monitor_words + stack_words, CHECK_NULL); - // How is the Zero stack? - // Throwing a StackOverflowError involves a VM call, which means - // we need a frame on the stack. We should be checking here to - // ensure that methods we call have enough room to install the - // largest possible frame, but that's more than twice the size - // of the entire Zero stack we get by default, so we just check - // we have *some* space instead... - free_stack = thread->zero_stack()->available_words() * wordSize; - if (free_stack < StackShadowPages * os::vm_page_size()) { - return true; - } - - return false; -} - -InterpreterFrame *InterpreterFrame::build(ZeroStack* stack, - const methodOop method, - JavaThread* thread) { - int monitor_words = - method->is_synchronized() ? frame::interpreter_frame_monitor_size() : 0; - int stack_words = method->is_native() ? 0 : method->max_stack(); - - if (header_words + monitor_words + stack_words > stack->available_words()) { - Unimplemented(); - } + // Adjust the caller's stack frame to accomodate any additional + // local variables we have contiguously with our parameters. + for (int i = 0; i < extra_locals; i++) + stack->push(0); intptr_t *locals; if (method->is_native()) @@ -819,14 +783,13 @@ // Deoptimization helpers -InterpreterFrame *InterpreterFrame::build(ZeroStack* stack, int size) { +InterpreterFrame *InterpreterFrame::build(int size, TRAPS) { + ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack(); + int size_in_words = size >> LogBytesPerWord; assert(size_in_words * wordSize == size, "unaligned"); assert(size_in_words >= header_words, "too small"); - - if (size_in_words > stack->available_words()) { - Unimplemented(); - } + stack->overflow_check(size_in_words, CHECK_NULL); stack->push(0); // next_frame, filled in later intptr_t *fp = stack->sp(); diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp Fri May 07 10:49:00 2010 +0100 @@ -39,9 +39,5 @@ static void main_loop(int recurse, TRAPS); private: - // Stack overflow checks - static bool stack_overflow_imminent(JavaThread *thread); - - private: // Fast result type determination static BasicType result_type_of(methodOop method); diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/disassembler_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/disassembler_zero.hpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/disassembler_zero.hpp Fri May 07 10:49:00 2010 +0100 @@ -1,6 +1,6 @@ /* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2007, 2010 Red Hat, Inc. + * Copyright 2007 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,10 +23,13 @@ * */ +// The disassembler prints out zero code annotated +// with Java specific information. + static int pd_instruction_alignment() { - return 1; + ShouldNotCallThis(); } static const char* pd_cpu_opts() { - return ""; + ShouldNotCallThis(); } diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp Fri May 07 10:49:00 2010 +0100 @@ -1,6 +1,6 @@ /* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2008 Red Hat, Inc. + * Copyright 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 @@ -47,10 +47,10 @@ }; public: - static EntryFrame *build(ZeroStack* stack, - const intptr_t* parameters, + static EntryFrame *build(const intptr_t* parameters, int parameter_words, - JavaCallWrapper* call_wrapper); + JavaCallWrapper* call_wrapper, + TRAPS); public: JavaCallWrapper *call_wrapper() const { return (JavaCallWrapper *) value_of_word(call_wrapper_off); diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/fakeStubFrame_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/fakeStubFrame_zero.hpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/fakeStubFrame_zero.hpp Fri May 07 10:49:00 2010 +0100 @@ -1,6 +1,6 @@ /* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2008 Red Hat, Inc. + * Copyright 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 @@ -42,7 +42,7 @@ }; public: - static FakeStubFrame *build(ZeroStack* stack); + static FakeStubFrame *build(TRAPS); public: void identify_word(int frame_index, diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/globals_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/globals_zero.hpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/globals_zero.hpp Fri May 07 10:49:00 2010 +0100 @@ -35,17 +35,8 @@ define_pd_global(bool, UncommonNullCast, true); define_pd_global(intx, CodeEntryAlignment, 32); -define_pd_global(uintx, TLABSize, 0); -#ifdef _LP64 -define_pd_global(uintx, NewSize, ScaleForWordSize(2048 * K)); -#else -define_pd_global(uintx, NewSize, ScaleForWordSize(1024 * K)); -#endif // _LP64 +define_pd_global(intx, OptoLoopAlignment, 16); define_pd_global(intx, InlineFrequencyCount, 100); -#ifdef SHARK -// Only required for older HotSpot versions -define_pd_global(intx, InlineSmallCode, 1000); -#endif // SHARK define_pd_global(intx, PreInflateSpin, 10); define_pd_global(intx, StackYellowPages, 2); diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp Fri May 07 10:49:00 2010 +0100 @@ -1,6 +1,6 @@ /* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2008 Red Hat, Inc. + * Copyright 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 @@ -55,10 +55,8 @@ }; public: - static InterpreterFrame *build(ZeroStack* stack, - const methodOop method, - JavaThread* thread); - static InterpreterFrame *build(ZeroStack* stack, int size); + static InterpreterFrame *build(const methodOop method, TRAPS); + static InterpreterFrame *build(int size, TRAPS); public: interpreterState interpreter_state() const { diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp --- a/ports/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp Fri May 07 10:49:00 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 @@ -140,9 +140,8 @@ int required_words = (align_size_up(sizeof(ffi_cif), wordSize) >> LogBytesPerWord) + (method->is_static() ? 2 : 1) + method->size_of_parameters() + 1; - if (required_words > stack->available_words()) { - Unimplemented(); - } + + stack->overflow_check(required_words, CHECK_NULL); intptr_t *buf = (intptr_t *) stack->alloc(required_words * wordSize); SlowSignatureHandlerGenerator sshg(methodHandle(thread, method), buf); diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp Fri May 07 10:49:00 2010 +0100 @@ -47,6 +47,7 @@ define_pd_global(intx, OnStackReplacePercentage, 933 ); define_pd_global(intx, FreqInlineSize, 325 ); +define_pd_global(intx, InlineSmallCode, 1000 ); define_pd_global(intx, NewRatio, 12 ); define_pd_global(intx, NewSizeThreadIncrease, 4*K ); define_pd_global(intx, InitialCodeCacheSize, 160*K); diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/stack_zero.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.cpp Fri May 07 10:49:00 2010 +0100 @@ -0,0 +1,73 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_stack_zero.cpp.incl" + +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) { + ZeroFrame *frame = thread->top_zero_frame(); + while (frame) { + if (frame->is_shark_frame()) + break; + + if (frame->is_interpreter_frame()) { + interpreterState istate = + frame->as_interpreter_frame()->interpreter_state(); + if (istate->self_link() == istate) + break; + } + + frame = frame->next(); + } + + if (frame == NULL) + fatal("unrecoverable stack overflow"); + + thread->set_last_Java_frame(frame); + } + + // Throw the exception + switch (thread->thread_state()) { + case _thread_in_Java: + InterpreterRuntime::throw_StackOverflowError(thread); + break; + + case _thread_in_vm: + Exceptions::throw_stack_overflow_exception(thread, __FILE__, __LINE__); + break; + + default: + ShouldNotReachHere(); + } + + // Reset the frame anchor if necessary + if (!has_last_Java_frame) + thread->reset_last_Java_frame(); +} diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/stack_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp Fri May 07 10:49:00 2010 +0100 @@ -1,6 +1,6 @@ /* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2008, 2009 Red Hat, Inc. + * Copyright 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 @@ -29,9 +29,14 @@ intptr_t *_top; // the word past the end of the stack intptr_t *_sp; // the top word on the stack + private: + int _shadow_pages_size; // how much ABI stack must we keep free? + public: ZeroStack() - : _base(NULL), _top(NULL), _sp(NULL) {} + : _base(NULL), _top(NULL), _sp(NULL) { + _shadow_pages_size = StackShadowPages * os::vm_page_size(); + } bool needs_setup() const { return _base == NULL; @@ -81,6 +86,14 @@ return _sp -= count; } + int shadow_pages_size() const { + return _shadow_pages_size; + } + + public: + void overflow_check(int required_words, TRAPS); + static void handle_overflow(TRAPS); + public: static ByteSize base_offset() { return byte_offset_of(ZeroStack, _base); diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/stack_zero.inline.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.inline.hpp Fri May 07 10:49:00 2010 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// 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()) { + 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()) { + handle_overflow(THREAD); + return; + } +} diff -r 540dc0858c17 ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp --- a/ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Fri May 07 10:49:00 2010 +0100 @@ -1,6 +1,6 @@ /* * Copyright 2003-2007 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 @@ -60,38 +60,43 @@ } // Allocate and initialize our frame - thread->push_zero_frame( - EntryFrame::build(stack, parameters, parameter_words, call_wrapper)); + EntryFrame *frame = + EntryFrame::build(parameters, parameter_words, call_wrapper, THREAD); - // Make the call - Interpreter::invoke_method(method, entry_point, THREAD); + if (!HAS_PENDING_EXCEPTION) { + // Push the frame + thread->push_zero_frame(frame); - // Store result depending on type - if (!HAS_PENDING_EXCEPTION) { - switch (result_type) { - case T_INT: - *(jint *) result = *(jint *) stack->sp(); - break; - case T_LONG: - *(jlong *) result = *(jlong *) stack->sp(); - break; - case T_FLOAT: - *(jfloat *) result = *(jfloat *) stack->sp(); - break; - case T_DOUBLE: - *(jdouble *) result = *(jdouble *) stack->sp(); - break; - case T_OBJECT: - *(oop *) result = *(oop *) stack->sp(); - break; - default: - ShouldNotReachHere(); + // Make the call + Interpreter::invoke_method(method, entry_point, THREAD); + + // Store the result + if (!HAS_PENDING_EXCEPTION) { + switch (result_type) { + case T_INT: + *(jint *) result = *(jint *) stack->sp(); + break; + case T_LONG: + *(jlong *) result = *(jlong *) stack->sp(); + break; + case T_FLOAT: + *(jfloat *) result = *(jfloat *) stack->sp(); + break; + case T_DOUBLE: + *(jdouble *) result = *(jdouble *) stack->sp(); + break; + case T_OBJECT: + *(oop *) result = *(oop *) stack->sp(); + break; + default: + ShouldNotReachHere(); + } } + + // Unwind the frame + thread->pop_zero_frame(); } - // Unwind our frame - thread->pop_zero_frame(); - // Tear down the stack if necessary if (stack_needs_teardown) stack->teardown(); @@ -226,13 +231,13 @@ StubGenerator g(code, all); } -EntryFrame *EntryFrame::build(ZeroStack* stack, - const intptr_t* parameters, +EntryFrame *EntryFrame::build(const intptr_t* parameters, int parameter_words, - JavaCallWrapper* call_wrapper) { - if (header_words + parameter_words > stack->available_words()) { - Unimplemented(); - } + JavaCallWrapper* call_wrapper, + TRAPS) { + + ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack(); + stack->overflow_check(header_words + parameter_words, CHECK_NULL); stack->push(0); // next_frame, filled in later intptr_t *fp = stack->sp(); diff -r 540dc0858c17 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 Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp Fri May 07 10:49:00 2010 +0100 @@ -1,6 +1,6 @@ /* * Copyright 2000-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 @@ -68,12 +68,13 @@ public: void set_last_Java_frame() { - JavaFrameAnchor *jfa = frame_anchor(); - jfa->set_last_Java_sp((intptr_t *) top_zero_frame()); + set_last_Java_frame(top_zero_frame()); } void reset_last_Java_frame() { - JavaFrameAnchor *jfa = frame_anchor(); - jfa->set_last_Java_sp(NULL); + set_last_Java_frame(NULL); + } + void set_last_Java_frame(ZeroFrame* frame) { + frame_anchor()->set_last_Java_sp((intptr_t *) frame); } private: diff -r 540dc0858c17 ports/hotspot/src/share/vm/includeDB_shark --- a/ports/hotspot/src/share/vm/includeDB_shark Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/share/vm/includeDB_shark Fri May 07 10:49:00 2010 +0100 @@ -1,6 +1,6 @@ // // Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. -// Copyright 2008, 2009 Red Hat, Inc. +// Copyright 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 @@ -273,6 +273,7 @@ sharkRuntime.cpp llvmHeaders.hpp sharkRuntime.cpp klassOop.hpp sharkRuntime.cpp sharkRuntime.hpp +sharkRuntime.cpp stack_.inline.hpp sharkRuntime.cpp thread.hpp sharkRuntime.hpp allocation.hpp diff -r 540dc0858c17 ports/hotspot/src/share/vm/includeDB_zero --- a/ports/hotspot/src/share/vm/includeDB_zero Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/share/vm/includeDB_zero Fri May 07 10:49:00 2010 +0100 @@ -1,6 +1,6 @@ // // Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved. -// Copyright 2009 Red Hat, Inc. +// Copyright 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 @@ -25,6 +25,8 @@ // NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps! +cppInterpreter_.cpp stack_.inline.hpp + entryFrame_.hpp javaCalls.hpp entryFrame_.hpp stack_.hpp @@ -47,9 +49,20 @@ interpreterFrame_.hpp stack_.hpp interpreterFrame_.hpp thread.hpp +interpreterRT_.cpp stack_.inline.hpp + sharkFrame_.hpp methodOop.hpp sharkFrame_.hpp stack_.hpp stack_.hpp sizes.hpp +stack_.inline.hpp stack_.hpp +stack_.inline.hpp thread.hpp + +stack_.cpp interpreterRuntime.hpp +stack_.cpp stack_.hpp +stack_.cpp stack_.inline.hpp + +stubGenerator_.cpp stack_.inline.hpp + thread.hpp stack_.hpp diff -r 540dc0858c17 ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Fri May 07 10:49:00 2010 +0100 @@ -149,6 +149,7 @@ pc_offset(), target(), bci(), + true, debug_info()->create_scope_values(locarray()), debug_info()->create_scope_values(exparray()), debug_info()->create_monitor_values(monarray())); diff -r 540dc0858c17 ports/hotspot/src/share/vm/shark/sharkRuntime.cpp --- a/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Wed May 05 11:28:27 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Fri May 07 10:49:00 2010 +0100 @@ -1,6 +1,6 @@ /* * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2008, 2009 Red Hat, Inc. + * Copyright 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 @@ -195,10 +195,12 @@ void SharkRuntime::uncommon_trap(JavaThread* thread, int trap_request) { // In C2, uncommon_trap_blob creates a frame, so all the various // deoptimization functions expect to find the frame of the method - // being deopted one frame down on the stack. Create a dummy frame - // to mirror this. - ZeroStack *stack = thread->zero_stack(); - thread->push_zero_frame(FakeStubFrame::build(stack)); + // being deopted one frame down on the stack. We create a dummy + // frame to mirror this. + FakeStubFrame *stubframe = FakeStubFrame::build(thread); + if (thread->has_pending_exception()) + return; + thread->push_zero_frame(stubframe); // Initiate the trap thread->set_last_Java_frame(); @@ -214,11 +216,17 @@ int number_of_frames = urb->number_of_frames(); for (int i = 0; i < number_of_frames; i++) { intptr_t size = urb->frame_sizes()[i]; - thread->push_zero_frame(InterpreterFrame::build(stack, size)); + InterpreterFrame *frame = InterpreterFrame::build(size, thread); + if (thread->has_pending_exception()) + return; + thread->push_zero_frame(frame); } // Push another dummy frame - thread->push_zero_frame(FakeStubFrame::build(stack)); + stubframe = FakeStubFrame::build(thread); + if (thread->has_pending_exception()) + return; + thread->push_zero_frame(stubframe); // Fill in the skeleton frames thread->set_last_Java_frame(); @@ -236,10 +244,9 @@ #endif // CC_INTERP } -FakeStubFrame* FakeStubFrame::build(ZeroStack* stack) { - if (header_words > stack->available_words()) { - Unimplemented(); - } +FakeStubFrame* FakeStubFrame::build(TRAPS) { + ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack(); + stack->overflow_check(header_words, CHECK_NULL); stack->push(0); // next_frame, filled in later intptr_t *fp = stack->sp(); From gbenson at redhat.com Fri May 7 06:09:21 2010 From: gbenson at redhat.com (Gary Benson) Date: Fri, 7 May 2010 14:09:21 +0100 Subject: RFC: PATCH: icedtea6 Zero and Shark update Message-ID: <20100507130921.GB3408@redhat.com> 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; From gbenson at redhat.com Mon May 10 03:48:08 2010 From: gbenson at redhat.com (Gary Benson) Date: Mon, 10 May 2010 11:48:08 +0100 Subject: Updated Zero and Shark; disabled ARM interpreter Message-ID: <20100510104807.GA3328@redhat.com> 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 + + 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 * 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; From ahughes at redhat.com Mon May 10 03:50:58 2010 From: ahughes at redhat.com (Andrew John Hughes) Date: Mon, 10 May 2010 11:50:58 +0100 Subject: Updated Zero and Shark; disabled ARM interpreter In-Reply-To: <20100510104807.GA3328@redhat.com> References: <20100510104807.GA3328@redhat.com> Message-ID: On 10 May 2010 11:48, Gary Benson wrote: > 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 is to HEAD? > 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/ > -- Andrew :-) Free Java Software Engineer Red Hat, Inc. (http://www.redhat.com) Support Free Java! Contribute to GNU Classpath and the OpenJDK http://www.gnu.org/software/classpath http://openjdk.java.net PGP Key: 94EFD9D8 (http://subkeys.pgp.net) Fingerprint: F8EF F1EA 401E 2E60 15FA 7927 142C 2591 94EF D9D8 From gbenson at redhat.com Mon May 10 04:01:22 2010 From: gbenson at redhat.com (Gary Benson) Date: Mon, 10 May 2010 12:01:22 +0100 Subject: Updated Zero and Shark; disabled ARM interpreter In-Reply-To: References: <20100510104807.GA3328@redhat.com> Message-ID: <20100510110122.GC3328@redhat.com> Andrew John Hughes wrote: > On 10 May 2010 11:48, Gary Benson wrote: > > 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 is to HEAD? icedtea6 HEAD, yes. Cheers, Gary -- http://gbenson.net/ From gbenson at redhat.com Tue May 11 01:28:03 2010 From: gbenson at redhat.com (Gary Benson) Date: Tue, 11 May 2010 09:28:03 +0100 Subject: Zero and Shark fix Message-ID: <20100511082803.GA3397@redhat.com> Hi all, This commit removes a hack that became unnecessary with the updated frame anchor code in my last commit. Xerxes, this might be the source of the failures you were seeing. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 9bc0c7b7f327 ChangeLog --- a/ChangeLog Mon May 10 11:44:31 2010 +0100 +++ b/ChangeLog Tue May 11 09:26:27 2010 +0100 @@ -1,3 +1,8 @@ +2010-05-11 Gary Benson + + * patches/icedtea-shark.patch + (Deoptimization::create_vframeArray): Remove a now-unnecessary hack. + 2010-05-10 Gary Benson PR icedtea/323 diff -r 9bc0c7b7f327 patches/icedtea-shark.patch --- a/patches/icedtea-shark.patch Mon May 10 11:44:31 2010 +0100 +++ b/patches/icedtea-shark.patch Tue May 11 09:26:27 2010 +0100 @@ -101,27 +101,6 @@ UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord, caller_adjustment * BytesPerWord, -@@ -890,7 +897,20 @@ - // stuff a C2I adapter we can properly fill in the callee-save - // register locations. - frame caller = fr.sender(reg_map); -+#ifdef ZERO -+ int frame_size; -+ { -+ // In zero, frame::sp() is the *end* of the frame, so -+ // caller.sp() - fr.sp() is the size of the *caller*. -+ RegisterMap dummy_map(thread, false); -+ frame frame_1 = thread->last_frame(); -+ frame frame_2 = frame_1.sender(&dummy_map); -+ assert(frame_2.sp() == fr.sp(), "should be"); -+ frame_size = frame_2.sp() - frame_1.sp(); -+ } -+#else - int frame_size = caller.sp() - fr.sp(); -+#endif // ZERO - - frame sender = caller; - @@ -1057,7 +1077,7 @@ JRT_END From xerxes at zafena.se Wed May 12 06:06:29 2010 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Wed, 12 May 2010 15:06:29 +0200 Subject: RFC: Shark correct llvm 2.8 memset intrinsic call. Message-ID: <4BEAA7D5.9090202@zafena.se> The attached patch makes Shark use the LLVM 2.8 memset intrinsic in a more "correct" way. The volatile field really are a bool and the intrinsic signature have been altered in LLVM 2.8 a little so by using the attached patch will make sure that LLVM dont have to guess which intrinsic match best. Cheers Xerxes -------------- next part -------------- A non-text attachment was scrubbed... Name: 12may-memset-llvm2.8-correctness.patch Type: text/x-patch Size: 1007 bytes Desc: not available Url : http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20100512/ba62a86c/attachment.bin From gbenson at redhat.com Thu May 13 07:57:54 2010 From: gbenson at redhat.com (Gary Benson) Date: Thu, 13 May 2010 15:57:54 +0100 Subject: Shark fix Message-ID: <20100513145754.GC11135@redhat.com> Hi all, This commit fixes Shark's compilation of native methods that return byte or char results. PR icedtea/483. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 0d1df8a64a73 ChangeLog --- a/ChangeLog Tue May 11 09:26:09 2010 +0100 +++ b/ChangeLog Thu May 13 15:55:14 2010 +0100 @@ -1,5 +1,13 @@ +2010-05-13 Gary Benson + + PR icedtea/483 + * ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp + (SharkNativeWrapper::initialize): Fix signedness of T_BYTE + and T_CHAR results. + 2010-05-11 Gary Benson + PR icedtea/323 * patches/icedtea-shark.patch (Deoptimization::create_vframeArray): Remove a now-unnecessary hack. diff -r 0d1df8a64a73 ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp --- a/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Tue May 11 09:26:09 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Thu May 13 15:55:14 2010 +0100 @@ -327,11 +327,11 @@ needs_cast = true; break; - case T_BYTE: + case T_CHAR: needs_cast = true; break; - case T_CHAR: + case T_BYTE: case T_SHORT: needs_cast = true; is_signed = true; From gbenson at redhat.com Fri May 14 06:05:07 2010 From: gbenson at redhat.com (Gary Benson) Date: Fri, 14 May 2010 14:05:07 +0100 Subject: New calling convention for Zero and Shark Message-ID: <20100514130506.GA3438@redhat.com> Hi all, This commit fixes PR icedtea/484, a bug where the native code for deoptimized methods could be freed when in fact they were still on the stack and waiting to return. To make this change I have had to change the calling convention within Zero and Shark. All method entries (the C function that executes the method) now return an integer which is the number of deoptimized frames they have left on the stack. Whenever a method is called it is now the caller's responsibility to check whether frames have been deoptimized and reenter the interpreter if they have. The ARM interpreter needs updating to follow the new convention. I have made a note of this in zeroshark.make, where the code that enables the ARM interpreter is currently commented out. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r f50bc2a9120e ChangeLog --- a/ChangeLog Fri May 14 11:16:36 2010 +0100 +++ b/ChangeLog Fri May 14 13:54:40 2010 +0100 @@ -1,3 +1,46 @@ +2010-05-14 Gary Benson + + PR icedtea/484 + * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp + (CppInterpreter::normal_entry): Return int instead of void. + (CppInterpreter::native_entry): Likewise. + (CppInterpreter::accessor_entry): Likewise. + (CppInterpreter::empty_entry): Likewise. + * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp + (CppInterpreter::normal_entry): Return 0. + (CppInterpreter::native_entry): Likewise. + (CppInterpreter::accessor_entry): Likewise. + (CppInterpreter::empty_entry): Likewise. + * ports/hotspot/src/cpu/zero/vm/entry_zero.hpp + (ZeroEntry::NormalEntryFunc): Return int instead of void. + (ZeroEntry::OSREntryFunc): Likewise. + (ZeroEntry::invoke): Deoptimize where necessary. + (ZeroEntry::invoke_osr): Likewise. + (ZeroEntry::maybe_deoptimize): New method. + * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp + (SharkBuilder::deoptimized_entry_point): New method. + * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp + (SharkBuilder::uncommon_trap): Return int instead of void. + (SharkBuilder::deoptimized_entry_point): New method. + * ports/hotspot/src/share/vm/shark/sharkContext.cpp + (SharkContext::SharkContext): Updated entry point types. + * ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp + (SharkNativeWrapper::initialize): Make generated wrappers + return 0 instead of void. + * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp + (SharkRuntime::uncommon_trap): Return int instead of void. + * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp + (SharkRuntime::uncommon_trap): Don't enter the interpreter, + just return the number of frames that have been deoptimized. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::do_trap): Return the number of deoptimized + frames instead of void. + (SharkTopLevelBlock::handle_return): Return 0 instead of void. + (SharkTopLevelBlock::do_call): Deoptimize where necessary. + + * ports/hotspot/make/linux/makefiles/zeroshark.make: + Note that ARM interpreter needs updating for this change too. + 2010-05-14 Gary Benson * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp diff -r f50bc2a9120e ports/hotspot/make/linux/makefiles/zeroshark.make --- a/ports/hotspot/make/linux/makefiles/zeroshark.make Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/make/linux/makefiles/zeroshark.make Fri May 14 13:54:40 2010 +0100 @@ -31,7 +31,8 @@ Obj_Files += cppInterpreter_arm.o Obj_Files += thumb2.o -#XXX disabled until it has the updated frame anchor code +#XXX disabled until it has the updated frame anchor code (PR icedtea/323) +#XXX and the updated calling convention for deopt (PR icedtea/484) #CFLAGS += -DHOTSPOT_ASM %.o: %.S diff -r f50bc2a9120e ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp --- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri May 14 13:54:40 2010 +0100 @@ -37,15 +37,18 @@ thread->reset_last_Java_frame(); \ fixup_after_potential_safepoint() -void CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) { +int CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) { JavaThread *thread = (JavaThread *) THREAD; // Allocate and initialize our frame. - InterpreterFrame *frame = InterpreterFrame::build(method, CHECK); + InterpreterFrame *frame = InterpreterFrame::build(method, CHECK_0); thread->push_zero_frame(frame); // Execute those bytecodes! main_loop(0, THREAD); + + // No deoptimized frames on the stack + return 0; } void CppInterpreter::main_loop(int recurse, TRAPS) { @@ -165,7 +168,7 @@ stack->push(result[-i]); } -void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) { +int CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) { // Make sure method is native and not abstract assert(method->is_native() && !method->is_abstract(), "should be"); @@ -173,7 +176,7 @@ ZeroStack *stack = thread->zero_stack(); // Allocate and initialize our frame - InterpreterFrame *frame = InterpreterFrame::build(method, CHECK); + InterpreterFrame *frame = InterpreterFrame::build(method, CHECK_0); thread->push_zero_frame(frame); interpreterState istate = frame->interpreter_state(); intptr_t *locals = istate->locals(); @@ -430,25 +433,26 @@ ShouldNotReachHere(); } } + + // No deoptimized frames on the stack + return 0; } -void CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) { +int CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) { JavaThread *thread = (JavaThread *) THREAD; ZeroStack *stack = thread->zero_stack(); intptr_t *locals = stack->sp(); // Drop into the slow path if we need a safepoint check if (SafepointSynchronize::do_call_back()) { - normal_entry(method, 0, THREAD); - return; + return normal_entry(method, 0, THREAD); } // Load the object pointer and drop into the slow path // if we have a NullPointerException oop object = LOCALS_OBJECT(0); if (object == NULL) { - normal_entry(method, 0, THREAD); - return; + return normal_entry(method, 0, THREAD); } // Read the field index from the bytecode, which looks like this: @@ -470,15 +474,14 @@ constantPoolCacheOop cache = method->constants()->cache(); ConstantPoolCacheEntry* entry = cache->entry_at(index); if (!entry->is_resolved(Bytecodes::_getfield)) { - normal_entry(method, 0, THREAD); - return; + return normal_entry(method, 0, THREAD); } // Get the result and push it onto the stack switch (entry->flag_state()) { case ltos: case dtos: - stack->overflow_check(1, CHECK); + stack->overflow_check(1, CHECK_0); stack->alloc(wordSize); break; } @@ -558,20 +561,25 @@ ShouldNotReachHere(); } } + + // No deoptimized frames on the stack + return 0; } -void CppInterpreter::empty_entry(methodOop method, intptr_t UNUSED, TRAPS) { +int CppInterpreter::empty_entry(methodOop method, intptr_t UNUSED, TRAPS) { JavaThread *thread = (JavaThread *) THREAD; ZeroStack *stack = thread->zero_stack(); // Drop into the slow path if we need a safepoint check if (SafepointSynchronize::do_call_back()) { - normal_entry(method, 0, THREAD); - return; + return normal_entry(method, 0, THREAD); } // Pop our parameters stack->set_sp(stack->sp() + method->size_of_parameters()); + + // No deoptimized frames on the stack + return 0; } InterpreterFrame *InterpreterFrame::build(const methodOop method, TRAPS) { diff -r f50bc2a9120e ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp Fri May 14 13:54:40 2010 +0100 @@ -29,10 +29,10 @@ public: // Method entries - static void normal_entry(methodOop method, intptr_t UNUSED, TRAPS); - static void native_entry(methodOop method, intptr_t UNUSED, TRAPS); - static void accessor_entry(methodOop method, intptr_t UNUSED, TRAPS); - static void empty_entry(methodOop method, intptr_t UNUSED, TRAPS); + static int normal_entry(methodOop method, intptr_t UNUSED, TRAPS); + static int native_entry(methodOop method, intptr_t UNUSED, TRAPS); + static int accessor_entry(methodOop method, intptr_t UNUSED, TRAPS); + static int empty_entry(methodOop method, intptr_t UNUSED, TRAPS); public: // Main loop of normal_entry diff -r f50bc2a9120e ports/hotspot/src/cpu/zero/vm/entry_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/entry_zero.hpp Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/entry_zero.hpp Fri May 14 13:54:40 2010 +0100 @@ -1,6 +1,6 @@ /* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2008, 2009 Red Hat, Inc. + * Copyright 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 @@ -41,20 +41,30 @@ } private: - typedef void (*NormalEntryFunc)(methodOop method, - intptr_t base_pc, - TRAPS); - typedef void (*OSREntryFunc)(methodOop method, - address osr_buf, - intptr_t base_pc, - TRAPS); + typedef int (*NormalEntryFunc)(methodOop method, + intptr_t base_pc, + TRAPS); + typedef int (*OSREntryFunc)(methodOop method, + address osr_buf, + intptr_t base_pc, + TRAPS); public: void invoke(methodOop method, TRAPS) const { - ((NormalEntryFunc) entry_point())(method, (intptr_t) this, THREAD); + maybe_deoptimize( + ((NormalEntryFunc) entry_point())(method, (intptr_t) this, THREAD), + THREAD); } void invoke_osr(methodOop method, address osr_buf, TRAPS) const { - ((OSREntryFunc) entry_point())(method, osr_buf, (intptr_t) this, THREAD); + maybe_deoptimize( + ((OSREntryFunc) entry_point())(method, osr_buf, (intptr_t) this, THREAD), + THREAD); + } + + private: + static void maybe_deoptimize(int deoptimized_frames, TRAPS) { + if (deoptimized_frames) + CppInterpreter::main_loop(deoptimized_frames - 1, THREAD); } public: diff -r f50bc2a9120e ports/hotspot/src/share/vm/shark/sharkBuilder.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Fri May 14 13:54:40 2010 +0100 @@ -326,7 +326,11 @@ } Value* SharkBuilder::uncommon_trap() { - return make_function((address) SharkRuntime::uncommon_trap, "Ti", "v"); + return make_function((address) SharkRuntime::uncommon_trap, "Ti", "i"); +} + +Value* SharkBuilder::deoptimized_entry_point() { + return make_function((address) CppInterpreter::main_loop, "iT", "v"); } // Native-Java transition diff -r f50bc2a9120e ports/hotspot/src/share/vm/shark/sharkBuilder.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Fri May 14 13:54:40 2010 +0100 @@ -133,6 +133,7 @@ public: llvm::Value* throw_StackOverflowError(); llvm::Value* uncommon_trap(); + llvm::Value* deoptimized_entry_point(); // Intrinsics and external functions, part 4: Native-Java transition. // This is a special case in that it is invoked during a thread diff -r f50bc2a9120e ports/hotspot/src/share/vm/shark/sharkContext.cpp --- a/ports/hotspot/src/share/vm/shark/sharkContext.cpp Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkContext.cpp Fri May 14 13:54:40 2010 +0100 @@ -1,6 +1,6 @@ /* * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2009 Red Hat, Inc. + * Copyright 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 @@ -76,14 +76,14 @@ params.push_back(methodOop_type()); params.push_back(intptr_type()); params.push_back(thread_type()); - _entry_point_type = FunctionType::get(void_type(), params, false); + _entry_point_type = FunctionType::get(jint_type(), params, false); params.clear(); params.push_back(methodOop_type()); params.push_back(PointerType::getUnqual(jbyte_type())); params.push_back(intptr_type()); params.push_back(thread_type()); - _osr_entry_point_type = FunctionType::get(void_type(), params, false); + _osr_entry_point_type = FunctionType::get(jint_type(), params, false); // Create mappings for (int i = 0; i < T_CONFLICT; i++) { diff -r f50bc2a9120e ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp --- a/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Fri May 14 13:54:40 2010 +0100 @@ -283,7 +283,7 @@ builder()->SetInsertPoint(exception); CreateResetHandleBlock(); stack()->CreatePopFrame(0); - builder()->CreateRetVoid(); + builder()->CreateRet(LLVMValue::jint_constant(0)); builder()->SetInsertPoint(no_exception); @@ -348,5 +348,5 @@ result_addr, PointerType::getUnqual(SharkType::to_stackType(result_type)))); } - builder()->CreateRetVoid(); + builder()->CreateRet(LLVMValue::jint_constant(0)); } diff -r f50bc2a9120e ports/hotspot/src/share/vm/shark/sharkRuntime.cpp --- a/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Fri May 14 13:54:40 2010 +0100 @@ -192,14 +192,14 @@ return object_klass->klass_part()->is_subtype_of(check_klass); } -void SharkRuntime::uncommon_trap(JavaThread* thread, int trap_request) { +int SharkRuntime::uncommon_trap(JavaThread* thread, int trap_request) { + Thread *THREAD = thread; + // In C2, uncommon_trap_blob creates a frame, so all the various // deoptimization functions expect to find the frame of the method // being deopted one frame down on the stack. We create a dummy // frame to mirror this. - FakeStubFrame *stubframe = FakeStubFrame::build(thread); - if (thread->has_pending_exception()) - return; + FakeStubFrame *stubframe = FakeStubFrame::build(CHECK_0); thread->push_zero_frame(stubframe); // Initiate the trap @@ -216,16 +216,12 @@ int number_of_frames = urb->number_of_frames(); for (int i = 0; i < number_of_frames; i++) { intptr_t size = urb->frame_sizes()[i]; - InterpreterFrame *frame = InterpreterFrame::build(size, thread); - if (thread->has_pending_exception()) - return; + InterpreterFrame *frame = InterpreterFrame::build(size, CHECK_0); thread->push_zero_frame(frame); } // Push another dummy frame - stubframe = FakeStubFrame::build(thread); - if (thread->has_pending_exception()) - return; + stubframe = FakeStubFrame::build(CHECK_0); thread->push_zero_frame(stubframe); // Fill in the skeleton frames @@ -236,12 +232,8 @@ // Pop our dummy frame thread->pop_zero_frame(); - // Jump into the interpreter -#ifdef CC_INTERP - CppInterpreter::main_loop(number_of_frames - 1, thread); -#else - Unimplemented(); -#endif // CC_INTERP + // Fall back into the interpreter + return number_of_frames; } FakeStubFrame* FakeStubFrame::build(TRAPS) { diff -r f50bc2a9120e ports/hotspot/src/share/vm/shark/sharkRuntime.hpp --- a/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp Fri May 14 13:54:40 2010 +0100 @@ -1,6 +1,6 @@ /* * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2008, 2009 Red Hat, Inc. + * Copyright 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 @@ -79,5 +79,5 @@ public: static void dump(const char *name, intptr_t value); static bool is_subtype_of(klassOop check_klass, klassOop object_klass); - static void uncommon_trap(JavaThread* thread, int trap_request); + static int uncommon_trap(JavaThread* thread, int trap_request); }; diff -r f50bc2a9120e ports/hotspot/src/share/vm/shark/sharkStack.cpp --- a/ports/hotspot/src/share/vm/shark/sharkStack.cpp Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkStack.cpp Fri May 14 13:54:40 2010 +0100 @@ -135,7 +135,7 @@ // Handle overflows builder()->SetInsertPoint(overflow); builder()->CreateCall(builder()->throw_StackOverflowError(), thread()); - builder()->CreateRetVoid(); + builder()->CreateRet(LLVMValue::jint_constant(0)); builder()->SetInsertPoint(abi_ok); } diff -r f50bc2a9120e ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri May 14 11:16:36 2010 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri May 14 13:54:40 2010 +0100 @@ -594,11 +594,11 @@ void SharkTopLevelBlock::do_trap(int trap_request) { decache_for_trap(); - builder()->CreateCall2( - builder()->uncommon_trap(), - thread(), - LLVMValue::jint_constant(trap_request)); - builder()->CreateRetVoid(); + builder()->CreateRet( + builder()->CreateCall2( + builder()->uncommon_trap(), + thread(), + LLVMValue::jint_constant(trap_request))); } void SharkTopLevelBlock::call_register_finalizer(Value *receiver) { @@ -677,7 +677,7 @@ PointerType::getUnqual(SharkType::to_stackType(type)))); } - builder()->CreateRetVoid(); + builder()->CreateRet(LLVMValue::jint_constant(0)); } void SharkTopLevelBlock::do_arraylength() { @@ -1203,7 +1203,25 @@ // Make the call decache_for_Java_call(call_method); - builder()->CreateCall3(entry_point, callee, base_pc, thread()); + Value *deoptimized_frames = builder()->CreateCall3( + entry_point, callee, base_pc, thread()); + + // If the callee got deoptimized then reexecute in the interpreter + BasicBlock *reexecute = function()->CreateBlock("reexecute"); + BasicBlock *call_completed = function()->CreateBlock("call_completed"); + builder()->CreateCondBr( + builder()->CreateICmpNE(deoptimized_frames, LLVMValue::jint_constant(0)), + reexecute, call_completed); + + builder()->SetInsertPoint(reexecute); + builder()->CreateCall2( + builder()->deoptimized_entry_point(), + builder()->CreateSub(deoptimized_frames, LLVMValue::jint_constant(1)), + thread()); + builder()->CreateBr(call_completed); + + // Cache after the call + builder()->SetInsertPoint(call_completed); cache_after_Java_call(call_method); // Check for pending exceptions From ahughes at redhat.com Fri May 14 06:24:19 2010 From: ahughes at redhat.com (Andrew John Hughes) Date: Fri, 14 May 2010 14:24:19 +0100 Subject: New calling convention for Zero and Shark In-Reply-To: <20100514130506.GA3438@redhat.com> References: <20100514130506.GA3438@redhat.com> Message-ID: On 14 May 2010 14:05, Gary Benson wrote: > Hi all, > > This commit fixes PR icedtea/484, a bug where the native code for > deoptimized methods could be freed when in fact they were still on > the stack and waiting to return. > > To make this change I have had to change the calling convention > within Zero and Shark. ?All method entries (the C function that > executes the method) now return an integer which is the number > of deoptimized frames they have left on the stack. ?Whenever a > method is called it is now the caller's responsibility to check > whether frames have been deoptimized and reenter the interpreter > if they have. > > The ARM interpreter needs updating to follow the new convention. > I have made a note of this in zeroshark.make, where the code that > enables the ARM interpreter is currently commented out. > > Cheers, > Gary > > -- > http://gbenson.net/ > These descriptions are very useful, but could you include them as part of the commit message? They'll still get e-mailed out (as part of the commit) and we then have the description in Mercurial with the patch, rather than having to look it up in the mailing list archives for each patch. Thanks, -- Andrew :-) Free Java Software Engineer Red Hat, Inc. (http://www.redhat.com) Support Free Java! Contribute to GNU Classpath and the OpenJDK http://www.gnu.org/software/classpath http://openjdk.java.net PGP Key: 94EFD9D8 (http://subkeys.pgp.net) Fingerprint: F8EF F1EA 401E 2E60 15FA 7927 142C 2591 94EF D9D8 From gbenson at redhat.com Fri May 14 06:39:15 2010 From: gbenson at redhat.com (Gary Benson) Date: Fri, 14 May 2010 14:39:15 +0100 Subject: New calling convention for Zero and Shark In-Reply-To: References: <20100514130506.GA3438@redhat.com> Message-ID: <20100514133915.GB3438@redhat.com> Andrew John Hughes wrote: > On 14 May 2010 14:05, Gary Benson wrote: > > This commit fixes PR icedtea/484, a bug where the native code for > > deoptimized methods could be freed when in fact they were still on > > the stack and waiting to return. > > > > To make this change I have had to change the calling convention > > within Zero and Shark. ?All method entries (the C function that > > executes the method) now return an integer which is the number > > of deoptimized frames they have left on the stack. ?Whenever a > > method is called it is now the caller's responsibility to check > > whether frames have been deoptimized and reenter the interpreter > > if they have. > > > > The ARM interpreter needs updating to follow the new convention. > > I have made a note of this in zeroshark.make, where the code that > > enables the ARM interpreter is currently commented out. > > These descriptions are very useful, but could you include them as > part of the commit message? They'll still get e-mailed out (as part > of the commit) and we then have the description in Mercurial with > the patch, rather than having to look it up in the mailing list > archives for each patch. Ok. Cheers, Gary -- http://gbenson.net/ From xerxes at zafena.se Sun May 30 01:50:42 2010 From: xerxes at zafena.se (Xerxes Ranby) Date: Sun, 30 May 2010 10:50:42 +0200 Subject: Where can I get Patch for "Relocation out of range!" assertion In-Reply-To: References: Message-ID: <4C0226E2.8030409@zafena.se> Gordienko Evgueni-XPNG76 wrote: > Hi, > > I have > java version "1.6.0_18" > OpenJDK Runtime Environment (build 1.6.0_18-b18) > OpenJDK Shark VM (build 14.0-b16, mixed mode) > > LLVM used for JIT build is 2.8 > > on PowerPC linux. > > I have: > # java: PPCJITInfo.cpp:399: virtual void > llvm::PPCJITInfo::relocate(void*, llvm::MachineRelocation*, unsigned > int, unsigned ch > ar*): Assertion `ResultPtr >= -(1 << 23) && ResultPtr < (1 << 23) && > "Relocation out of range!"' failed. > Stack dump: > 0. Running pass 'PowerPC Machine Code Emitter' on function > '@"java.io.ObjectStreamClass::lookup"' > > > Where can I get patch for this LLVM issue? > > Thanks, > Evgueni > Hi Icedtea bugzilla problem-report 399 tracks this issue: http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=399 patches for LLVM to work around this issue for various LLVM versions are attached to the bugreport. Cheers and have a great day! Xerxes