|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
Native method wrapper generationHi all,
This commit adds native wrapper generation to Shark. It also removes support for LLVM < 2.6, because the new code requires it. I'll write this up in more detail tomorrow with some benchmarks. Cheers, Gary -- http://gbenson.net/ diff -r b3d03017bdef ChangeLog --- a/ChangeLog Wed Nov 11 10:50:38 2009 -0500 +++ b/ChangeLog Wed Nov 11 16:21:16 2009 +0000 @@ -1,3 +1,186 @@ +2009-11-11 Gary Benson <gbenson@...> + + * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp + (CppInterpreter::native_entry): Add invocation counting for + non-synchronized native methods. + + * ports/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp + (SharedRuntime::generate_native_wrapper): Implemented. + + * ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp + (SharkFrame): Made friendly with SharkStack. Snubbed + SharkFunction. + + * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp + (SharkBuilder::SharkBuilder): Removed module argument. + (SharkBuilder::_module): Removed. + (SharkBuilder::module): Likewise. + (SharkBuilder::check_special_condition_for_native_trans): New method. + (SharkBuilder::CreateInlineOop): New method with jobject argument. + * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp + (SharkBuilder::SharkBuilder): Removed module argument, and changed + to use Shark context instead of global context. + (SharkBuilder::make_type): Updated for new SharkType. + (SharkBuilder::make_function): Use SharkContext for resolution. + (SharkBuilder::check_special_condition_for_native_trans): New method. + (SharkBuilder::CreateDump): Removed support for LLVM < 2.6. + (SharkBuilder::CreateBlock): Likewise. + (SharkBuilder::CreateInlineOop): Changed object argument type. + + * ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp + (SharkDecacher::oopmap_slot_munge): Defer to SharkStack method. + (SharkDecacher::slot2reg): Likewise. + * ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp + (SharkDecacher::start_frame): Use new SharkStack code. + (SharkDecacher::start_stack): Likewise. + (SharkDecacher::process_pc_slot): Likewise. + (SharkOSREntryCacher::process_monitor): Likewise. + (SharkDecacher::write_value_to_frame): Likewise. + (SharkCacher::read_value_from_frame): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp + (SharkCodeBuffer::SharkCodeBuffer): Wrap a MacroAssembler + instead of creating one along with a CodeBuffer. + (SharkCodeBuffer::_cb): Removed. + (SharkCodeBuffer::_cb): Likewise. + (SharkCodeBuffer::inline_oop): Changed object argument type. + + * ports/hotspot/src/share/vm/shark/sharkCompiler.hpp + (SharkCompiler::supports_native): Return true instead of false. + (SharkCompiler::generate_native_wrapper): New method. + (SharkCompiler::_module): Removed. + (SharkCompiler::module): Likewise. + (SharkCompiler::_normal_context): New field. + (SharkCompiler::_native_context): Likewise. + (SharkCompiler::_execution_engine_lock): Likewise. + (SharkCompiler::context): New method. + (SharkCompiler::execution_engine_lock): Likewise. + (SharkCompiler::memory_manager): Added assertion. + (SharkCompiler::execution_engine): Likewise. + (SharkCompiler::compiler): New method. + (SharkCompiler::generate_native_code): Likewise. + (SharkCompiler::free_queued_methods): Likewise. + * ports/hotspot/src/share/vm/shark/sharkCompiler.cpp + (SharkCompiler::SharkCompiler): Create the lock and the two + contexts. Removed support for LLVM < 2.6. + (SharkCompiler::compile_method): Create the HotSpot code buffer + and macro assembler, and defer native code generation to new + method SharkCompiler::generate_native_code(). + (SharkCompiler::generate_native_wrapper): New method. + (SharkCompiler::generate_native_code): Likewise. + (SharkCompiler::free_compiled_method): New implementation. + (SharkCompiler::free_queued_methods): New method. + + * ports/hotspot/src/share/vm/shark/sharkEntry.hpp + (SharkEntry::_context): New field. + (SharkEntry::context): New method. + (SharkEntry::set_context): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkFunction.hpp + (SharkFunction::build): Removed compiler argument. + (SharkFunction::SharkFunction): Likewise. + (SharkFunction::_stack): New field. + (SharkFunction::stack): New method. + (SharkFunction::CreateBlock): Removed support for LLVM < 2.6. + (SharkFunction::_zero_stack_base): Removed. + (SharkFunction::_zero_stack_pointer_addr): Likewise. + (SharkFunction::_zero_frame_pointer_addr): Likewise. + (SharkFunction::zero_stack_base): Likewise. + (SharkFunction::zero_stack_pointer_addr): Likewise. + (SharkFunction::zero_frame_pointer_addr): Likewise. + (SharkFunction::CreateInitZeroStack): Likewise. + (SharkFunction::CreateLoadZeroStackPointer): Likewise. + (SharkFunction::CreateStoreZeroStackPointer): Likewise. + (SharkFunction::CreateLoadZeroFramePointer): Likewise. + (SharkFunction::CreateStoreZeroFramePointer): Likewise. + (SharkFunction::CreateStackOverflowCheck): Likewise. + (SharkFunction::CreatePushFrame): Likewise. + (SharkFunction::CreatePopFrame): Likewise. + (SharkFunction::_frame): Likewise. + (SharkFunction::CreateAddressOfFrameEntry): Likewise. + (SharkFunction::CreateBuildFrame): Likewise. + (SharkFunction::_extended_frame_size): Likewise. + (SharkFunction::_stack_slots_offset): Likewise. + (SharkFunction::_monitors_slots_offset): Likewise. + (SharkFunction::_oop_tmp_slot_offset): Likewise. + (SharkFunction::_method_slot_offset): Likewise. + (SharkFunction::_pc_slot_offset): Likewise. + (SharkFunction::_locals_slots_offset): Likewise. + (SharkFunction::extended_frame_size): Likewise. + (SharkFunction::oopmap_frame_size): Likewise. + (SharkFunction::stack_slots_offset): Likewise. + (SharkFunction::monitors_slots_offset): Likewise. + (SharkFunction::oop_tmp_slot_offset): Likewise. + (SharkFunction::method_slot_offset): Likewise. + (SharkFunction::pc_slot_offset): Likewise. + (SharkFunction::locals_slots_offset): Likewise. + (SharkFunction::monitor_offset): Likewise. + (SharkFunction::monitor_object_offset): Likewise. + (SharkFunction::monitor_header_offset): Likewise. + (SharkFunction::monitor_addr): Likewise. + (SharkFunction::monitor_object_addr): Likewise. + (SharkFunction::monitor_header_addr): Likewise. + * ports/hotspot/src/share/vm/shark/sharkFunction.cpp + (SharkFunction::initialize): Defer stack frame creation to new + SharkStack code. + (SharkFunction::CreateInitZeroStack): Removed. + (SharkFunction::CreateStackOverflowCheck): Likewise. + (SharkFunction::CreatePushFrame): Likewise. + (SharkFunction::CreatePopFrame): Likewise. + (SharkFunction::CreateBuildFrame): Likewise. + (SharkFunction::CreateAddressOfFrameEntry): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkInvariants.hpp + (SharkCompileInvariants::SharkCompileInvariants): Removed + compiler argument. + (SharkTargetInvariants::SharkTargetInvariants): Likewise. + (SharkCompileInvariants::_compiler): Removed. + (SharkCompileInvariants::env): Added assertion. + + * ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp + (SharkStateScanner::SharkStateScanner): Updated. + (SharkStateScanner::_function): Removed. + (SharkStateScanner::function): Likewise. + (SharkStateScanner::_stack): New field. + (SharkStateScanner::stack): New method. + * ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp + (SharkStateScanner::scan): Use new SharkStack code. + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::stack): New method. + (SharkTopLevelBlock::set_last_Java_frame): Removed. + (SharkTopLevelBlock::reset_last_Java_frame): Likewise. + (SharkTopLevelBlock::call_vm): Use new SharkStack code. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::handle_return): Likewise. + (SharkTopLevelBlock::do_multianewarray): Likewise. + (SharkTopLevelBlock::acquire_lock): Likewise. + (SharkTopLevelBlock::release_lock): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkType.hpp: + Defer everything to new SharkContext code. + * ports/hotspot/src/share/vm/shark/sharkType.cpp: Removed. + + * ports/hotspot/src/share/vm/shark/llvmHeaders.hpp: + Removed support for LLVM < 2.6. + * ports/hotspot/src/share/vm/shark/llvmValue.hpp + (LLVMValue::jfloat_constant): Likewise. + (LLVMValue::jdouble_constant): Likewise. + (LLVMValue::bit_constant): Likewise. + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::parse_bytecode): Likewise. + * ports/hotspot/src/share/vm/shark/sharkMemoryManager.hpp: Likewise. + * ports/hotspot/src/share/vm/shark/sharkMemoryManager.cpp: Likewise. + + * ports/hotspot/src/share/vm/shark/sharkContext.hpp: New file. + * ports/hotspot/src/share/vm/shark/sharkContext.cpp: Likewise. + * ports/hotspot/src/share/vm/shark/sharkNativeWrapper.hpp: Likewise. + * ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp: Likewise. + * ports/hotspot/src/share/vm/shark/sharkStack.hpp: Likewise. + * ports/hotspot/src/share/vm/shark/sharkStack.cpp: Likewise. + + * ports/hotspot/src/share/vm/includeDB_shark: Updated. + 2009-11-11 Gary Benson <gbenson@...> PR icedtea/324: diff -r b3d03017bdef ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp --- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -204,6 +204,20 @@ goto unwind_and_return; } + // Update the invocation counter + if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) { + thread->set_do_not_unlock(); + InvocationCounter *counter = method->invocation_counter(); + counter->increment(); + if (counter->reached_InvocationLimit()) { + CALL_VM_NOCHECK( + InterpreterRuntime::frequency_counter_overflow(thread, NULL)); + if (HAS_PENDING_EXCEPTION) + goto unwind_and_return; + } + thread->clr_do_not_unlock(); + } + // Lock if necessary BasicObjectLock *monitor; monitor = NULL; diff -r b3d03017bdef ports/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp --- a/ports/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -61,7 +61,14 @@ BasicType *in_sig_bt, VMRegPair *in_regs, BasicType ret_type) { +#ifdef SHARK + return SharkCompiler::compiler()->generate_native_wrapper(masm, + method, + in_sig_bt, + ret_type); +#else ShouldNotCallThis(); +#endif // SHARK } int Deoptimization::last_frame_adjust(int callee_parameters, diff -r b3d03017bdef ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2008 Red Hat, Inc. + * Copyright 2008, 2009 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,7 +41,7 @@ // | ... | class SharkFrame : public ZeroFrame { - friend class SharkFunction; + friend class SharkStack; private: SharkFrame() : ZeroFrame() { diff -r b3d03017bdef ports/hotspot/src/share/vm/includeDB_shark --- a/ports/hotspot/src/share/vm/includeDB_shark Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/includeDB_shark Wed Nov 11 16:21:16 2009 +0000 @@ -48,6 +48,8 @@ ciTypeFlow.hpp ciKlass.hpp ciTypeFlow.hpp ciMethodBlocks.hpp +cppInterpreter_<arch>.cpp shark_globals.hpp + compileBroker.cpp sharkCompiler.hpp globals.hpp shark_globals_<arch>.hpp @@ -55,10 +57,14 @@ globals.cpp shark_globals.hpp llvmValue.hpp llvmHeaders.hpp +llvmValue.hpp sharkContext.hpp llvmValue.hpp sharkType.hpp nmethod.cpp sharkCompiler.hpp +sharedRuntime_<arch>.cpp compileBroker.hpp +sharedRuntime_<arch>.cpp sharkCompiler.hpp + shark_globals.cpp shark_globals.hpp shark_globals.hpp shark_globals_<arch>.hpp @@ -95,7 +101,7 @@ sharkBuilder.cpp resourceArea.hpp sharkBuilder.cpp llvmHeaders.hpp sharkBuilder.cpp sharkBuilder.hpp -sharkBuilder.cpp sharkCompiler.hpp +sharkBuilder.cpp sharkContext.hpp sharkBuilder.cpp sharkRuntime.hpp sharkBuilder.cpp synchronizer.hpp sharkBuilder.cpp thread.hpp @@ -108,7 +114,6 @@ sharkBuilder.hpp llvmValue.hpp sharkBuilder.hpp sizes.hpp sharkBuilder.hpp sharkCodeBuffer.hpp -sharkBuilder.hpp sharkCompiler.hpp sharkBuilder.hpp sharkType.hpp sharkBuilder.hpp sharkValue.hpp sharkBuilder.hpp sharkEntry.hpp @@ -145,16 +150,29 @@ sharkCompiler.cpp sharkBuilder.hpp sharkCompiler.cpp sharkCodeBuffer.hpp sharkCompiler.cpp sharkCompiler.hpp +sharkCompiler.cpp sharkContext.hpp sharkCompiler.cpp sharkEntry.hpp sharkCompiler.cpp sharkFunction.hpp sharkCompiler.cpp sharkMemoryManager.hpp +sharkCompiler.cpp sharkNativeWrapper.hpp sharkCompiler.hpp abstractCompiler.hpp sharkCompiler.hpp ciEnv.hpp sharkCompiler.hpp ciMethod.hpp +sharkCompiler.hpp compileBroker.hpp sharkCompiler.hpp llvmHeaders.hpp sharkCompiler.hpp sharkMemoryManager.hpp +sharkContext.cpp arrayOop.hpp +sharkContext.cpp globalDefinitions.hpp +sharkContext.cpp llvmHeaders.hpp +sharkContext.cpp oop.hpp +sharkContext.cpp sharkContext.hpp + +sharkContext.hpp llvmHeaders.hpp +sharkContext.hpp sharkCompiler.hpp + +sharkConstant.cpp ciInstance.hpp sharkConstant.cpp ciStreams.hpp sharkConstant.cpp sharkBuilder.hpp sharkConstant.cpp sharkConstant.hpp @@ -186,7 +204,9 @@ sharkFunction.hpp llvmHeaders.hpp sharkFunction.hpp llvmValue.hpp sharkFunction.hpp sharkBuilder.hpp +sharkFunction.hpp sharkContext.hpp sharkFunction.hpp sharkInvariants.hpp +sharkFunction.hpp sharkStack.hpp sharkInliner.cpp allocation.hpp sharkInliner.cpp bytecodes.hpp @@ -229,8 +249,6 @@ sharkInvariants.hpp dependencies.hpp sharkInvariants.hpp llvmHeaders.hpp sharkInvariants.hpp sharkBuilder.hpp -sharkInvariants.hpp sharkCompiler.hpp -sharkInvariants.hpp sharkMemoryManager.hpp sharkMemoryManager.hpp llvmHeaders.hpp sharkMemoryManager.hpp sharkEntry.hpp @@ -239,6 +257,17 @@ sharkMemoryManager.cpp sharkEntry.hpp sharkMemoryManager.cpp sharkMemoryManager.hpp +sharkNativeWrapper.cpp llvmHeaders.hpp +sharkNativeWrapper.cpp sharkNativeWrapper.hpp +sharkNativeWrapper.cpp sharkType.hpp + +sharkNativeWrapper.hpp handles.hpp +sharkNativeWrapper.hpp llvmHeaders.hpp +sharkNativeWrapper.hpp sharkBuilder.hpp +sharkNativeWrapper.hpp sharkContext.hpp +sharkNativeWrapper.hpp sharkInvariants.hpp +sharkNativeWrapper.hpp sharkStack.hpp + sharkRuntime.cpp biasedLocking.hpp sharkRuntime.cpp deoptimization.hpp sharkRuntime.cpp llvmHeaders.hpp @@ -248,9 +277,20 @@ sharkRuntime.hpp allocation.hpp sharkRuntime.hpp llvmHeaders.hpp +sharkRuntime.hpp llvmValue.hpp sharkRuntime.hpp klassOop.hpp sharkRuntime.hpp thread.hpp +sharkStack.cpp llvmHeaders.hpp +sharkStack.cpp sharkFunction.hpp +sharkStack.cpp sharkNativeWrapper.hpp +sharkStack.cpp sharkStack.hpp +sharkStack.cpp sharkType.hpp + +sharkStack.hpp llvmHeaders.hpp +sharkStack.hpp sharkInvariants.hpp +sharkStack.hpp sharkType.hpp + sharkState.cpp allocation.hpp sharkState.cpp ciType.hpp sharkState.cpp ciTypeFlow.hpp @@ -279,6 +319,8 @@ sharkTopLevelBlock.cpp allocation.hpp sharkTopLevelBlock.cpp bytecodes.hpp sharkTopLevelBlock.cpp ciField.hpp +sharkTopLevelBlock.cpp ciInstance.hpp +sharkTopLevelBlock.cpp ciObjArrayKlass.hpp sharkTopLevelBlock.cpp ciStreams.hpp sharkTopLevelBlock.cpp ciType.hpp sharkTopLevelBlock.cpp ciTypeFlow.hpp @@ -307,17 +349,11 @@ sharkTopLevelBlock.hpp sharkState.hpp sharkTopLevelBlock.hpp sharkValue.hpp -sharkType.cpp arrayOop.hpp -sharkType.cpp globalDefinitions.hpp -sharkType.cpp llvmHeaders.hpp -sharkType.cpp oop.hpp -sharkType.cpp sharkEntry.hpp -sharkType.cpp sharkType.hpp - sharkType.hpp allocation.hpp sharkType.hpp ciType.hpp sharkType.hpp globalDefinitions.hpp sharkType.hpp llvmHeaders.hpp +sharkType.hpp sharkContext.hpp sharkValue.cpp ciType.hpp sharkValue.cpp llvmHeaders.hpp diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/llvmHeaders.hpp --- a/ports/hotspot/src/share/vm/shark/llvmHeaders.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/llvmHeaders.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -32,16 +32,12 @@ #include <llvm/DerivedTypes.h> #include <llvm/ExecutionEngine/ExecutionEngine.h> #include <llvm/Instructions.h> -#if SHARK_LLVM_VERSION >= 26 #include <llvm/LLVMContext.h> -#endif #include <llvm/Module.h> #include <llvm/ModuleProvider.h> #include <llvm/Support/IRBuilder.h> -#if SHARK_LLVM_VERSION >= 26 #include <llvm/System/Threading.h> #include <llvm/Target/TargetSelect.h> -#endif #include <llvm/Type.h> #include <llvm/ExecutionEngine/JITMemoryManager.h> #if SHARK_LLVM_VERSION < 27 diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/llvmValue.hpp --- a/ports/hotspot/src/share/vm/shark/llvmValue.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/llvmValue.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -39,19 +39,11 @@ } static llvm::ConstantFP* jfloat_constant(jfloat value) { -#if SHARK_LLVM_VERSION >= 26 - return llvm::ConstantFP::get(llvm::getGlobalContext(), llvm::APFloat(value)); -#else - return llvm::ConstantFP::get(SharkType::jfloat_type(), value); -#endif + return llvm::ConstantFP::get(SharkContext::current(), llvm::APFloat(value)); } static llvm::ConstantFP* jdouble_constant(jdouble value) { -#if SHARK_LLVM_VERSION >= 26 - return llvm::ConstantFP::get(llvm::getGlobalContext(), llvm::APFloat(value)); -#else - return llvm::ConstantFP::get(SharkType::jdouble_type(), value); -#endif + return llvm::ConstantFP::get(SharkContext::current(), llvm::APFloat(value)); } static llvm::ConstantPointerNull* null() { @@ -61,11 +53,7 @@ public: static llvm::ConstantInt* bit_constant(int value) { -#if SHARK_LLVM_VERSION >= 26 - return llvm::ConstantInt::get(llvm::Type::getInt1Ty(llvm::getGlobalContext()), value, false); -#else - return llvm::ConstantInt::get(llvm::Type::Int1Ty, value, false); -#endif + return llvm::ConstantInt::get(SharkType::bit_type(), value, false); } static llvm::ConstantInt* intptr_constant(intptr_t value) { diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -532,31 +532,19 @@ b = pop(); a = pop(); push(SharkValue::create_jfloat( -#if SHARK_LLVM_VERSION >= 26 builder()->CreateFAdd(a->jfloat_value(), b->jfloat_value()))); -#else - builder()->CreateAdd(a->jfloat_value(), b->jfloat_value()))); -#endif break; case Bytecodes::_fsub: b = pop(); a = pop(); push(SharkValue::create_jfloat( -#if SHARK_LLVM_VERSION >= 26 builder()->CreateFSub(a->jfloat_value(), b->jfloat_value()))); -#else - builder()->CreateSub(a->jfloat_value(), b->jfloat_value()))); -#endif break; case Bytecodes::_fmul: b = pop(); a = pop(); push(SharkValue::create_jfloat( -#if SHARK_LLVM_VERSION >= 26 builder()->CreateFMul(a->jfloat_value(), b->jfloat_value()))); -#else - builder()->CreateMul(a->jfloat_value(), b->jfloat_value()))); -#endif break; case Bytecodes::_fdiv: b = pop(); @@ -573,42 +561,26 @@ case Bytecodes::_fneg: a = pop(); push(SharkValue::create_jfloat( -#if SHARK_LLVM_VERSION >= 26 builder()->CreateFNeg(a->jfloat_value()))); -#else - builder()->CreateNeg(a->jfloat_value()))); -#endif break; case Bytecodes::_dadd: b = pop(); a = pop(); push(SharkValue::create_jdouble( -#if SHARK_LLVM_VERSION >= 26 builder()->CreateFAdd(a->jdouble_value(), b->jdouble_value()))); -#else - builder()->CreateAdd(a->jdouble_value(), b->jdouble_value()))); -#endif break; case Bytecodes::_dsub: b = pop(); a = pop(); push(SharkValue::create_jdouble( -#if SHARK_LLVM_VERSION >= 26 builder()->CreateFSub(a->jdouble_value(), b->jdouble_value()))); -#else - builder()->CreateSub(a->jdouble_value(), b->jdouble_value()))); -#endif break; case Bytecodes::_dmul: b = pop(); a = pop(); push(SharkValue::create_jdouble( -#if SHARK_LLVM_VERSION >= 26 builder()->CreateFMul(a->jdouble_value(), b->jdouble_value()))); -#else - builder()->CreateMul(a->jdouble_value(), b->jdouble_value()))); -#endif break; case Bytecodes::_ddiv: b = pop(); @@ -625,11 +597,7 @@ case Bytecodes::_dneg: a = pop(); push(SharkValue::create_jdouble( -#if SHARK_LLVM_VERSION >= 26 builder()->CreateFNeg(a->jdouble_value()))); -#else - builder()->CreateNeg(a->jdouble_value()))); -#endif break; case Bytecodes::_iinc: diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkBuilder.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -28,16 +28,8 @@ using namespace llvm; -SharkBuilder::SharkBuilder(Module* module, SharkCodeBuffer* code_buffer) -#if SHARK_LLVM_VERSION >= 26 - // LLVM 2.6 requires a LLVMContext during IRBuilder construction. - // getGlobalConext() returns one that can be used as long as the shark - // compiler are single-threaded. - : IRBuilder<>(getGlobalContext()), -#else - : IRBuilder<>(), -#endif // SHARK_LLVM_VERSION >= 26 - _module(module), +SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer) + : IRBuilder<>(SharkContext::current()), _code_buffer(code_buffer) { } @@ -155,17 +147,9 @@ // Miscellaneous case 'v': assert(void_ok, "should be"); -#if SHARK_LLVM_VERSION >= 26 - return Type::getVoidTy(getGlobalContext()); -#else - return Type::VoidTy; -#endif + return SharkType::void_type(); case '1': -#if SHARK_LLVM_VERSION >= 26 - return Type::getInt1Ty(getGlobalContext()); -#else - return Type::Int1Ty; -#endif + return SharkType::bit_type(); default: ShouldNotReachHere(); @@ -196,7 +180,7 @@ const char* params, const char* ret) { - return module()->getOrInsertFunction(name, make_ftype(params, ret)); + return SharkContext::current().get_external(name, make_ftype(params, ret)); } // Create an object representing an external function by inlining a @@ -372,6 +356,15 @@ return make_function((address) SharkRuntime::uncommon_trap, "Ti", "v"); } +// Native-Java transition. + +Value* SharkBuilder::check_special_condition_for_native_trans() +{ + return make_function( + (address) JavaThread::check_special_condition_for_native_trans, + "T", "v"); +} + // Low-level non-VM calls // The ARM-specific code here is to work around unimplemented @@ -520,11 +513,7 @@ const char *name; if (value->hasName()) // XXX this leaks, but it's only debug code -#if SHARK_LLVM_VERSION >= 26 name = strdup(value->getName().str().c_str()); -#else - name = strdup(value->getName().c_str()); -#endif else name = "unnamed_value"; @@ -572,7 +561,7 @@ LLVMValue::intptr_constant(offset)); } -Value* SharkBuilder::CreateInlineOop(ciObject* object, const char* name) +Value* SharkBuilder::CreateInlineOop(jobject object, const char* name) { return CreateLoad( CreateIntToPtr( @@ -607,9 +596,6 @@ BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const { -#if SHARK_LLVM_VERSION >= 26 - return BasicBlock::Create(getGlobalContext(), name, GetInsertBlock()->getParent(), ip); -#else - return BasicBlock::Create(name, GetInsertBlock()->getParent(), ip); -#endif + return BasicBlock::Create( + SharkContext::current(), name, GetInsertBlock()->getParent(), ip); } diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkBuilder.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -27,18 +27,12 @@ friend class SharkCompileInvariants; public: - SharkBuilder(llvm::Module* module, SharkCodeBuffer* code_buffer); + SharkBuilder(SharkCodeBuffer* code_buffer); - // The LLVM module and Shark code buffer we are building into. + // The code buffer we are building into. private: - llvm::Module* _module; SharkCodeBuffer* _code_buffer; - private: - llvm::Module* module() const - { - return _module; - } protected: SharkCodeBuffer* code_buffer() const { @@ -138,7 +132,14 @@ public: llvm::Value* uncommon_trap(); - // Intrinsics and external functions, part 4: Low-level non-VM calls. + // Intrinsics and external functions, part 4: Native-Java transition. + // This is a special case in that it is invoked during a thread + // state transition. The stack must be set up for walking, and it + // may throw exceptions, but the state is _thread_in_native_trans. + public: + llvm::Value* check_special_condition_for_native_trans(); + + // Intrinsics and external functions, part 5: Low-level non-VM calls. // These have the same caveats as the high-level non-VM calls // above. They are not accessed directly; rather, you should // access them via the various Create* methods below. @@ -184,7 +185,11 @@ // Helpers for accessing the code buffer. public: llvm::Value* code_buffer_address(int offset); - llvm::Value* CreateInlineOop(ciObject* object, const char* name = ""); + llvm::Value* CreateInlineOop(jobject object, const char* name = ""); + llvm::Value* CreateInlineOop(ciObject* object, const char* name = "") + { + return CreateInlineOop(object->encoding(), name); + } // Helpers for creating basic blocks. // NB don't use unless SharkFunction::CreateBlock is unavailable. diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -33,7 +33,7 @@ // Start recording the debug information _pc_offset = code_buffer()->create_unique_offset(); _oopmap = new OopMap( - oopmap_slot_munge(function()->oopmap_frame_size()), + oopmap_slot_munge(stack()->oopmap_frame_size()), oopmap_slot_munge(arg_size())); debug_info()->add_safepoint(pc_offset(), oopmap()); } @@ -44,10 +44,10 @@ _exparray = new GrowableArray<ScopeValue*>(stack_depth); // Set the stack pointer - function()->CreateStoreZeroStackPointer( + stack()->CreateStoreStackPointer( builder()->CreatePtrToInt( - function()->CreateAddressOfFrameEntry( - function()->stack_slots_offset() + max_stack() - stack_depth), + stack()->slot_addr( + stack()->stack_slots_offset() + max_stack() - stack_depth), SharkType::intptr_type())); } @@ -120,7 +120,7 @@ // Record the PC builder()->CreateStore( builder()->code_buffer_address(pc_offset()), - function()->CreateAddressOfFrameEntry(offset)); + stack()->slot_addr(offset)); } void SharkDecacher::start_locals() @@ -194,13 +194,11 @@ builder()->CreateStore( builder()->CreateLoad( CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())), - function()->CreateAddressOfFrameEntry( - box_offset, SharkType::intptr_type())); + stack()->slot_addr(box_offset, SharkType::intptr_type())); builder()->CreateStore( builder()->CreateLoad( CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())), - function()->CreateAddressOfFrameEntry( - obj_offset, SharkType::oop_type())); + stack()->slot_addr(obj_offset, SharkType::oop_type())); } void SharkCacher::process_oop_tmp_slot(Value** value, int offset) @@ -270,12 +268,10 @@ Value* value, int offset) { - builder()->CreateStore( - value, function()->CreateAddressOfFrameEntry(offset, type)); + builder()->CreateStore(value, stack()->slot_addr(offset, type)); } Value* SharkCacher::read_value_from_frame(const Type* type, int offset) { - return builder()->CreateLoad( - function()->CreateAddressOfFrameEntry(offset, type)); + return builder()->CreateLoad(stack()->slot_addr(offset, type)); } diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp --- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -116,13 +116,13 @@ // oopmap and debuginfo helpers private: - static int oopmap_slot_munge(int x) + static int oopmap_slot_munge(int offset) { - return x << (LogBytesPerWord - LogBytesPerInt); + return SharkStack::oopmap_slot_munge(offset); } static VMReg slot2reg(int offset) { - return VMRegImpl::stack2reg(oopmap_slot_munge(offset)); + return SharkStack::slot2reg(offset); } static Location slot2loc(int offset, Location::Type type) { diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp --- a/ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -25,25 +25,13 @@ class SharkCodeBuffer : public StackObj { public: - SharkCodeBuffer(OopRecorder* oop_recorder) - : _cb("Shark", 256 * K, 64 * K), - _masm(new MacroAssembler(&_cb)), - _base_pc(NULL) - { - cb()->initialize_oop_recorder(oop_recorder); - } + SharkCodeBuffer(MacroAssembler* masm) + : _masm(masm), _base_pc(NULL) {} private: - CodeBuffer _cb; MacroAssembler* _masm; llvm::Value* _base_pc; - public: - CodeBuffer* cb() - { - return &_cb; - } - private: MacroAssembler* masm() const { @@ -84,11 +72,11 @@ // Inline an oop into the buffer and return its offset. public: - int inline_oop(ciObject* object) const + int inline_oop(jobject object) const { masm()->align(BytesPerWord); int offset = masm()->offset(); - masm()->store_oop(object->encoding()); + masm()->store_oop(object); return offset; } }; diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkCompiler.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -33,52 +33,32 @@ SharkCompiler::SharkCompiler() : AbstractCompiler() { -#if SHARK_LLVM_VERSION >= 26 - // Make LLVM safe for multithreading. We only make LLVM calls from - // the compiler thread, but if LLVM leaves stubs to be rewritten on - // execution then it's possible for Java threads to be making LLVM - // calls at the same time we are. + // Create the lock to protect the memory manager and execution engine + _execution_engine_lock = new Monitor(Mutex::leaf, "SharkExecutionEngineLock"); + MutexLocker locker(execution_engine_lock()); + + // Make LLVM safe for multithreading if (!llvm_start_multithreaded()) - warning("llvm_start_multithreaded() failed"); -#endif + fatal("llvm_start_multithreaded() failed"); - // Create a module to build our functions into -#if SHARK_LLVM_VERSION >= 26 - // LLVM 2.6 and later requires passing a LLVMContext during module - // creation. The LLVM API getGlobalContext() returns a LLVMContext that - // can be used safely as long as the shark compiler stays single threaded - // and only uses one module. - _module = new Module("shark", getGlobalContext()); -#else - _module = new Module("shark"); -#endif + // Initialize the native target + InitializeNativeTarget(); -#if SHARK_LLVM_VERSION >= 26 - // If we have a native target, initialize it to ensure it is linked in and - // usable by the JIT. - InitializeNativeTarget(); -#endif - + // Create the two contexts which we'll use + _normal_context = new SharkContext("normal"); + _native_context = new SharkContext("native"); + + // Create the memory manager + _memory_manager = new SharkMemoryManager(); + // Create the JIT - ModuleProvider *module_provider = new ExistingModuleProvider(module()); - _memory_manager = new SharkMemoryManager(); _execution_engine = ExecutionEngine::createJIT( -#if SHARK_LLVM_VERSION >= 26 - /* - * LLVM 26 introduced a more fine-grained control to set the optimization - * level when creating the LLVM JIT. - * The optimization level are now specified with a enum instead of a bool. - * CodeGenOpt::None = bool true; a fast JIT with reduced optimization. - * CodeGenOpt::Default = bool false; a non-fast JIT with optimization. - * CodeGenOpt::Aggressive = a new non-fast JIT with best optimization. - */ - module_provider, NULL, memory_manager(), CodeGenOpt::Default); -#else - module_provider, NULL, memory_manager(), false); -#endif + _normal_context->module_provider(), + NULL, memory_manager(), CodeGenOpt::Default); + execution_engine()->addModuleProvider( + _native_context->module_provider()); - // Initialize Shark components that need it - SharkType::initialize(); + // All done mark_initialized(); } @@ -90,9 +70,9 @@ void SharkCompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) { assert(is_initialized(), "should be"); - ResourceMark rm; - const char *name = methodname(target); + const char *name = methodname( + target->holder()->name()->as_utf8(), target->name()->as_utf8()); // Do the typeflow analysis ciTypeFlow *flow; @@ -116,62 +96,26 @@ env->set_dependencies(new Dependencies(env)); // Create the code buffer and builder - SharkCodeBuffer cb(env->oop_recorder()); - SharkBuilder builder(module(), &cb); + CodeBuffer hscb("Shark", 256 * K, 64 * K); + hscb.initialize_oop_recorder(env->oop_recorder()); + MacroAssembler *masm = new MacroAssembler(&hscb); + SharkCodeBuffer cb(masm); + SharkBuilder builder(&cb); // Emit the entry point SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry)); // Build the LLVM IR for the method - Function *function = SharkFunction::build(this, env, &builder, flow, name); - if (SharkPrintBitcodeOf != NULL) { - if (!fnmatch(SharkPrintBitcodeOf, name, 0)) - function->dump(); + Function *function = SharkFunction::build(env, &builder, flow, name); + + // Generate native code. It's unpleasant that we have to drop into + // the VM to do this -- it blocks safepoints -- but I can't see any + // other way to handle the locking. + { + ThreadInVMfromNative tiv(JavaThread::current()); + generate_native_code(entry, function, name); } - entry->set_function(function); - // Compile to native code -#ifndef PRODUCT -#if SHARK_LLVM_VERSION < 27 -#ifdef X86 - if (SharkPrintAsmOf != NULL) { - std::vector<const char*> args; - args.push_back(""); // program name - if (!fnmatch(SharkPrintAsmOf, name, 0)) - args.push_back("-debug-only=x86-emitter"); - else - args.push_back("-debug-only=none"); - args.push_back(0); // terminator - cl::ParseCommandLineOptions(args.size() - 1, (char **) &args[0]); - } -#endif // X86 -#else - if (SharkPrintAsmOf != NULL) { - if (!fnmatch(SharkPrintAsmOf, name, 0)) { -#ifdef X86 - llvm::SetCurrentDebugType("x86-emitter"); -#else - llvm::SetCurrentDebugType("jit"); -#endif // X86 - llvm::DebugFlag=true; - } else { - llvm::SetCurrentDebugType(""); - llvm::DebugFlag=false; - } - } -#endif -#endif // !PRODUCT - memory_manager()->set_entry_for_function(function, entry); - module()->getFunctionList().push_back(function); - entry->set_entry_point( - (address) execution_engine()->getPointerToFunction(function)); - address code_start = entry->code_start(); - address code_limit = entry->code_limit(); - - // Register generated code for profiling, etc - if (JvmtiExport::should_post_dynamic_code_generated()) - JvmtiExport::post_dynamic_code_generated(name, code_start, code_limit); - // Install the method into the VM CodeOffsets offsets; offsets.set_value(CodeOffsets::Deopt, 0); @@ -186,7 +130,7 @@ entry_bci, &offsets, 0, - cb.cb(), + &hscb, 0, &oopmaps, &handler_table, @@ -195,8 +139,96 @@ env->comp_level(), false, false); +} - // Print statistics, if requested +nmethod* SharkCompiler::generate_native_wrapper(MacroAssembler* masm, + methodHandle target, + BasicType* arg_types, + BasicType return_type) +{ + assert(is_initialized(), "should be"); + ResourceMark rm; + const char *name = methodname( + target->klass_name()->as_utf8(), target->name()->as_utf8()); + + // Create the code buffer and builder + SharkCodeBuffer cb(masm); + SharkBuilder builder(&cb); + + // Emit the entry point + SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry)); + + // Build the LLVM IR for the method + SharkNativeWrapper *wrapper = SharkNativeWrapper::build( + &builder, target, name, arg_types, return_type); + + // Generate native code + generate_native_code(entry, wrapper->function(), name); + + // Return the nmethod for installation in the VM + return nmethod::new_native_nmethod(target, + masm->code(), + 0, + 0, + wrapper->frame_size(), + wrapper->receiver_offset(), + wrapper->lock_offset(), + wrapper->oop_maps()); +} + +void SharkCompiler::generate_native_code(SharkEntry* entry, + Function* function, + const char* name) +{ + // Print the LLVM bitcode, if requested + if (SharkPrintBitcodeOf != NULL) { + if (!fnmatch(SharkPrintBitcodeOf, name, 0)) + function->dump(); + } + + // Compile to native code + address code = NULL; + context()->add_function(function); + { + MutexLocker locker(execution_engine_lock()); + free_queued_methods(); + + if (SharkPrintAsmOf != NULL) { +#if SHARK_LLVM_VERSION >= 27 + if (!fnmatch(SharkPrintAsmOf, name, 0)) { + llvm::SetCurrentDebugType(X86_ONLY("x86-emitter") NOT_X86("jit")); + llvm::DebugFlag = true; + } + else { + llvm::SetCurrentDebugType(""); + llvm::DebugFlag = false; + } +#else + // NB you need to patch LLVM with http://tinyurl.com/yf3baln for this + std::vector<const char*> args; + args.push_back(""); // program name + if (!fnmatch(SharkPrintAsmOf, name, 0)) + args.push_back("-debug-only=x86-emitter"); + else + args.push_back("-debug-only=none"); + args.push_back(0); // terminator + cl::ParseCommandLineOptions(args.size() - 1, (char **) &args[0]); +#endif // SHARK_LLVM_VERSION + } + memory_manager()->set_entry_for_function(function, entry); + code = (address) execution_engine()->getPointerToFunction(function); + } + entry->set_entry_point(code); + entry->set_function(function); + entry->set_context(context()); + address code_start = entry->code_start(); + address code_limit = entry->code_limit(); + + // Register generated code for profiling, etc + if (JvmtiExport::should_post_dynamic_code_generated()) + JvmtiExport::post_dynamic_code_generated(name, code_start, code_limit); + + // Print debug information, if requested if (SharkTraceInstalls) { tty->print_cr( " [%p-%p): %s (%d bytes code)", @@ -206,21 +238,39 @@ void SharkCompiler::free_compiled_method(address code) { - Function *function = ((SharkEntry *) code)->function(); - execution_engine()->freeMachineCodeForFunction(function); - function->eraseFromParent(); + // This method may only be called when the VM is at a safepoint. + // All _thread_in_vm threads will be waiting for the safepoint to + // finish with the exception of the VM thread, so we can consider + // ourself the owner of the execution engine lock even though we + // can't actually acquire it at this time. + assert(Thread::current()->is_VM_thread(), "must be called by VM thread"); + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); + + SharkEntry *entry = (SharkEntry *) code; + entry->context()->push_to_free_queue(entry->function()); } -const char* SharkCompiler::methodname(const ciMethod* target) +void SharkCompiler::free_queued_methods() { - const char *klassname = target->holder()->name()->as_utf8(); - const char *methodname = target->name()->as_utf8(); + // The free queue is protected by the execution engine lock + assert(execution_engine_lock()->owned_by_self(), "should be"); - char *buf = NEW_RESOURCE_ARRAY( - char, strlen(klassname) + 2 + strlen(methodname) + 1); + while (true) { + Function *function = context()->pop_from_free_queue(); + if (function == NULL) + break; + + execution_engine()->freeMachineCodeForFunction(function); + function->eraseFromParent(); + } +} + +const char* SharkCompiler::methodname(const char* klass, const char* method) +{ + char *buf = NEW_RESOURCE_ARRAY(char, strlen(klass) + 2 + strlen(method) + 1); char *dst = buf; - for (const char *c = klassname; *c; c++) { + for (const char *c = klass; *c; c++) { if (*c == '/') *(dst++) = '.'; else @@ -228,7 +278,7 @@ } *(dst++) = ':'; *(dst++) = ':'; - for (const char *c = methodname; *c; c++) { + for (const char *c = method; *c; c++) { *(dst++) = *c; } *(dst++) = '\0'; diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkCompiler.hpp --- a/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -23,6 +23,8 @@ * */ +class SharkContext; + class SharkCompiler : public AbstractCompiler { public: // Creation @@ -32,7 +34,7 @@ const char *name() { return "shark"; } // Missing feature tests - bool supports_native() { return false; } + bool supports_native() { return true; } bool supports_osr() { return true; } // Customization @@ -42,33 +44,81 @@ // Initialization void initialize(); - // Compilation entry point for methods + // Compile a normal (bytecode) method and install it in the VM void compile_method(ciEnv* env, ciMethod* target, int entry_bci); - // Free compiled methods + // Generate a wrapper for a native (JNI) method + nmethod* generate_native_wrapper(MacroAssembler* masm, + methodHandle target, + BasicType* arg_types, + BasicType return_type); + + // Free compiled methods (and native wrappers) void free_compiled_method(address code); - // LLVM interface + // Each thread generating IR needs its own context. The normal + // context is used for bytecode methods, and is protected from + // multiple simultaneous accesses by being restricted to the + // compiler thread. The native context is used for JNI methods, + // and is protected from multiple simultaneous accesses by the + // adapter handler library lock. private: - llvm::Module* _module; + SharkContext* _normal_context; + SharkContext* _native_context; + + public: + SharkContext* context() const + { + if (JavaThread::current()->is_Compiler_thread()) { + return _normal_context; + } + else { + assert(AdapterHandlerLibrary_lock->owned_by_self(), "should be"); + return _native_context; + } + } + + // The LLVM execution engine is the JIT we use to generate native + // code. It is thread safe, but we need to protect it with a lock + // of our own because otherwise LLVM's lock and HotSpot's locks + // interleave and deadlock. The SharkMemoryManager is not thread + // safe, and is protected by the same lock as the execution engine. + private: + Monitor* _execution_engine_lock; SharkMemoryManager* _memory_manager; llvm::ExecutionEngine* _execution_engine; - public: - llvm::Module* module() const + private: + Monitor* execution_engine_lock() const { - return _module; + return _execution_engine_lock; } SharkMemoryManager* memory_manager() const { + assert(execution_engine_lock()->owned_by_self(), "should be"); return _memory_manager; } llvm::ExecutionEngine* execution_engine() const { + assert(execution_engine_lock()->owned_by_self(), "should be"); return _execution_engine; } - // Helper + // Global access + public: + static SharkCompiler* compiler() + { + AbstractCompiler *compiler = + CompileBroker::compiler(CompLevel_fast_compile); + assert(compiler->is_shark() && compiler->is_initialized(), "should be"); + return (SharkCompiler *) compiler; + } + + // Helpers private: - static const char* methodname(const ciMethod* target); + static const char* methodname(const char* klass, const char* method); + void generate_native_code(SharkEntry* entry, + llvm::Function* function, + const char* name); + void free_queued_methods(); }; diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkContext.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkContext.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -0,0 +1,185 @@ +/* + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 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/_sharkContext.cpp.incl" + +using namespace llvm; + +SharkContext::SharkContext(const char* name) + : LLVMContext(), + _free_queue(NULL) +{ + // Create a module to build our functions into + _module = new Module(name, *this); + + // Create basic types + _void_type = Type::getVoidTy(*this); + _bit_type = Type::getInt1Ty(*this); + _jbyte_type = Type::getInt8Ty(*this); + _jshort_type = Type::getInt16Ty(*this); + _jint_type = Type::getInt32Ty(*this); + _jlong_type = Type::getInt64Ty(*this); + _jfloat_type = Type::getFloatTy(*this); + _jdouble_type = Type::getDoubleTy(*this); + + // Create compound types + _itableOffsetEntry_type = PointerType::getUnqual( + ArrayType::get(jbyte_type(), itableOffsetEntry::size() * wordSize)); + + _klass_type = PointerType::getUnqual( + ArrayType::get(jbyte_type(), sizeof(Klass))); + + _jniEnv_type = PointerType::getUnqual( + ArrayType::get(jbyte_type(), sizeof(JNIEnv))); + + _jniHandleBlock_type = PointerType::getUnqual( + ArrayType::get(jbyte_type(), sizeof(JNIHandleBlock))); + + _methodOop_type = PointerType::getUnqual( + ArrayType::get(jbyte_type(), sizeof(methodOopDesc))); + + _monitor_type = ArrayType::get( + jbyte_type(), frame::interpreter_frame_monitor_size() * wordSize); + + _oop_type = PointerType::getUnqual( + ArrayType::get(jbyte_type(), sizeof(oopDesc))); + + _thread_type = PointerType::getUnqual( + ArrayType::get(jbyte_type(), sizeof(JavaThread))); + + _zeroStack_type = PointerType::getUnqual( + ArrayType::get(jbyte_type(), sizeof(ZeroStack))); + + std::vector<const Type*> params; + params.push_back(methodOop_type()); + params.push_back(intptr_type()); + params.push_back(thread_type()); + _entry_point_type = FunctionType::get(void_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); + + // Create mappings + for (int i = 0; i < T_CONFLICT; i++) { + switch (i) { + case T_BOOLEAN: + _to_stackType[i] = jint_type(); + _to_arrayType[i] = jbyte_type(); + break; + + case T_BYTE: + _to_stackType[i] = jint_type(); + _to_arrayType[i] = jbyte_type(); + break; + + case T_CHAR: + _to_stackType[i] = jint_type(); + _to_arrayType[i] = jshort_type(); + break; + + case T_SHORT: + _to_stackType[i] = jint_type(); + _to_arrayType[i] = jshort_type(); + break; + + case T_INT: + _to_stackType[i] = jint_type(); + _to_arrayType[i] = jint_type(); + break; + + case T_LONG: + _to_stackType[i] = jlong_type(); + _to_arrayType[i] = jlong_type(); + break; + + case T_FLOAT: + _to_stackType[i] = jfloat_type(); + _to_arrayType[i] = jfloat_type(); + break; + + case T_DOUBLE: + _to_stackType[i] = jdouble_type(); + _to_arrayType[i] = jdouble_type(); + break; + + case T_OBJECT: + case T_ARRAY: + _to_stackType[i] = oop_type(); + _to_arrayType[i] = oop_type(); + break; + + case T_ADDRESS: + _to_stackType[i] = intptr_type(); + _to_arrayType[i] = NULL; + break; + + default: + _to_stackType[i] = NULL; + _to_arrayType[i] = NULL; + } + } +} + +class SharkFreeQueueItem : public CHeapObj { + public: + SharkFreeQueueItem(llvm::Function* function, SharkFreeQueueItem *next) + : _function(function), _next(next) {} + + private: + llvm::Function* _function; + SharkFreeQueueItem* _next; + + public: + llvm::Function* function() const + { + return _function; + } + SharkFreeQueueItem* next() const + { + return _next; + } +}; + +void SharkContext::push_to_free_queue(Function* function) +{ + _free_queue = new SharkFreeQueueItem(function, _free_queue); +} + +Function* SharkContext::pop_from_free_queue() +{ + if (_free_queue == NULL) + return NULL; + + SharkFreeQueueItem *item = _free_queue; + Function *function = item->function(); + _free_queue = item->next(); + delete item; + return function; +} diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkContext.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkContext.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -0,0 +1,208 @@ +/* + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 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. + * + */ + +// The LLVMContext class allows multiple instances of LLVM to operate +// independently of each other in a multithreaded context. We extend +// this here to store things in Shark that are LLVMContext-specific. + +class SharkFreeQueueItem; + +class SharkContext : public llvm::LLVMContext { + public: + SharkContext(const char* name); + + private: + llvm::Module* _module; + + private: + llvm::Module* module() const + { + return _module; + } + + // Get this thread's SharkContext + public: + static SharkContext& current() + { + return *SharkCompiler::compiler()->context(); + } + + // Module accessors + public: + llvm::ModuleProvider* module_provider() const + { + return new llvm::ExistingModuleProvider(module()); + } + void add_function(llvm::Function* function) const + { + module()->getFunctionList().push_back(function); + } + llvm::Constant* get_external(const char* name, const llvm::FunctionType* sig) + { + return module()->getOrInsertFunction(name, sig); + } + + // Basic types + private: + const llvm::Type* _void_type; + const llvm::IntegerType* _bit_type; + const llvm::IntegerType* _jbyte_type; + const llvm::IntegerType* _jshort_type; + const llvm::IntegerType* _jint_type; + const llvm::IntegerType* _jlong_type; + const llvm::Type* _jfloat_type; + const llvm::Type* _jdouble_type; + + public: + const llvm::Type* void_type() const + { + return _void_type; + } + const llvm::IntegerType* bit_type() const + { + return _bit_type; + } + const llvm::IntegerType* jbyte_type() const + { + return _jbyte_type; + } + const llvm::IntegerType* jshort_type() const + { + return _jshort_type; + } + const llvm::IntegerType* jint_type() const + { + return _jint_type; + } + const llvm::IntegerType* jlong_type() const + { + return _jlong_type; + } + const llvm::Type* jfloat_type() const + { + return _jfloat_type; + } + const llvm::Type* jdouble_type() const + { + return _jdouble_type; + } + const llvm::IntegerType* intptr_type() const + { + return LP64_ONLY(jlong_type()) NOT_LP64(jint_type()); + } + + // Compound types + private: + const llvm::PointerType* _itableOffsetEntry_type; + const llvm::PointerType* _jniEnv_type; + const llvm::PointerType* _jniHandleBlock_type; + const llvm::PointerType* _klass_type; + const llvm::PointerType* _methodOop_type; + const llvm::ArrayType* _monitor_type; + const llvm::PointerType* _oop_type; + const llvm::PointerType* _thread_type; + const llvm::PointerType* _zeroStack_type; + const llvm::FunctionType* _entry_point_type; + const llvm::FunctionType* _osr_entry_point_type; + + public: + const llvm::PointerType* itableOffsetEntry_type() const + { + return _itableOffsetEntry_type; + } + const llvm::PointerType* jniEnv_type() const + { + return _jniEnv_type; + } + const llvm::PointerType* jniHandleBlock_type() const + { + return _jniHandleBlock_type; + } + const llvm::PointerType* klass_type() const + { + return _klass_type; + } + const llvm::PointerType* methodOop_type() const + { + return _methodOop_type; + } + const llvm::ArrayType* monitor_type() const + { + return _monitor_type; + } + const llvm::PointerType* oop_type() const + { + return _oop_type; + } + const llvm::PointerType* thread_type() const + { + return _thread_type; + } + const llvm::PointerType* zeroStack_type() const + { + return _zeroStack_type; + } + const llvm::FunctionType* entry_point_type() const + { + return _entry_point_type; + } + const llvm::FunctionType* osr_entry_point_type() const + { + return _osr_entry_point_type; + } + + // Mappings + private: + const llvm::Type* _to_stackType[T_CONFLICT]; + const llvm::Type* _to_arrayType[T_CONFLICT]; + + private: + const llvm::Type* map_type(const llvm::Type* const* table, + BasicType type) const + { + assert(type >= 0 && type < T_CONFLICT, "unhandled type"); + const llvm::Type* result = table[type]; + assert(type != NULL, "unhandled type"); + return result; + } + + public: + const llvm::Type* to_stackType(BasicType type) const + { + return map_type(_to_stackType, type); + } + const llvm::Type* to_arrayType(BasicType type) const + { + return map_type(_to_arrayType, type); + } + + // Functions queued for freeing + private: + SharkFreeQueueItem* _free_queue; + + public: + void push_to_free_queue(llvm::Function* function); + llvm::Function* pop_from_free_queue(); +}; diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkEntry.hpp --- a/ports/hotspot/src/share/vm/shark/sharkEntry.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkEntry.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -23,9 +23,12 @@ * */ +class SharkContext; + class SharkEntry : public ZeroEntry { private: address _code_limit; + SharkContext* _context; llvm::Function* _function; public: @@ -37,6 +40,10 @@ { return _code_limit; } + SharkContext* context() const + { + return _context; + } llvm::Function* function() const { return _function; @@ -47,6 +54,10 @@ { _code_limit = code_limit; } + void set_context(SharkContext* context) + { + _context = context; + } void set_function(llvm::Function* function) { _function = function; diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkFunction.cpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -77,17 +77,10 @@ block(i)->initialize(); } - // Create the method preamble + // Create and push our stack frame set_block_insertion_point(&function()->front()); builder()->SetInsertPoint(CreateBlock()); - CreateInitZeroStack(); - CreatePushFrame(CreateBuildFrame()); - NOT_PRODUCT(builder()->CreateStore( - method, - CreateAddressOfFrameEntry( - method_slot_offset(), - SharkType::methodOop_type(), - "method_slot"))); + _stack = SharkStack::CreateBuildAndPushFrame(this, method); // Create the entry state SharkState *entry_state; @@ -132,150 +125,6 @@ do_deferred_zero_checks(); } -void SharkFunction::CreateInitZeroStack() -{ - Value *zero_stack = builder()->CreateAddressOfStructEntry( - thread(), JavaThread::zero_stack_offset(), - SharkType::zeroStack_type(), - "zero_stack"); - - _zero_stack_base = builder()->CreateValueOfStructEntry( - zero_stack, ZeroStack::base_offset(), - SharkType::intptr_type(), - "zero_stack_base"); - - _zero_stack_pointer_addr = builder()->CreateAddressOfStructEntry( - zero_stack, ZeroStack::sp_offset(), - PointerType::getUnqual(SharkType::intptr_type()), - "zero_stack_pointer_addr"); - - _zero_frame_pointer_addr = builder()->CreateAddressOfStructEntry( - thread(), JavaThread::top_zero_frame_offset(), - PointerType::getUnqual(SharkType::intptr_type()), - "zero_frame_pointer_addr"); -} - -void SharkFunction::CreateStackOverflowCheck(Value *sp) -{ - BasicBlock *overflow = CreateBlock("stack_overflow"); - BasicBlock *no_overflow = CreateBlock("no_overflow"); - - builder()->CreateCondBr( - builder()->CreateICmpULT(sp, zero_stack_base()), - overflow, no_overflow); - - builder()->SetInsertPoint(overflow); - builder()->CreateUnimplemented(__FILE__, __LINE__); - builder()->CreateUnreachable(); - - builder()->SetInsertPoint(no_overflow); -} - -void SharkFunction::CreatePushFrame(Value *fp) -{ - builder()->CreateStore(CreateLoadZeroFramePointer(), fp); - CreateStoreZeroFramePointer( - builder()->CreatePtrToInt(fp, SharkType::intptr_type())); -} - -Value* SharkFunction::CreatePopFrame(int result_slots) -{ - assert(result_slots >= 0 && result_slots <= 2, "should be"); - - int locals_to_pop = max_locals() - result_slots; - - Value *fp = CreateLoadZeroFramePointer(); - Value *sp = builder()->CreateAdd( - fp, - LLVMValue::intptr_constant((1 + locals_to_pop) * wordSize)); - - CreateStoreZeroStackPointer(sp); - CreateStoreZeroFramePointer( - builder()->CreateLoad( - builder()->CreateIntToPtr( - fp, PointerType::getUnqual(SharkType::intptr_type())))); - - return sp; -} - -Value* SharkFunction::CreateBuildFrame() -{ - int locals_words = max_locals(); - int extra_locals = locals_words - arg_size(); - int header_words = SharkFrame::header_words; - int monitor_words = max_monitors()*frame::interpreter_frame_monitor_size(); - int stack_words = max_stack(); - int frame_words = header_words + monitor_words + stack_words; - - _extended_frame_size = frame_words + locals_words; - - // Update the stack pointer - Value *zero_stack_pointer = builder()->CreateSub( - CreateLoadZeroStackPointer(), - LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize)); - CreateStackOverflowCheck(zero_stack_pointer); - NOT_PRODUCT(CreateStoreZeroStackPointer(zero_stack_pointer)); - - // Create the frame - _frame = builder()->CreateIntToPtr( - zero_stack_pointer, - PointerType::getUnqual( - ArrayType::get(SharkType::intptr_type(), extended_frame_size())), - "frame"); - int offset = 0; - - // Expression stack - _stack_slots_offset = offset; - offset += stack_words; - - // Monitors - _monitors_slots_offset = offset; - offset += monitor_words; - - // Temporary oop slot - _oop_tmp_slot_offset = offset++; - - // Method pointer - _method_slot_offset = offset++; - - // Unextended SP - builder()->CreateStore( - zero_stack_pointer, - CreateAddressOfFrameEntry(offset++)); - - // PC - _pc_slot_offset = offset++; - - // Frame header - builder()->CreateStore( - LLVMValue::intptr_constant(ZeroFrame::SHARK_FRAME), - CreateAddressOfFrameEntry(offset++)); - Value *fp = CreateAddressOfFrameEntry(offset++); - - // Local variables - _locals_slots_offset = offset; - offset += locals_words; - - assert(offset == extended_frame_size(), "should do"); - return fp; -} - -Value* SharkFunction::CreateAddressOfFrameEntry(int offset, - const llvm::Type* type, - const char* name) const -{ - bool needs_cast = type && type != SharkType::intptr_type(); - - Value* result = builder()->CreateStructGEP( - _frame, offset, needs_cast ? "" : name); - - if (needs_cast) { - result = builder()->CreateBitCast( - result, PointerType::getUnqual(type), name); - } - return result; -} - class DeferredZeroCheck : public SharkTargetInvariants { public: DeferredZeroCheck(SharkTopLevelBlock* block, SharkValue* value) diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkFunction.hpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -27,24 +27,24 @@ class DeferredZeroCheck; class SharkFunction : public SharkTargetInvariants { + friend class SharkStackWithNormalFrame; + public: - static llvm::Function* build(SharkCompiler* compiler, - ciEnv* env, - SharkBuilder* builder, - ciTypeFlow* flow, - const char* name) + static llvm::Function* build(ciEnv* env, + SharkBuilder* builder, + ciTypeFlow* flow, + const char* name) { - SharkFunction function(compiler, env, builder, flow, name); + SharkFunction function(env, builder, flow, name); return function.function(); } private: - SharkFunction(SharkCompiler* compiler, - ciEnv* env, - SharkBuilder* builder, - ciTypeFlow* flow, - const char* name) - : SharkTargetInvariants(compiler, env, builder, flow) { initialize(name); } + SharkFunction(ciEnv* env, + SharkBuilder* builder, + ciTypeFlow* flow, + const char* name) + : SharkTargetInvariants(env, builder, flow) { initialize(name); } private: void initialize(const char* name); @@ -53,6 +53,7 @@ llvm::Function* _function; SharkTopLevelBlock** _blocks; GrowableArray<DeferredZeroCheck*> _deferred_zero_checks; + SharkStack* _stack; public: llvm::Function* function() const @@ -72,6 +73,10 @@ { return &_deferred_zero_checks; } + SharkStack* stack() const + { + return _stack; + } // On-stack replacement private: @@ -103,153 +108,8 @@ public: llvm::BasicBlock* CreateBlock(const char* name = "") const { -#if SHARK_LLVM_VERSION >= 26 - return llvm::BasicBlock::Create(llvm::getGlobalContext(), name, function(), block_insertion_point()); -#else - return llvm::BasicBlock::Create(name, function(), block_insertion_point()); -#endif - } - - // Stack management - private: - llvm::Value* _zero_stack_base; - llvm::Value* _zero_stack_pointer_addr; - llvm::Value* _zero_frame_pointer_addr; - - private: - llvm::Value* zero_stack_base() const - { - return _zero_stack_base; - } - llvm::Value* zero_stack_pointer_addr() const - { - return _zero_stack_pointer_addr; - } - llvm::Value* zero_frame_pointer_addr() const - { - return _zero_frame_pointer_addr; - } - - private: - void CreateInitZeroStack(); - - public: - llvm::LoadInst* CreateLoadZeroStackPointer(const char *name = "") - { - return builder()->CreateLoad(zero_stack_pointer_addr(), name); - } - llvm::StoreInst* CreateStoreZeroStackPointer(llvm::Value* value) - { - return builder()->CreateStore(value, zero_stack_pointer_addr()); - } - llvm::LoadInst* CreateLoadZeroFramePointer(const char *name = "") - { - return builder()->CreateLoad(zero_frame_pointer_addr(), name); - } - private: - llvm::StoreInst* CreateStoreZeroFramePointer(llvm::Value* value) - { - return builder()->CreateStore(value, zero_frame_pointer_addr()); - } - - private: - void CreateStackOverflowCheck(llvm::Value* sp); - - public: - void CreatePushFrame(llvm::Value* fp); - llvm::Value* CreatePopFrame(int result_slots); - - // Frame management - private: - llvm::Value* _frame; - - public: - llvm::Value* CreateAddressOfFrameEntry(int offset, - const llvm::Type* type = NULL, - const char* name = "") const; - private: - llvm::Value* CreateBuildFrame(); - - private: - int _extended_frame_size; - int _stack_slots_offset; - int _monitors_slots_offset; - int _oop_tmp_slot_offset; - int _method_slot_offset; - int _pc_slot_offset; - int _locals_slots_offset; - - public: - int extended_frame_size() const - { - return _extended_frame_size; - } - int oopmap_frame_size() const - { - return extended_frame_size() - arg_size(); - } - int stack_slots_offset() const - { - return _stack_slots_offset; - } - int oop_tmp_slot_offset() const - { - return _oop_tmp_slot_offset; - } - int method_slot_offset() const - { - return _method_slot_offset; - } - int pc_slot_offset() const - { - return _pc_slot_offset; - } - int locals_slots_offset() const - { - return _locals_slots_offset; - } - - // Monitors - public: - int monitor_offset(int index) const - { - assert(index >= 0 && index < max_monitors(), "invalid monitor index"); - return _monitors_slots_offset + - (max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size(); - } - int monitor_object_offset(int index) const - { - return monitor_offset(index) + - (BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord); - } - int monitor_header_offset(int index) const - { - return monitor_offset(index) + - ((BasicObjectLock::lock_offset_in_bytes() + - BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord); - } - - public: - llvm::Value* monitor_addr(int index) const - { - return CreateAddressOfFrameEntry( - monitor_offset(index), - SharkType::monitor_type(), - "monitor"); - } - llvm::Value* monitor_object_addr(int index) const - { - return CreateAddressOfFrameEntry( - monitor_object_offset(index), - SharkType::oop_type(), - "object_addr"); - } - llvm::Value* monitor_header_addr(int index) const - { - return CreateAddressOfFrameEntry( - monitor_header_offset(index), - SharkType::intptr_type(), - "displaced_header_addr"); + return llvm::BasicBlock::Create( + SharkContext::current(), name, function(), block_insertion_point()); } // Deferred zero checks diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkInvariants.hpp --- a/ports/hotspot/src/share/vm/shark/sharkInvariants.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkInvariants.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -31,35 +31,20 @@ class SharkCompileInvariants : public ResourceObj { protected: - SharkCompileInvariants(SharkCompiler* compiler, - ciEnv* env, - SharkBuilder* builder) - : _compiler(compiler), - _env(env), + SharkCompileInvariants(ciEnv* env, SharkBuilder* builder) + : _env(env), _builder(builder), _thread(NULL) {} SharkCompileInvariants(const SharkCompileInvariants* parent) - : _compiler(parent->_compiler), - _env(parent->_env), + : _env(parent->_env), _builder(parent->_builder), _thread(parent->_thread) {} private: - SharkCompiler* _compiler; - ciEnv* _env; - SharkBuilder* _builder; - llvm::Value* _thread; - - // The SharkCompiler that is compiling this method. Holds the - // classes that form the interface with LLVM (the module, the - // memory manager, etc) and provides the compile() method to - // convert LLVM functions to native code. - protected: - SharkCompiler* compiler() const - { - return _compiler; - } + ciEnv* _env; + SharkBuilder* _builder; + llvm::Value* _thread; // Top-level broker for HotSpot's Compiler Interface. // @@ -73,6 +58,7 @@ private: ciEnv* env() const { + assert(_env != NULL, "env not available"); return _env; } @@ -124,11 +110,8 @@ class SharkTargetInvariants : public SharkCompileInvariants { protected: - SharkTargetInvariants(SharkCompiler* compiler, - ciEnv* env, - SharkBuilder* builder, - ciTypeFlow* flow) - : SharkCompileInvariants(compiler, env, builder), + SharkTargetInvariants(ciEnv* env, SharkBuilder* builder, ciTypeFlow* flow) + : SharkCompileInvariants(env, builder), _target(flow->method()), _flow(flow), _max_monitors(count_monitors()) {} diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkMemoryManager.cpp --- a/ports/hotspot/src/share/vm/shark/sharkMemoryManager.cpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkMemoryManager.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -103,8 +103,8 @@ } #endif -#if SHARK_LLVM_VERSION >= 26 -uint8_t* SharkMemoryManager::allocateGlobal(uintptr_t Size, unsigned int Alignment) +uint8_t* SharkMemoryManager::allocateGlobal(uintptr_t Size, + unsigned int Alignment) { return mm()->allocateGlobal(Size, Alignment); } @@ -124,12 +124,8 @@ mm()->setPoisonMemory(poison); } -#endif - -#if SHARK_LLVM_VERSION >= 25 unsigned char *SharkMemoryManager::allocateSpace(intptr_t Size, unsigned int Alignment) { return mm()->allocateSpace(Size, Alignment); } -#endif diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkMemoryManager.hpp --- a/ports/hotspot/src/share/vm/shark/sharkMemoryManager.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkMemoryManager.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -71,12 +71,10 @@ unsigned char* TableStart, unsigned char* TableEnd, unsigned char* FrameRegister); -#if SHARK_LLVM_VERSION >= 26 void* getDlsymTable() const; void SetDlsymTable(void *ptr); void setPoisonMemory(bool); uint8_t* allocateGlobal(uintptr_t, unsigned int); -#endif void setMemoryWritable(); void setMemoryExecutable(); #if SHARK_LLVM_VERSION >= 27 @@ -85,9 +83,6 @@ #else void deallocateMemForFunction(const llvm::Function* F); #endif - -#if SHARK_LLVM_VERSION >= 25 unsigned char *allocateSpace(intptr_t Size, unsigned int Alignment); -#endif }; diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -0,0 +1,352 @@ +/* + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 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/_sharkNativeWrapper.cpp.incl" + +using namespace llvm; + +void SharkNativeWrapper::initialize(const char *name) +{ + // Create the function + _function = Function::Create( + SharkType::entry_point_type(), + GlobalVariable::InternalLinkage, + name); + + // Get our arguments + Function::arg_iterator ai = function()->arg_begin(); + Argument *method = ai++; + method->setName("method"); + Argument *base_pc = ai++; + base_pc->setName("base_pc"); + code_buffer()->set_base_pc(base_pc); + Argument *thread = ai++; + thread->setName("thread"); + set_thread(thread); + + // Create and push our stack frame + builder()->SetInsertPoint(CreateBlock()); + _stack = SharkStack::CreateBuildAndPushFrame(this, method); + NOT_PRODUCT(method = NULL); + + // Create the oopmap. We use the one oopmap for every call site in + // the wrapper, which results in the odd mild inefficiency but is a + // damn sight easier to code. + OopMap *oopmap = new OopMap( + SharkStack::oopmap_slot_munge(stack()->oopmap_frame_size()), + SharkStack::oopmap_slot_munge(arg_size())); + oopmap->set_oop(SharkStack::slot2reg(stack()->method_slot_offset())); + + // Set up the oop_tmp slot if required: + // - For static methods we use it to handlize the class argument + // for the call, and to protect the same during slow path locks + // (if synchronized). + // - For methods returning oops, we use it to protect the return + // value across safepoints or slow path unlocking. + if (is_static() || is_returning_oop()) { + _oop_tmp_slot = stack()->slot_addr( + stack()->oop_tmp_slot_offset(), + SharkType::oop_type(), + "oop_tmp_slot"); + + oopmap->set_oop(SharkStack::slot2reg(stack()->oop_tmp_slot_offset())); + } + + // Set up the monitor slot, for synchronized methods + if (is_synchronized()) { + Unimplemented(); + _lock_slot_offset = 23; + } + + // Start building the argument list + std::vector<const Type*> param_types; + std::vector<Value*> param_values; + const PointerType *box_type = PointerType::getUnqual(SharkType::oop_type()); + + // First argument is the JNIEnv + param_types.push_back(SharkType::jniEnv_type()); + param_values.push_back( + builder()->CreateAddressOfStructEntry( + thread, + JavaThread::jni_environment_offset(), + SharkType::jniEnv_type(), + "jni_environment")); + + // For static methods, the second argument is the class + if (is_static()) { + builder()->CreateStore( + builder()->CreateInlineOop( + JNIHandles::make_local(target()->method_holder())), + oop_tmp_slot()); + + param_types.push_back(box_type); + param_values.push_back(oop_tmp_slot()); + + _receiver_slot_offset = stack()->oop_tmp_slot_offset(); + } + else if (is_returning_oop()) { + // The oop_tmp slot is registered in the oopmap, + // so we need to clear it. This is one of the + // mild inefficiencies I mentioned earlier. + builder()->CreateStore(LLVMValue::null(), oop_tmp_slot()); + } + + // Parse the arguments + for (int i = 0; i < arg_size(); i++) { + int slot_offset = stack()->locals_slots_offset() + arg_size() - 1 - i; + int adjusted_offset = slot_offset; + BasicBlock *null, *not_null, *merge; + Value *box; + PHINode *phi; + + switch (arg_type(i)) { + case T_VOID: + break; + + case T_OBJECT: + case T_ARRAY: + null = CreateBlock("null"); + not_null = CreateBlock("not_null"); + merge = CreateBlock("merge"); + + box = stack()->slot_addr(slot_offset, SharkType::oop_type()); + builder()->CreateCondBr( + builder()->CreateICmp( + ICmpInst::ICMP_EQ, + builder()->CreateLoad(box), + LLVMValue::null()), + null, not_null); + + builder()->SetInsertPoint(null); + builder()->CreateBr(merge); + + builder()->SetInsertPoint(not_null); + builder()->CreateBr(merge); + + builder()->SetInsertPoint(merge); + phi = builder()->CreatePHI(box_type, "boxed_object"); + phi->addIncoming(ConstantPointerNull::get(box_type), null); + phi->addIncoming(box, not_null); + box = phi; + + param_types.push_back(box_type); + param_values.push_back(box); + + oopmap->set_oop(SharkStack::slot2reg(slot_offset)); + + if (i == 0 && !is_static()) + _receiver_slot_offset = slot_offset; + + break; + + case T_LONG: + case T_DOUBLE: + adjusted_offset--; + // fall through + + default: + const Type *param_type = SharkType::to_stackType(arg_type(i)); + + param_types.push_back(param_type); + param_values.push_back( + builder()->CreateLoad(stack()->slot_addr(adjusted_offset, param_type))); + } + } + + // The oopmap is now complete, and everything is written + // into the frame except the PC. + int pc_offset = code_buffer()->create_unique_offset(); + + _oop_maps = new OopMapSet(); + oop_maps()->add_gc_map(pc_offset, oopmap); + + builder()->CreateStore( + builder()->code_buffer_address(pc_offset), + stack()->slot_addr(stack()->pc_slot_offset())); + + // Set up the Java frame anchor + stack()->CreateSetLastJavaFrame(); + + // Lock if necessary + if (is_synchronized()) + Unimplemented(); + + // Change the thread state to _thread_in_native + CreateSetThreadState(_thread_in_native); + + // Make the call + BasicType result_type = target()->result_type(); + const Type* return_type; + if (result_type == T_VOID) + return_type = SharkType::void_type(); + else if (is_returning_oop()) + return_type = box_type; + else + return_type = SharkType::to_arrayType(result_type); + Value* native_function = builder()->CreateIntToPtr( + LLVMValue::intptr_constant((intptr_t) target()->native_function()), + PointerType::getUnqual( + FunctionType::get(return_type, param_types, false))); + Value *result = builder()->CreateCall( + native_function, param_values.begin(), param_values.end()); + + // Start the transition back to _thread_in_Java + CreateSetThreadState(_thread_in_native_trans); + + // Make sure new state is visible in the GC thread + if (os::is_MP()) { + if (UseMembar) + { Unimplemented(); } + else + CreateWriteMemorySerializePage(); + } + + // Handle safepoint operations, pending suspend requests, + // and pending asynchronous exceptions. + BasicBlock *check_thread = CreateBlock("check_thread"); + BasicBlock *do_safepoint = CreateBlock("do_safepoint"); + BasicBlock *safepointed = CreateBlock("safepointed"); + + Value *global_state = builder()->CreateLoad( + builder()->CreateIntToPtr( + LLVMValue::intptr_constant( + (intptr_t) SafepointSynchronize::address_of_state()), + PointerType::getUnqual(SharkType::jint_type())), + "global_state"); + + builder()->CreateCondBr( + builder()->CreateICmpNE( + global_state, + LLVMValue::jint_constant(SafepointSynchronize::_not_synchronized)), + do_safepoint, check_thread); + + builder()->SetInsertPoint(check_thread); + Value *thread_state = builder()->CreateValueOfStructEntry( + thread, + JavaThread::suspend_flags_offset(), + SharkType::jint_type(), + "thread_state"); + + builder()->CreateCondBr( + builder()->CreateICmpNE( + thread_state, + LLVMValue::jint_constant(0)), + do_safepoint, safepointed); + + builder()->SetInsertPoint(do_safepoint); + builder()->CreateCall( + builder()->check_special_condition_for_native_trans(), thread); + builder()->CreateBr(safepointed); + + // Finally we can change the thread state to _thread_in_Java + builder()->SetInsertPoint(safepointed); + CreateSetThreadState(_thread_in_Java); + + // Clear the frame anchor + stack()->CreateResetLastJavaFrame(); + + // If there is a pending exception then we can just unwind and + // return. It seems totally wrong that unlocking is skipped here + // but apparently the template interpreter does this so we do too. + BasicBlock *exception = CreateBlock("exception"); + BasicBlock *no_exception = CreateBlock("no_exception"); + + builder()->CreateCondBr( + builder()->CreateICmpEQ( + CreateLoadPendingException(), + LLVMValue::null()), + no_exception, exception); + + builder()->SetInsertPoint(exception); + CreateResetHandleBlock(); + stack()->CreatePopFrame(0); + builder()->CreateRetVoid(); + + builder()->SetInsertPoint(no_exception); + + // If the result was an oop then unbox it before + // releasing the handle it might be protected by + if (is_returning_oop()) { + BasicBlock *null = builder()->GetInsertBlock(); + BasicBlock *not_null = CreateBlock("not_null"); + BasicBlock *merge = CreateBlock("merge"); + + builder()->CreateCondBr( + builder()->CreateICmpNE(result, ConstantPointerNull::get(box_type)), + not_null, merge); + + builder()->SetInsertPoint(not_null); + Value *unboxed_result = builder()->CreateLoad(result); + builder()->CreateBr(merge); + + builder()->SetInsertPoint(merge); + PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "result"); + phi->addIncoming(LLVMValue::null(), null); + phi->addIncoming(unboxed_result, not_null); + result = phi; + } + + // Reset handle block + CreateResetHandleBlock(); + + // Unlock if necessary. + if (is_synchronized()) + Unimplemented(); + + // Unwind and return + Value *result_addr = stack()->CreatePopFrame(type2size[result_type]); + if (result_type != T_VOID) { + bool needs_cast = false; + bool is_signed = false; + switch (result_type) { + case T_BOOLEAN: + result = builder()->CreateICmpNE(result, LLVMValue::jbyte_constant(0)); + needs_cast = true; + break; + + case T_BYTE: + needs_cast = true; + break; + + case T_CHAR: + case T_SHORT: + needs_cast = true; + is_signed = true; + break; + } + if (needs_cast) { + result = builder()->CreateIntCast( + result, SharkType::to_stackType(result_type), is_signed); + } + + builder()->CreateStore( + result, + builder()->CreateIntToPtr( + result_addr, + PointerType::getUnqual(SharkType::to_stackType(result_type)))); + } + builder()->CreateRetVoid(); +} diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkNativeWrapper.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -0,0 +1,204 @@ +/* + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 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. + * + */ + +class SharkNativeWrapper : public SharkCompileInvariants { + friend class SharkStackWithNativeFrame; + + public: + static SharkNativeWrapper* build(SharkBuilder* builder, + methodHandle target, + const char* name, + BasicType* arg_types, + BasicType return_type) + { + return new SharkNativeWrapper(builder, + target, + name, + arg_types, + return_type); + } + + private: + SharkNativeWrapper(SharkBuilder* builder, + methodHandle target, + const char* name, + BasicType* arg_types, + BasicType return_type) + : SharkCompileInvariants(NULL, builder), + _target(target), + _arg_types(arg_types), + _return_type(return_type), + _lock_slot_offset(0) { initialize(name); } + + private: + void initialize(const char* name); + + private: + methodHandle _target; + BasicType* _arg_types; + BasicType _return_type; + llvm::Function* _function; + SharkStack* _stack; + llvm::Value* _oop_tmp_slot; + OopMapSet* _oop_maps; + int _receiver_slot_offset; + int _lock_slot_offset; + + // The method being compiled. + protected: + methodHandle target() const + { + return _target; + } + + // Properties of the method. + protected: + int arg_size() const + { + return target()->size_of_parameters(); + } + BasicType arg_type(int i) const + { + return _arg_types[i]; + } + BasicType return_type() const + { + return _return_type; + } + bool is_static() const + { + return target()->is_static(); + } + bool is_synchronized() const + { + return target()->is_synchronized(); + } + bool is_returning_oop() const + { + return target()->is_returning_oop(); + } + + // The LLVM function we are building. + public: + llvm::Function* function() const + { + return _function; + } + + // The Zero stack and our frame on it. + protected: + SharkStack* stack() const + { + return _stack; + } + + // Temporary oop storage. + protected: + llvm::Value* oop_tmp_slot() const + { + assert(is_static() || is_returning_oop(), "should be"); + return _oop_tmp_slot; + } + + // Information required by nmethod::new_native_nmethod(). + public: + int frame_size() const + { + return stack()->oopmap_frame_size(); + } + ByteSize receiver_offset() const + { + return in_ByteSize(_receiver_slot_offset * wordSize); + } + ByteSize lock_offset() const + { + return in_ByteSize(_lock_slot_offset * wordSize); + } + OopMapSet* oop_maps() const + { + return _oop_maps; + } + + // Helpers. + private: + llvm::BasicBlock* CreateBlock(const char* name = "") const + { + return llvm::BasicBlock::Create(SharkContext::current(), name, function()); + } + llvm::Value* thread_state_address() const + { + return builder()->CreateAddressOfStructEntry( + thread(), JavaThread::thread_state_offset(), + llvm::PointerType::getUnqual(SharkType::jint_type()), + "thread_state_address"); + } + llvm::Value* pending_exception_address() const + { + return builder()->CreateAddressOfStructEntry( + thread(), Thread::pending_exception_offset(), + llvm::PointerType::getUnqual(SharkType::oop_type()), + "pending_exception_address"); + } + void CreateSetThreadState(JavaThreadState state) const + { + builder()->CreateStore( + LLVMValue::jint_constant(state), thread_state_address()); + } + void CreateWriteMemorySerializePage() const + { + builder()->CreateStore( + LLVMValue::jint_constant(1), + builder()->CreateIntToPtr( + builder()->CreateAdd( + LLVMValue::intptr_constant( + (intptr_t) os::get_memory_serialize_page()), + builder()->CreateAnd( + builder()->CreateLShr( + builder()->CreatePtrToInt(thread(), SharkType::intptr_type()), + LLVMValue::intptr_constant(os::get_serialize_page_shift_count())), + LLVMValue::intptr_constant(os::get_serialize_page_mask()))), + llvm::PointerType::getUnqual(SharkType::jint_type()))); + } + void CreateResetHandleBlock() const + { + llvm::Value *active_handles = builder()->CreateValueOfStructEntry( + thread(), + JavaThread::active_handles_offset(), + SharkType::jniHandleBlock_type(), + "active_handles"); + builder()->CreateStore( + LLVMValue::intptr_constant(0), + builder()->CreateAddressOfStructEntry( + active_handles, + in_ByteSize(JNIHandleBlock::top_offset_in_bytes()), + llvm::PointerType::getUnqual(SharkType::intptr_type()), + "top")); + } + llvm::LoadInst* CreateLoadPendingException() const + { + return builder()->CreateLoad( + pending_exception_address(), "pending_exception"); + } +}; diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkStack.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkStack.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -0,0 +1,239 @@ +/* + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008, 2009 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/_sharkStack.cpp.incl" + +using namespace llvm; + +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; + int monitor_words = max_monitors()*frame::interpreter_frame_monitor_size(); + int stack_words = max_stack(); + int frame_words = header_words + monitor_words + stack_words; + + _extended_frame_size = frame_words + locals_words; + + // Update the stack pointer + Value *stack_pointer = builder()->CreateSub( + CreateLoadStackPointer(), + LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize)); + CreateHardStackOverflowCheck(stack_pointer); + if (setup_sp_and_method) + CreateStoreStackPointer(stack_pointer); + + // Create the frame + _frame = builder()->CreateIntToPtr( + stack_pointer, + PointerType::getUnqual( + ArrayType::get(SharkType::intptr_type(), extended_frame_size())), + "frame"); + int offset = 0; + + // Expression stack + _stack_slots_offset = offset; + offset += stack_words; + + // Monitors + _monitors_slots_offset = offset; + offset += monitor_words; + + // Temporary oop slot + _oop_tmp_slot_offset = offset++; + + // Method pointer + _method_slot_offset = offset++; + if (setup_sp_and_method) { + builder()->CreateStore( + method, slot_addr(method_slot_offset(), SharkType::methodOop_type())); + } + + // Unextended SP + builder()->CreateStore(stack_pointer, slot_addr(offset++)); + + // PC + _pc_slot_offset = offset++; + + // Frame header + builder()->CreateStore( + LLVMValue::intptr_constant(ZeroFrame::SHARK_FRAME), slot_addr(offset++)); + Value *fp = slot_addr(offset++); + + // Local variables + _locals_slots_offset = offset; + offset += locals_words; + + // Push the frame + assert(offset == extended_frame_size(), "should do"); + 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"); + + builder()->CreateCondBr( + builder()->CreateICmpULT(sp, stack_base()), + overflow, no_overflow); + + builder()->SetInsertPoint(overflow); + builder()->CreateUnimplemented(__FILE__, __LINE__); + builder()->CreateUnreachable(); + + builder()->SetInsertPoint(no_overflow); +} + +// 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 +} + +Value* SharkStack::CreatePopFrame(int result_slots) +{ + assert(result_slots >= 0 && result_slots <= 2, "should be"); + int locals_to_pop = max_locals() - result_slots; + + Value *fp = CreateLoadFramePointer(); + Value *sp = builder()->CreateAdd( + fp, + LLVMValue::intptr_constant((1 + locals_to_pop) * wordSize)); + + CreateStoreStackPointer(sp); + CreateStoreFramePointer( + builder()->CreateLoad( + builder()->CreateIntToPtr( + fp, PointerType::getUnqual(SharkType::intptr_type())))); + + return sp; +} + +Value* SharkStack::slot_addr(int offset, + const Type* type, + const char* name) const +{ + bool needs_cast = type && type != SharkType::intptr_type(); + + Value* result = builder()->CreateStructGEP( + _frame, offset, needs_cast ? "" : name); + + if (needs_cast) { + result = builder()->CreateBitCast( + result, PointerType::getUnqual(type), name); + } + return result; +} + +// The bits that differentiate stacks with normal and native frames on top + +SharkStack* SharkStack::CreateBuildAndPushFrame(SharkFunction* function, + Value* method) +{ + return new SharkStackWithNormalFrame(function, method); +} +SharkStack* SharkStack::CreateBuildAndPushFrame(SharkNativeWrapper* wrapper, + Value* method) +{ + return new SharkStackWithNativeFrame(wrapper, method); +} + +SharkStackWithNormalFrame::SharkStackWithNormalFrame(SharkFunction* function, + Value* method) + : SharkStack(function), _function(function) +{ + // For normal frames, the stack pointer and the method slot will + // 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)); +} +SharkStackWithNativeFrame::SharkStackWithNativeFrame(SharkNativeWrapper* wrp, + Value* method) + : SharkStack(wrp), _wrapper(wrp) +{ + initialize(method); +} + +int SharkStackWithNormalFrame::arg_size() const +{ + return function()->arg_size(); +} +int SharkStackWithNativeFrame::arg_size() const +{ + return wrapper()->arg_size(); +} + +int SharkStackWithNormalFrame::max_locals() const +{ + return function()->max_locals(); +} +int SharkStackWithNativeFrame::max_locals() const +{ + return wrapper()->arg_size(); +} + +int SharkStackWithNormalFrame::max_stack() const +{ + return function()->max_stack(); +} +int SharkStackWithNativeFrame::max_stack() const +{ + return 0; +} + +int SharkStackWithNormalFrame::max_monitors() const +{ + return function()->max_monitors(); +} +int SharkStackWithNativeFrame::max_monitors() const +{ + return wrapper()->is_synchronized() ? 1 : 0; +} + +BasicBlock* SharkStackWithNormalFrame::CreateBlock(const char* name) const +{ + return function()->CreateBlock(name); +} +BasicBlock* SharkStackWithNativeFrame::CreateBlock(const char* name) const +{ + return wrapper()->CreateBlock(name); +} diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkStack.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkStack.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -0,0 +1,292 @@ +/* + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008, 2009 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. + * + */ + +class SharkFunction; +class SharkNativeWrapper; +class SharkStackWithNormalFrame; +class SharkStackWithNativeFrame; + +class SharkStack : public SharkCompileInvariants { + public: + static SharkStack* CreateBuildAndPushFrame( + SharkFunction* function, llvm::Value* method); + static SharkStack* CreateBuildAndPushFrame( + SharkNativeWrapper* wrapper, llvm::Value* method); + + protected: + SharkStack(const SharkCompileInvariants* parent) + : SharkCompileInvariants(parent) {} + + protected: + void initialize(llvm::Value* method); + + protected: + void CreateHardStackOverflowCheck(llvm::Value* sp); + void CreateSoftStackOverflowCheck(llvm::Value* sp); + + // Properties of the method being compiled + protected: + virtual int arg_size() const = 0; + virtual int max_locals() const = 0; + virtual int max_stack() const = 0; + virtual int max_monitors() const = 0; + + // BasicBlock creation + protected: + virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0; + + // Interface with the Zero stack + private: + llvm::Value* zero_stack() const + { + return builder()->CreateAddressOfStructEntry( + thread(), + JavaThread::zero_stack_offset(), + SharkType::zeroStack_type(), + "zero_stack"); + } + llvm::Value* stack_base() const + { + return builder()->CreateValueOfStructEntry( + zero_stack(), + ZeroStack::base_offset(), + SharkType::intptr_type(), + "stack_base"); + } + llvm::Value* stack_pointer_addr() const + { + return builder()->CreateAddressOfStructEntry( + zero_stack(), + ZeroStack::sp_offset(), + llvm::PointerType::getUnqual(SharkType::intptr_type()), + "stack_pointer_addr"); + } + llvm::Value* frame_pointer_addr() const + { + return builder()->CreateAddressOfStructEntry( + thread(), + JavaThread::top_zero_frame_offset(), + llvm::PointerType::getUnqual(SharkType::intptr_type()), + "frame_pointer_addr"); + } + + public: + llvm::LoadInst* CreateLoadStackPointer(const char *name = "") + { + return builder()->CreateLoad(stack_pointer_addr(), name); + } + llvm::StoreInst* CreateStoreStackPointer(llvm::Value* value) + { + return builder()->CreateStore(value, stack_pointer_addr()); + } + llvm::LoadInst* CreateLoadFramePointer(const char *name = "") + { + return builder()->CreateLoad(frame_pointer_addr(), name); + } + llvm::StoreInst* CreateStoreFramePointer(llvm::Value* value) + { + return builder()->CreateStore(value, frame_pointer_addr()); + } + llvm::Value* CreatePopFrame(int result_slots); + + // Interface with the frame anchor + private: + llvm::Value* frame_anchor_addr() const + { + return builder()->CreateAddressOfStructEntry( + thread(), + JavaThread::last_Java_sp_offset(), + llvm::PointerType::getUnqual(SharkType::intptr_type()), + "frame_anchor_addr"); + } + + public: + llvm::StoreInst* CreateSetLastJavaFrame() + { + return builder()->CreateStore( + CreateLoadFramePointer(), frame_anchor_addr()); + } + llvm::StoreInst* CreateResetLastJavaFrame() + { + return builder()->CreateStore( + LLVMValue::intptr_constant(0), frame_anchor_addr()); + } + + // Our method's frame + private: + llvm::Value* _frame; + int _extended_frame_size; + int _stack_slots_offset; + + public: + int extended_frame_size() const + { + return _extended_frame_size; + } + int oopmap_frame_size() const + { + return extended_frame_size() - arg_size(); + } + + // Offsets of things in the frame + private: + int _monitors_slots_offset; + int _oop_tmp_slot_offset; + int _method_slot_offset; + int _pc_slot_offset; + int _locals_slots_offset; + + public: + int stack_slots_offset() const + { + return _stack_slots_offset; + } + int oop_tmp_slot_offset() const + { + return _oop_tmp_slot_offset; + } + int method_slot_offset() const + { + return _method_slot_offset; + } + int pc_slot_offset() const + { + return _pc_slot_offset; + } + int locals_slots_offset() const + { + return _locals_slots_offset; + } + int monitor_offset(int index) const + { + assert(index >= 0 && index < max_monitors(), "invalid monitor index"); + return _monitors_slots_offset + + (max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size(); + } + int monitor_object_offset(int index) const + { + return monitor_offset(index) + + (BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord); + } + int monitor_header_offset(int index) const + { + return monitor_offset(index) + + ((BasicObjectLock::lock_offset_in_bytes() + + BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord); + } + + // Addresses of things in the frame + public: + llvm::Value* slot_addr(int offset, + const llvm::Type* type = NULL, + const char* name = "") const; + + llvm::Value* monitor_addr(int index) const + { + return slot_addr( + monitor_offset(index), + SharkType::monitor_type(), + "monitor"); + } + llvm::Value* monitor_object_addr(int index) const + { + return slot_addr( + monitor_object_offset(index), + SharkType::oop_type(), + "object_addr"); + } + llvm::Value* monitor_header_addr(int index) const + { + return slot_addr( + monitor_header_offset(index), + SharkType::intptr_type(), + "displaced_header_addr"); + } + + // oopmap helpers + public: + static int oopmap_slot_munge(int offset) + { + return offset << (LogBytesPerWord - LogBytesPerInt); + } + static VMReg slot2reg(int offset) + { + return VMRegImpl::stack2reg(oopmap_slot_munge(offset)); + } +}; + +class SharkStackWithNormalFrame : public SharkStack { + friend class SharkStack; + + protected: + SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method); + + private: + SharkFunction* _function; + + private: + SharkFunction* function() const + { + return _function; + } + + // Properties of the method being compiled + private: + int arg_size() const; + int max_locals() const; + int max_stack() const; + int max_monitors() const; + + // BasicBlock creation + private: + llvm::BasicBlock* CreateBlock(const char* name = "") const; +}; + +class SharkStackWithNativeFrame : public SharkStack { + friend class SharkStack; + + protected: + SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method); + + private: + SharkNativeWrapper* _wrapper; + + private: + SharkNativeWrapper* wrapper() const + { + return _wrapper; + } + + // Properties of the method being compiled + private: + int arg_size() const; + int max_locals() const; + int max_stack() const; + int max_monitors() const; + + // BasicBlock creation + private: + llvm::BasicBlock* CreateBlock(const char* name = "") const; +}; diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp --- a/ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -39,7 +39,7 @@ process_stack_slot( i, state->stack_addr(i), - function()->stack_slots_offset() + + stack()->stack_slots_offset() + i + max_stack() - state->stack_depth()); } end_stack(); @@ -49,17 +49,17 @@ for (int i = 0; i < state->num_monitors(); i++) { process_monitor( i, - function()->monitor_offset(i), - function()->monitor_object_offset(i)); + stack()->monitor_offset(i), + stack()->monitor_object_offset(i)); } end_monitors(); // Frame header start_frame_header(); process_oop_tmp_slot( - state->oop_tmp_addr(), function()->oop_tmp_slot_offset()); - process_method_slot(state->method_addr(), function()->method_slot_offset()); - process_pc_slot(function()->pc_slot_offset()); + state->oop_tmp_addr(), stack()->oop_tmp_slot_offset()); + process_method_slot(state->method_addr(), stack()->method_slot_offset()); + process_pc_slot(stack()->pc_slot_offset()); end_frame_header(); // Local variables @@ -69,7 +69,7 @@ process_local_slot( i, state->local_addr(i), - function()->locals_slots_offset() + max_locals() - 1 - i); + stack()->locals_slots_offset() + max_locals() - 1 - i); } end_locals(); diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp --- a/ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -28,15 +28,15 @@ class SharkStateScanner : public SharkTargetInvariants { protected: SharkStateScanner(SharkFunction* function) - : SharkTargetInvariants(function), _function(function) {} + : SharkTargetInvariants(function), _stack(function->stack()) {} private: - SharkFunction* _function; + SharkStack* _stack; protected: - SharkFunction* function() const + SharkStack* stack() const { - return _function; + return _stack; } // Scan the frame diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Nov 11 16:21:16 2009 +0000 @@ -638,7 +638,7 @@ builder()->CreateStore(exception, pending_exception_address()); } - Value *result_addr = function()->CreatePopFrame(type2size[type]); + Value *result_addr = stack()->CreatePopFrame(type2size[type]); if (type != T_VOID) { builder()->CreateStore( pop_result(type)->generic_value(), @@ -1648,8 +1648,8 @@ // of normal stack order. int ndims = iter()->get_dimensions(); - Value *dimensions = function()->CreateAddressOfFrameEntry( - function()->stack_slots_offset() + max_stack() - xstack_depth(), + Value *dimensions = stack()->slot_addr( + stack()->stack_slots_offset() + max_stack() - xstack_depth(), ArrayType::get(SharkType::jint_type(), ndims), "dimensions"); @@ -1707,9 +1707,9 @@ BasicBlock *lock_acquired = function()->CreateBlock("lock_acquired"); int monitor = num_monitors(); - Value *monitor_addr = function()->monitor_addr(monitor); - Value *monitor_object_addr = function()->monitor_object_addr(monitor); - Value *monitor_header_addr = function()->monitor_header_addr(monitor); + Value *monitor_addr = stack()->monitor_addr(monitor); + Value *monitor_object_addr = stack()->monitor_object_addr(monitor); + Value *monitor_header_addr = stack()->monitor_header_addr(monitor); // Store the object and mark the slot as live builder()->CreateStore(lockee, monitor_object_addr); @@ -1791,9 +1791,9 @@ BasicBlock *lock_released = function()->CreateBlock("lock_released"); int monitor = num_monitors() - 1; - Value *monitor_addr = function()->monitor_addr(monitor); - Value *monitor_object_addr = function()->monitor_object_addr(monitor); - Value *monitor_header_addr = function()->monitor_header_addr(monitor); + Value *monitor_addr = stack()->monitor_addr(monitor); + Value *monitor_object_addr = stack()->monitor_object_addr(monitor); + Value *monitor_header_addr = stack()->monitor_header_addr(monitor); // If it is recursive then we're already done Value *disp = builder()->CreateLoad(monitor_header_addr); diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -49,6 +49,13 @@ return _ciblock; } + // Function properties + public: + SharkStack* stack() const + { + return function()->stack(); + } + // Typeflow properties public: int index() const @@ -272,26 +279,6 @@ void check_pending_exception(int action); void handle_exception(llvm::Value* exception, int action); - // Frame anchor - private: - void set_last_Java_frame(llvm::Value* value) const - { - builder()->CreateStore( - value, - builder()->CreateAddressOfStructEntry( - thread(), JavaThread::last_Java_sp_offset(), - llvm::PointerType::getUnqual(SharkType::intptr_type()), - "last_Java_sp_addr")); - } - void set_last_Java_frame() const - { - set_last_Java_frame(function()->CreateLoadZeroFramePointer()); - } - void reset_last_Java_frame() const - { - set_last_Java_frame(LLVMValue::intptr_constant(0)); - } - // VM calls private: llvm::CallInst* call_vm(llvm::Value* callee, @@ -300,9 +287,9 @@ int exception_action) { decache_for_VM_call(); - set_last_Java_frame(); + stack()->CreateSetLastJavaFrame(); llvm::CallInst *res = builder()->CreateCall(callee, args_start, args_end); - reset_last_Java_frame(); + stack()->CreateResetLastJavaFrame(); cache_after_VM_call(); if (exception_action & EAM_CHECK) { check_pending_exception(exception_action); diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkType.cpp --- a/ports/hotspot/src/share/vm/shark/sharkType.cpp Wed Nov 11 10:50:38 2009 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -/* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2008 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/_sharkType.cpp.incl" - -using namespace llvm; - -const PointerType* SharkType::_cpCacheEntry_type; -const FunctionType* SharkType::_entry_point_type; -const FunctionType* SharkType::_osr_entry_point_type; -const PointerType* SharkType::_itableOffsetEntry_type; -const PointerType* SharkType::_klass_type; -const PointerType* SharkType::_methodOop_type; -const ArrayType* SharkType::_monitor_type; -const PointerType* SharkType::_oop_type; -const PointerType* SharkType::_thread_type; -const PointerType* SharkType::_zeroStack_type; - -const Type* SharkType::_to_stackType_tab[T_CONFLICT + 1]; -const Type* SharkType::_to_arrayType_tab[T_CONFLICT + 1]; - -void SharkType::initialize() -{ - // VM types - _cpCacheEntry_type = PointerType::getUnqual( -#if SHARK_LLVM_VERSION >= 26 - ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(ConstantPoolCacheEntry))); -#else - ArrayType::get(Type::Int8Ty, sizeof(ConstantPoolCacheEntry))); -#endif - - _itableOffsetEntry_type = PointerType::getUnqual( -#if SHARK_LLVM_VERSION >= 26 - ArrayType::get(Type::getInt8Ty(getGlobalContext()), itableOffsetEntry::size() * wordSize)); -#else - ArrayType::get(Type::Int8Ty, itableOffsetEntry::size() * wordSize)); -#endif - - _klass_type = PointerType::getUnqual( -#if SHARK_LLVM_VERSION >= 26 - ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(Klass))); -#else - ArrayType::get(Type::Int8Ty, sizeof(Klass))); -#endif - - _methodOop_type = PointerType::getUnqual( -#if SHARK_LLVM_VERSION >= 26 - ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(methodOopDesc))); -#else - ArrayType::get(Type::Int8Ty, sizeof(methodOopDesc))); -#endif - - _monitor_type = ArrayType::get( -#if SHARK_LLVM_VERSION >= 26 - Type::getInt8Ty(getGlobalContext()), -#else - Type::Int8Ty, -#endif - frame::interpreter_frame_monitor_size() * wordSize); - - _oop_type = PointerType::getUnqual( -#if SHARK_LLVM_VERSION >= 26 - ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(oopDesc))); -#else - ArrayType::get(Type::Int8Ty, sizeof(oopDesc))); -#endif - - _thread_type = PointerType::getUnqual( -#if SHARK_LLVM_VERSION >= 26 - ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(JavaThread))); -#else - ArrayType::get(Type::Int8Ty, sizeof(JavaThread))); -#endif - - _zeroStack_type = PointerType::getUnqual( -#if SHARK_LLVM_VERSION >= 26 - ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(ZeroStack))); -#else - ArrayType::get(Type::Int8Ty, sizeof(ZeroStack))); -#endif - - std::vector<const Type*> params; - params.push_back(methodOop_type()); - params.push_back(intptr_type()); - params.push_back(thread_type()); -#if SHARK_LLVM_VERSION >= 26 - _entry_point_type = FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false); -#else - _entry_point_type = FunctionType::get(Type::VoidTy, params, false); -#endif - - params.clear(); - params.push_back(methodOop_type()); - params.push_back(PointerType::getUnqual(jbyte_type())); - params.push_back(intptr_type()); - params.push_back(thread_type()); -#if SHARK_LLVM_VERSION >= 26 - _osr_entry_point_type = FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false); -#else - _osr_entry_point_type = FunctionType::get(Type::VoidTy, params, false); -#endif - - // Java types a) on the stack and in fields, and b) in arrays - for (int i = 0; i < T_CONFLICT + 1; i++) { - switch (i) { - case T_BOOLEAN: - _to_stackType_tab[i] = jint_type(); - _to_arrayType_tab[i] = jboolean_type(); - break; - - case T_BYTE: - _to_stackType_tab[i] = jint_type(); - _to_arrayType_tab[i] = jbyte_type(); - break; - - case T_CHAR: - _to_stackType_tab[i] = jint_type(); - _to_arrayType_tab[i] = jchar_type(); - break; - - case T_SHORT: - _to_stackType_tab[i] = jint_type(); - _to_arrayType_tab[i] = jshort_type(); - break; - - case T_INT: - _to_stackType_tab[i] = jint_type(); - _to_arrayType_tab[i] = jint_type(); - break; - - case T_LONG: - _to_stackType_tab[i] = jlong_type(); - _to_arrayType_tab[i] = jlong_type(); - break; - - case T_FLOAT: - _to_stackType_tab[i] = jfloat_type(); - _to_arrayType_tab[i] = jfloat_type(); - break; - - case T_DOUBLE: - _to_stackType_tab[i] = jdouble_type(); - _to_arrayType_tab[i] = jdouble_type(); - break; - - case T_OBJECT: - case T_ARRAY: - _to_stackType_tab[i] = oop_type(); - _to_arrayType_tab[i] = oop_type(); - break; - - case T_ADDRESS: - _to_stackType_tab[i] = intptr_type(); - break; - } - } -} diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkType.hpp --- a/ports/hotspot/src/share/vm/shark/sharkType.hpp Wed Nov 11 10:50:38 2009 -0500 +++ b/ports/hotspot/src/share/vm/shark/sharkType.hpp Wed Nov 11 16:21:16 2009 +0000 @@ -24,178 +24,111 @@ */ class SharkType : public AllStatic { + private: + static SharkContext& context() + { + return SharkContext::current(); + } + + // Basic types public: - static void initialize(); - - // C types - public: + static const llvm::Type* void_type() + { + return context().void_type(); + } + static const llvm::IntegerType* bit_type() + { + return context().bit_type(); + } + static const llvm::IntegerType* jbyte_type() + { + return context().jbyte_type(); + } + static const llvm::IntegerType* jshort_type() + { + return context().jshort_type(); + } + static const llvm::IntegerType* jint_type() + { + return context().jint_type(); + } + static const llvm::IntegerType* jlong_type() + { + return context().jlong_type(); + } + static const llvm::Type* jfloat_type() + { + return context().jfloat_type(); + } + static const llvm::Type* jdouble_type() + { + return context().jdouble_type(); + } static const llvm::IntegerType* intptr_type() { -#if SHARK_LLVM_VERSION >= 26 - return LP64_ONLY(llvm::Type::getInt64Ty(llvm::getGlobalContext())) - NOT_LP64 (llvm::Type::getInt32Ty(llvm::getGlobalContext())); -#else - return LP64_ONLY(llvm::Type::Int64Ty) - NOT_LP64 (llvm::Type::Int32Ty); -#endif + return context().intptr_type(); } - // VM types - private: - static const llvm::PointerType* _cpCacheEntry_type; - static const llvm::FunctionType* _entry_point_type; - static const llvm::FunctionType* _osr_entry_point_type; - static const llvm::PointerType* _itableOffsetEntry_type; - static const llvm::PointerType* _klass_type; - static const llvm::PointerType* _methodOop_type; - static const llvm::ArrayType* _monitor_type; - static const llvm::PointerType* _oop_type; - static const llvm::PointerType* _thread_type; - static const llvm::PointerType* _zeroStack_type; - + // Compound types public: - static const llvm::PointerType* cpCacheEntry_type() + static const llvm::PointerType* itableOffsetEntry_type() { - return _cpCacheEntry_type; + return context().itableOffsetEntry_type(); + } + static const llvm::PointerType* jniEnv_type() + { + return context().jniEnv_type(); + } + static const llvm::PointerType* jniHandleBlock_type() + { + return context().jniHandleBlock_type(); + } + static const llvm::PointerType* klass_type() + { + return context().klass_type(); + } + static const llvm::PointerType* methodOop_type() + { + return context().methodOop_type(); + } + static const llvm::ArrayType* monitor_type() + { + return context().monitor_type(); + } + static const llvm::PointerType* oop_type() + { + return context().oop_type(); + } + static const llvm::PointerType* thread_type() + { + return context().thread_type(); + } + static const llvm::PointerType* zeroStack_type() + { + return context().zeroStack_type(); } static const llvm::FunctionType* entry_point_type() { - return _entry_point_type; + return context().entry_point_type(); } static const llvm::FunctionType* osr_entry_point_type() { - return _osr_entry_point_type; - } - static const llvm::PointerType* itableOffsetEntry_type() - { - return _itableOffsetEntry_type; - } - static const llvm::PointerType* klass_type() - { - return _klass_type; - } - static const llvm::PointerType* methodOop_type() - { - return _methodOop_type; - } - static const llvm::ArrayType* monitor_type() - { - return _monitor_type; - } - static const llvm::PointerType* oop_type() - { - return _oop_type; - } - static const llvm::PointerType* thread_type() - { - return _thread_type; - } - static const llvm::PointerType* zeroStack_type() - { - return _zeroStack_type; + return context().osr_entry_point_type(); } - // Java types - public: - static const llvm::IntegerType* jboolean_type() - { -#if SHARK_LLVM_VERSION >= 26 - return llvm::Type::getInt8Ty(llvm::getGlobalContext()); -#else - return llvm::Type::Int8Ty; -#endif - } - static const llvm::IntegerType* jbyte_type() - { -#if SHARK_LLVM_VERSION >= 26 - return llvm::Type::getInt8Ty(llvm::getGlobalContext()); -#else - return llvm::Type::Int8Ty; -#endif - } - static const llvm::IntegerType* jchar_type() - { -#if SHARK_LLVM_VERSION >= 26 - return llvm::Type::getInt16Ty(llvm::getGlobalContext()); -#else - return llvm::Type::Int16Ty; -#endif - } - static const llvm::IntegerType* jshort_type() - { -#if SHARK_LLVM_VERSION >= 26 - return llvm::Type::getInt16Ty(llvm::getGlobalContext()); -#else - return llvm::Type::Int16Ty; -#endif - } - static const llvm::IntegerType* jint_type() - { -#if SHARK_LLVM_VERSION >= 26 - return llvm::Type::getInt32Ty(llvm::getGlobalContext()); -#else - return llvm::Type::Int32Ty; -#endif - } - static const llvm::IntegerType* jlong_type() - { -#if SHARK_LLVM_VERSION >= 26 - return llvm::Type::getInt64Ty(llvm::getGlobalContext()); -#else - return llvm::Type::Int64Ty; -#endif - } - static const llvm::Type* jfloat_type() - { -#if SHARK_LLVM_VERSION >= 26 - return llvm::Type::getFloatTy(llvm::getGlobalContext()); -#else - return llvm::Type::FloatTy; -#endif - } - static const llvm::Type* jdouble_type() - { -#if SHARK_LLVM_VERSION >= 26 - return llvm::Type::getDoubleTy(llvm::getGlobalContext()); -#else - return llvm::Type::DoubleTy; -#endif - } - - // Java types as they appear on the stack and in fields - private: - static const llvm::Type* _to_stackType_tab[T_CONFLICT + 1]; - + // Mappings public: static const llvm::Type* to_stackType(BasicType type) { -#ifdef ASSERT - if (type < 0 || type > T_CONFLICT || _to_stackType_tab[type] == NULL) { - tty->print_cr("Unhandled type %s", type2name(type)); - ShouldNotReachHere(); - } -#endif // ASSERT - return _to_stackType_tab[type]; + return context().to_stackType(type); } static const llvm::Type* to_stackType(ciType* type) { return to_stackType(type->basic_type()); } - - // Java types as they appear in arrays - private: - static const llvm::Type* _to_arrayType_tab[T_CONFLICT + 1]; - - public: static const llvm::Type* to_arrayType(BasicType type) { -#ifdef ASSERT - if (type < 0 || type > T_CONFLICT || _to_arrayType_tab[type] == NULL) { - tty->print_cr("Unhandled type %s", type2name(type)); - ShouldNotReachHere(); - } -#endif // ASSERT - return _to_arrayType_tab[type]; + return context().to_arrayType(type); } static const llvm::Type* to_arrayType(ciType* type) { |
| Free embeddable forum powered by Nabble | Forum Help |