From xerxes at zafena.se Thu Mar 4 04:13:02 2010 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Thu, 04 Mar 2010 13:13:02 +0100 Subject: RFC: [patch] Shark fix memory corruption bug when accessing mattr outside of defined scope. Message-ID: <4B8FA3CE.2020606@zafena.se> The memory used for mattr during sharkCompiler::sharkCompiler can have been reallocated before its contents are used because the args vector refers to the mattr memory outside of matts valid scope. The attached patch fixed this issue. If you have got hit by this bug then you will see shark exit early with an odd error messages like ": Unknown command line argument 't-failed-fuse-candidates'. Try: ' -help'" because LLVM are trying to parse reused memory for its command line arguments. Ok to push? Ok to push to icedtea6-1.7 release branch? 2010-03-04 Xerxes R?nby * ports/hotspot/src/share/vm/shark/sharkCompiler.cpp (sharkCompiler::sharkCompiler): Move mattr define to make its memory valid in the scope where it are used by the args vector. Cheers and have a great day! Xerxes -------------- next part -------------- A non-text attachment was scrubbed... Name: fix_shark_mattr_scope.patch Type: text/x-diff Size: 642 bytes Desc: not available Url : http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20100304/79331ef6/attachment.bin From xerxes at zafena.se Thu Mar 4 04:54:16 2010 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Thu, 04 Mar 2010 13:54:16 +0100 Subject: RFC: [patch] Shark fix memory corruption bug when accessing mattr outside of defined scope. In-Reply-To: <4B8FA3CE.2020606@zafena.se> References: <4B8FA3CE.2020606@zafena.se> Message-ID: <4B8FAD78.9090704@zafena.se> On 2010-03-04 13:13, Xerxes R?nby wrote: > The memory used for mattr during sharkCompiler::sharkCompiler can have > been reallocated before its contents are used because the args vector > refers to the mattr memory outside of matts valid scope. The attached > patch fixed this issue. > > If you have got hit by this bug then you will see shark exit early with > an odd error messages like > ": Unknown command line argument 't-failed-fuse-candidates'. Try: ' -help'" > because LLVM are trying to parse reused memory for its command line > arguments. > > Ok to push? > Ok to push to icedtea6-1.7 release branch? > > 2010-03-04 Xerxes R?nby > > * ports/hotspot/src/share/vm/shark/sharkCompiler.cpp > (sharkCompiler::sharkCompiler): Move mattr define to make its memory > valid in the scope where it are used by the args vector. > > Cheers and have a great day! > Xerxes > > > Commited as: http://icedtea.classpath.org/hg/release/icedtea6-1.7/rev/546f16ad97d5 and http://icedtea.classpath.org/hg/icedtea6/rev/c736cfc2dcb2 After codereview by gnu_andrew ower irc: (13.46.32) gnu_andrew: xranby, ok looks good to me Thanks Andrew for the review! Cheers Xerxes -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20100304/600c23de/attachment.html From gbenson at redhat.com Fri Mar 19 09:08:29 2010 From: gbenson at redhat.com (Gary Benson) Date: Fri, 19 Mar 2010 16:08:29 +0000 Subject: Shark updates Message-ID: <20100319160829.GD4543@redhat.com> Hi all, This commit updates icedtea6 to the latest Shark with the following fixes: - Correctly generate memory barriers on x86 (fixes volatile fields). - Throw an ArithmeticException on detecting a divide by zero. - Throw a ClassCastException when checkcast fails. - Work when the UseMembar command line option is specified. - Detect and handle stack overflows. - Bail out to the interpreter if a method tries to access a static variable before that class's has completed. - Do not attempt to handle exceptions thrown by monitorexit (fixes PR IcedTea/449). - Made (some) debug options available in production builds. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 3fa0b8d84878 -r 9eb6324a42a6 ChangeLog --- a/ChangeLog Fri Mar 19 14:47:16 2010 +0000 +++ b/ChangeLog Fri Mar 19 15:50:36 2010 +0000 @@ -1,3 +1,62 @@ +2010-03-19 Gary Benson + + * ports/hotspot/src/cpu/zero/vm/disassembler_zero.hpp + (Disassembler::pd_instruction_alignment): Return a usable default. + (Disassembler::pd_cpu_opts): Likewise. + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::do_field_access): Indentation fixes. + * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp + (SharkBuilder::throw_ArithmeticException): New method. + (SharkBuilder::throw_ClassCastException): Likewise. + (SharkBuilder::frame_address): Likewise. + (SharkBuilder::CreateGetFrameAddress): Likewise. + * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp + (SharkBuilder::throw_ArithmeticException): New method. + (SharkBuilder::throw_ClassCastException): Likewise. + (SharkBuilder::frame_address): Likewise. + (SharkBuilder::CreateGetFrameAddress): Likewise. + (SharkBuilder::CreateMemoryBarrier): Actually do something on x86. + * ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp + (SharkNativeWrapper::initialize): Implemented UseMembar code. + * ports/hotspot/src/share/vm/shark/sharkRuntime.hpp + (SharkRuntime::throw_ArithmeticException): New method. + (SharkRuntime::throw_ClassCastException): Likewise. + * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp + (SharkRuntime::throw_ArithmeticException): New method. + (SharkRuntime::throw_ClassCastException): Likewise. + * ports/hotspot/src/share/vm/shark/sharkStack.hpp + (SharkStack::initialize): Added setup_sp_and_method parameter. + (SharkStack::CreateStackOverflowCheck): New method. + (SharkStack::CreateCheckStack): Likewise. + (SharkStack::interpreter_entry_point): Likewise. + (SharkStackWithNormalFrame::interpreter_entry_point): Likewise. + (SharkStackWithNativeFrame::interpreter_entry_point): Likewise. + (SharkStack::CreateHardStackOverflowCheck): Removed. + (SharkStack::CreateSoftStackOverflowCheck): Likewise. + * ports/hotspot/src/share/vm/shark/sharkStack.cpp + (SharkStack::initialize): Added setup_sp_and_method parameter, + and changed to use new stack overflow detection code. + (SharkStack::CreateStackOverflowCheck): New method. + (SharkStack::CreateCheckStack): Likewise. + (SharkStack::CreateHardStackOverflowCheck): Removed. + (SharkStack::CreateSoftStackOverflowCheck): Likewise. + (SharkStackWithNormalFrame::interpreter_entry_point): Likewise. + (SharkStackWithNativeFrame::interpreter_entry_point): Likewise. + (SharkStackWithNormalFrame::SharkStackWithNormalFrame): Updated. + (SharkStackWithNativeFrame::SharkStackWithNativeFrame): Likewise. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::static_field_ok_in_clinit): New method. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::scan_for_traps): New trap. + (SharkTopLevelBlock::static_field_ok_in_clinit): New method. + (SharkTopLevelBlock::zero_check_value): Throw arithmetic exception + for divide by zero. + (SharkTopLevelBlock::do_full_instance_check): Throw class cast + exception. + (SharkTopLevelBlock::do_monitorexit): Do not handle exceptions. + * ports/hotspot/src/share/vm/shark/shark_globals.hpp: + Make debugging options available in product builds. + 2010-03-19 Pavel Tisnovsky * patches/icedtea-sh4-support.patch: removed duplicated diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/cpu/zero/vm/disassembler_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/disassembler_zero.hpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/cpu/zero/vm/disassembler_zero.hpp Fri Mar 19 15:50:36 2010 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2007 Red Hat, Inc. + * Copyright 2007, 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,13 +23,10 @@ * */ -// The disassembler prints out zero code annotated -// with Java specific information. - static int pd_instruction_alignment() { - ShouldNotCallThis(); + return 1; } static const char* pd_cpu_opts() { - ShouldNotCallThis(); + return ""; } diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/share/vm/shark/sharkBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Fri Mar 19 15:50:36 2010 +0000 @@ -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 @@ -1043,18 +1043,20 @@ if (is_get) { Value *field_value = builder()->CreateLoad(addr); - if (field_type != stack_type) - field_value = builder()->CreateIntCast( - field_value, stack_type, basic_type != T_CHAR); + if (field_type != stack_type) { + field_value = builder()->CreateIntCast( + field_value, stack_type, basic_type != T_CHAR); + } value = SharkValue::create_generic(field->type(), field_value, false); } else { Value *field_value = value->generic_value(); - if (field_type != stack_type) + if (field_type != stack_type) { field_value = builder()->CreateIntCast( field_value, field_type, basic_type != T_CHAR); + } builder()->CreateStore(field_value, addr); diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/share/vm/shark/sharkBuilder.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Fri Mar 19 15:50:36 2010 +0000 @@ -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 @@ -224,11 +224,21 @@ return make_function((address) SafepointSynchronize::block, "T", "v"); } +Value* SharkBuilder::throw_ArithmeticException() { + return make_function( + (address) SharkRuntime::throw_ArithmeticException, "TCi", "v"); +} + Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() { return make_function( (address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v"); } +Value* SharkBuilder::throw_ClassCastException() { + return make_function( + (address) SharkRuntime::throw_ClassCastException, "TCi", "v"); +} + Value* SharkBuilder::throw_NullPointerException() { return make_function( (address) SharkRuntime::throw_NullPointerException, "TCi", "v"); @@ -374,6 +384,10 @@ "Xxx", "x"); } +Value* SharkBuilder::frame_address() { + return make_function("llvm.frameaddress", "i", "C"); +} + Value* SharkBuilder::memory_barrier() { return make_function( #ifdef ARM @@ -414,13 +428,17 @@ return CreateCall3(cmpxchg_ptr(), dst, compare_value, exchange_value); } +CallInst* SharkBuilder::CreateGetFrameAddress() { + return CreateCall(frame_address(), LLVMValue::jint_constant(0)); +} + CallInst *SharkBuilder::CreateMemoryBarrier(int flags) { Value *args[] = { LLVMValue::bit_constant((flags & BARRIER_LOADLOAD) ? 1 : 0), LLVMValue::bit_constant((flags & BARRIER_LOADSTORE) ? 1 : 0), LLVMValue::bit_constant((flags & BARRIER_STORELOAD) ? 1 : 0), LLVMValue::bit_constant((flags & BARRIER_STORESTORE) ? 1 : 0), - LLVMValue::bit_constant(0)}; + LLVMValue::bit_constant(1)}; return CreateCall(memory_barrier(), args, args + 5); } diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/share/vm/shark/sharkBuilder.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Fri Mar 19 15:50:36 2010 +0000 @@ -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 @@ -96,7 +96,9 @@ llvm::Value* multianewarray(); llvm::Value* register_finalizer(); llvm::Value* safepoint(); + llvm::Value* throw_ArithmeticException(); llvm::Value* throw_ArrayIndexOutOfBoundsException(); + llvm::Value* throw_ClassCastException(); llvm::Value* throw_NullPointerException(); // Intrinsics and external functions, part 2: High-level non-VM calls. @@ -145,6 +147,7 @@ private: llvm::Value* cmpxchg_int(); llvm::Value* cmpxchg_ptr(); + llvm::Value* frame_address(); llvm::Value* memory_barrier(); llvm::Value* memset(); llvm::Value* unimplemented(); @@ -159,6 +162,7 @@ llvm::CallInst* CreateCmpxchgPtr(llvm::Value* exchange_value, llvm::Value* dst, llvm::Value* compare_value); + llvm::CallInst* CreateGetFrameAddress(); llvm::CallInst* CreateMemoryBarrier(int flags); llvm::CallInst* CreateMemset(llvm::Value* dst, llvm::Value* value, diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp --- a/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Fri Mar 19 15:50:36 2010 +0000 @@ -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 @@ -218,7 +218,7 @@ // Make sure new state is visible in the GC thread if (os::is_MP()) { if (UseMembar) - { Unimplemented(); } + builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD); else CreateWriteMemorySerializePage(); } diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/share/vm/shark/sharkRuntime.cpp --- a/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Fri Mar 19 15:50:36 2010 +0000 @@ -133,6 +133,15 @@ instanceKlass::register_finalizer(instanceOop(object), CHECK); JRT_END +JRT_ENTRY(void, SharkRuntime::throw_ArithmeticException(JavaThread* thread, + const char* file, + int line)) + Exceptions::_throw_msg( + thread, file, line, + vmSymbols::java_lang_ArithmeticException(), + ""); +JRT_END + JRT_ENTRY(void, SharkRuntime::throw_ArrayIndexOutOfBoundsException( JavaThread* thread, const char* file, @@ -146,6 +155,15 @@ msg); JRT_END +JRT_ENTRY(void, SharkRuntime::throw_ClassCastException(JavaThread* thread, + const char* file, + int line)) + Exceptions::_throw_msg( + thread, file, line, + vmSymbols::java_lang_ClassCastException(), + ""); +JRT_END + JRT_ENTRY(void, SharkRuntime::throw_NullPointerException(JavaThread* thread, const char* file, int line)) diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/share/vm/shark/sharkRuntime.hpp --- a/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp Fri Mar 19 15:50:36 2010 +0000 @@ -43,10 +43,16 @@ static void register_finalizer(JavaThread* thread, oop object); + static void throw_ArithmeticException(JavaThread* thread, + const char* file, + int line); static void throw_ArrayIndexOutOfBoundsException(JavaThread* thread, const char* file, int line, int index); + static void throw_ClassCastException(JavaThread* thread, + const char* file, + int line); static void throw_NullPointerException(JavaThread* thread, const char* file, int line); diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/share/vm/shark/sharkStack.cpp --- a/ports/hotspot/src/share/vm/shark/sharkStack.cpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkStack.cpp Fri Mar 19 15:50:36 2010 +0000 @@ -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 @@ -28,9 +28,7 @@ using namespace llvm; -void SharkStack::initialize(Value* method) { - bool setup_sp_and_method = (method != NULL); - +void SharkStack::initialize(Value* method, bool setup_sp_and_method) { int locals_words = max_locals(); int extra_locals = locals_words - arg_size(); int header_words = SharkFrame::header_words; @@ -44,7 +42,7 @@ Value *stack_pointer = builder()->CreateSub( CreateLoadStackPointer(), LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize)); - CreateHardStackOverflowCheck(stack_pointer); + CreateStackOverflowCheck(stack_pointer, method); if (setup_sp_and_method) CreateStoreStackPointer(stack_pointer); @@ -94,35 +92,63 @@ builder()->CreateStore(CreateLoadFramePointer(), fp); CreateStoreFramePointer( builder()->CreatePtrToInt(fp, SharkType::intptr_type())); - - // Check we're not about to run out of stack - CreateSoftStackOverflowCheck(stack_pointer); } -// Check that the stack will not overflow before a stack pointer -// update. Overflows here are problematic as we haven't yet -// created a frame, so it's not clear how to report the error. -// http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=249 -void SharkStack::CreateHardStackOverflowCheck(Value* sp) { - BasicBlock *overflow = CreateBlock("stack_overflow"); - BasicBlock *no_overflow = CreateBlock("no_overflow"); +// 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"); + BasicBlock *abi_ok = CreateBlock("abi_stack_ok"); + BasicBlock *zero_ok = CreateBlock("zero_stack_ok"); - builder()->CreateCondBr( - builder()->CreateICmpULT(sp, stack_base()), - overflow, no_overflow); + // 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()->CreatePtrToInt( + builder()->CreateGetFrameAddress(), + SharkType::intptr_type(), + "abi_pointer"), + 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 builder()->SetInsertPoint(overflow); - builder()->CreateUnimplemented(__FILE__, __LINE__); - builder()->CreateUnreachable(); + 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()->CreateRetVoid(); - builder()->SetInsertPoint(no_overflow); + builder()->SetInsertPoint(zero_ok); } -// Check that a stack overflow is not imminent, throwing a -// StackOverflowError if it is while we still have the stack -// in which to do so. -void SharkStack::CreateSoftStackOverflowCheck(Value* sp) { - // XXX see CppInterpreter::stack_overflow_imminent +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); } Value* SharkStack::CreatePopFrame(int result_slots) { @@ -176,12 +202,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(PRODUCT_ONLY(NULL) NOT_PRODUCT(method)); + initialize(method, NOT_PRODUCT(true) PRODUCT_ONLY(false)); } SharkStackWithNativeFrame::SharkStackWithNativeFrame(SharkNativeWrapper* wrp, Value* method) : SharkStack(wrp), _wrapper(wrp) { - initialize(method); + initialize(method, true); } int SharkStackWithNormalFrame::arg_size() const { @@ -218,3 +244,10 @@ BasicBlock* SharkStackWithNativeFrame::CreateBlock(const char* name) const { return wrapper()->CreateBlock(name); } + +address SharkStackWithNormalFrame::interpreter_entry_point() const { + return (address) CppInterpreter::normal_entry; +} +address SharkStackWithNativeFrame::interpreter_entry_point() const { + return (address) CppInterpreter::native_entry; +} diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/share/vm/shark/sharkStack.hpp --- a/ports/hotspot/src/share/vm/shark/sharkStack.hpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkStack.hpp Fri Mar 19 15:50:36 2010 +0000 @@ -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 @@ -40,11 +40,16 @@ : SharkCompileInvariants(parent) {} protected: - void initialize(llvm::Value* method); + void initialize(llvm::Value* method, bool setup_sp_and_method); protected: - void CreateHardStackOverflowCheck(llvm::Value* sp); - void CreateSoftStackOverflowCheck(llvm::Value* sp); + void CreateStackOverflowCheck(llvm::Value* sp, llvm::Value* method); + + private: + void CreateCheckStack(llvm::Value* base, + llvm::Value* sp, + llvm::BasicBlock* overflow, + llvm::BasicBlock* no_overflow); // Properties of the method being compiled protected: @@ -57,6 +62,10 @@ protected: virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0; + // Interpreter entry point for bailouts + protected: + virtual address interpreter_entry_point() const = 0; + // Interface with the Zero stack private: llvm::Value* zero_stack() const { @@ -235,6 +244,10 @@ // BasicBlock creation private: llvm::BasicBlock* CreateBlock(const char* name = "") const; + + // Interpreter entry point for bailouts + private: + address interpreter_entry_point() const; }; class SharkStackWithNativeFrame : public SharkStack { @@ -261,4 +274,8 @@ // BasicBlock creation private: llvm::BasicBlock* CreateBlock(const char* name = "") const; + + // Interpreter entry point for bailouts + private: + address interpreter_entry_point() const; }; diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri Mar 19 15:50:36 2010 +0000 @@ -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 @@ -72,6 +72,18 @@ Deoptimization::Action_none), bci()); return; } + + // Bail out if we are trying to access a static variable + // before the class initializer has completed. + if (!is_field && !field->holder()->is_initialized()) { + if (!static_field_ok_in_clinit(field)) { + set_trap( + Deoptimization::make_trap_request( + Deoptimization::Reason_uninitialized, + Deoptimization::Action_reinterpret), bci()); + return; + } + } break; case Bytecodes::_invokestatic: @@ -139,6 +151,31 @@ } } +bool SharkTopLevelBlock::static_field_ok_in_clinit(ciField* field) { + assert(field->is_static(), "should be"); + + // This code is lifted pretty much verbatim from C2's + // Parse::static_field_ok_in_clinit() in parse3.cpp. + bool access_OK = false; + if (target()->holder()->is_subclass_of(field->holder())) { + if (target()->is_static()) { + if (target()->name() == ciSymbol::class_initializer_name()) { + // It's OK to access static fields from the class initializer + access_OK = true; + } + } + else { + if (target()->name() == ciSymbol::object_initializer_name()) { + // It's also OK to access static fields inside a constructor, + // because any thread calling the constructor must first have + // synchronized on the class by executing a "new" bytecode. + access_OK = true; + } + } + } + return access_OK; +} + SharkState* SharkTopLevelBlock::entry_state() { if (_entry_state == NULL) { assert(needs_phis(), "should do"); @@ -329,7 +366,13 @@ EX_CHECK_NONE); } else { - builder()->CreateUnimplemented(__FILE__, __LINE__); + call_vm( + builder()->throw_ArithmeticException(), + builder()->CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) __FILE__), + PointerType::getUnqual(SharkType::jbyte_type())), + LLVMValue::jint_constant(__LINE__), + EX_CHECK_NONE); } Value *pending_exception = get_pending_exception(); @@ -1344,9 +1387,21 @@ success, failure); builder()->SetInsertPoint(failure); - builder()->CreateUnimplemented(__FILE__, __LINE__); - builder()->CreateUnreachable(); + SharkState *saved_state = current_state()->copy(); + call_vm( + builder()->throw_ClassCastException(), + builder()->CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) __FILE__), + PointerType::getUnqual(SharkType::jbyte_type())), + LLVMValue::jint_constant(__LINE__), + EX_CHECK_NONE); + + Value *pending_exception = get_pending_exception(); + clear_pending_exception(); + handle_exception(pending_exception, EX_CHECK_FULL); + + set_current_state(saved_state); builder()->SetInsertPoint(success); push(SharkValue::create_generic(klass, object, false)); } @@ -1652,7 +1707,7 @@ void SharkTopLevelBlock::do_monitorexit() { pop(); // don't need this (monitors are block structured) - release_lock(EX_CHECK_FULL); + release_lock(EX_CHECK_NO_CATCH); } void SharkTopLevelBlock::acquire_lock(Value *lockee, int exception_action) { diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Fri Mar 19 15:50:36 2010 +0000 @@ -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 @@ -122,6 +122,9 @@ private: void scan_for_traps(); + private: + bool static_field_ok_in_clinit(ciField* field); + // Entry state private: bool _entered; diff -r 3fa0b8d84878 -r 9eb6324a42a6 ports/hotspot/src/share/vm/shark/shark_globals.hpp --- a/ports/hotspot/src/share/vm/shark/shark_globals.hpp Fri Mar 19 14:47:16 2010 +0000 +++ b/ports/hotspot/src/share/vm/shark/shark_globals.hpp Fri Mar 19 15:50:36 2010 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2000-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 @@ -23,10 +23,6 @@ * */ -// -// Defines all global flags used by the shark compiler. -// - #define SHARK_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \ \ product(intx, MaxNodeLimit, 65000, \ @@ -40,19 +36,19 @@ develop(ccstr, SharkPrintTypeflowOf, NULL, \ "Print the typeflow of the specified method") \ \ - develop(ccstr, SharkPrintBitcodeOf, NULL, \ + diagnostic(ccstr, SharkPrintBitcodeOf, NULL, \ "Print the LLVM bitcode of the specified method") \ \ - develop(ccstr, SharkPrintAsmOf, NULL, \ + diagnostic(ccstr, SharkPrintAsmOf, NULL, \ "Print the asm of the specified method") \ \ develop(bool, SharkTraceBytecodes, false, \ "Trace bytecode compilation") \ \ - develop(bool, SharkTraceInstalls, false, \ + diagnostic(bool, SharkTraceInstalls, false, \ "Trace method installation") \ \ - develop(bool, SharkPerformanceWarnings, false, \ + diagnostic(bool, SharkPerformanceWarnings, false, \ "Warn about things that could be made faster") \ SHARK_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)