Native method wrapper generation
Gary Benson
gbenson at redhat.com
Wed Nov 11 08:38:39 PST 2009
Hi 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/
-------------- next part --------------
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 at redhat.com>
+
+ * 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 at redhat.com>
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)
{
More information about the distro-pkg-dev
mailing list