--- old/src/cpu/zero/vm/assembler_zero.cpp 2012-11-21 18:10:54.147714170 +0100 +++ new/src/cpu/zero/vm/assembler_zero.cpp 2012-11-21 18:10:53.972714377 +0100 @@ -80,6 +80,11 @@ emit_address((address) obj); } +void MacroAssembler::store_Metadata(Metadata* md) { + code_section()->relocate(pc(), metadata_Relocation::spec_for_immediate()); + emit_address((address) md); +} + static void should_not_call() { report_should_not_call(__FILE__, __LINE__); } --- old/src/cpu/zero/vm/assembler_zero.hpp 2012-11-21 18:10:55.044713105 +0100 +++ new/src/cpu/zero/vm/assembler_zero.hpp 2012-11-21 18:10:54.889713288 +0100 @@ -55,6 +55,7 @@ public: void advance(int bytes); void store_oop(jobject obj); + void store_Metadata(Metadata* obj); }; #ifdef ASSERT --- old/src/cpu/zero/vm/cppInterpreter_zero.cpp 2012-11-21 18:10:56.022711948 +0100 +++ new/src/cpu/zero/vm/cppInterpreter_zero.cpp 2012-11-21 18:10:55.859712140 +0100 @@ -1015,11 +1015,7 @@ // Helper for figuring out if frames are interpreter frames bool CppInterpreter::contains(address pc) { -#ifdef PRODUCT - ShouldNotCallThis(); -#else return false; // make frame::print_value_on work -#endif // !PRODUCT } // Result handlers and convertors --- old/src/cpu/zero/vm/globals_zero.hpp 2012-11-21 18:10:56.984710809 +0100 +++ new/src/cpu/zero/vm/globals_zero.hpp 2012-11-21 18:10:56.828710994 +0100 @@ -52,11 +52,7 @@ define_pd_global(bool, RewriteBytecodes, true); define_pd_global(bool, RewriteFrequentPairs, true); -#ifdef _ALLBSD_SOURCE define_pd_global(bool, UseMembar, true); -#else -define_pd_global(bool, UseMembar, false); -#endif // GC Ergo Flags define_pd_global(intx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread --- old/src/share/vm/runtime/thread.cpp 2012-11-21 18:10:58.174709401 +0100 +++ new/src/share/vm/runtime/thread.cpp 2012-11-21 18:10:57.983709626 +0100 @@ -3626,7 +3626,7 @@ } // initialize compiler(s) -#if defined(COMPILER1) || defined(COMPILER2) +#if defined(COMPILER1) || defined(COMPILER2) || defined(SHARK) CompileBroker::compilation_init(); #endif --- old/src/share/vm/shark/llvmHeaders.hpp 2012-11-21 18:10:59.422707925 +0100 +++ new/src/share/vm/shark/llvmHeaders.hpp 2012-11-21 18:10:59.246708132 +0100 @@ -35,6 +35,7 @@ #undef DEBUG #endif +#include #include #include #include @@ -42,29 +43,17 @@ #include #include #include -#if SHARK_LLVM_VERSION < 27 -#include -#endif #include -#if SHARK_LLVM_VERSION >= 29 #include -#else -#include -#endif -#include +#include #include #include #include -#if SHARK_LLVM_VERSION >= 27 +#include #include #include #include -#if SHARK_LLVM_VERSION >= 29 #include -#else -#include -#endif -#endif #include --- old/src/share/vm/shark/llvmValue.hpp 2012-11-21 18:11:00.405706763 +0100 +++ new/src/share/vm/shark/llvmValue.hpp 2012-11-21 18:11:00.247706951 +0100 @@ -56,6 +56,10 @@ { return llvm::ConstantPointerNull::get(SharkType::oop_type()); } + static llvm::ConstantPointerNull* nullKlass() + { + return llvm::ConstantPointerNull::get(SharkType::klass_type()); + } public: static llvm::ConstantInt* bit_constant(int value) --- old/src/share/vm/shark/sharkBlock.cpp 2012-11-21 18:11:01.381705609 +0100 +++ new/src/share/vm/shark/sharkBlock.cpp 2012-11-21 18:11:01.179705849 +0100 @@ -170,10 +170,12 @@ case Bytecodes::_ldc: case Bytecodes::_ldc_w: - case Bytecodes::_ldc2_w: - push(SharkConstant::for_ldc(iter())->value(builder())); + case Bytecodes::_ldc2_w: { + SharkConstant* constant = SharkConstant::for_ldc(iter()); + assert(constant->is_loaded(), "trap should handle unloaded classes"); + push(constant->value(builder())); break; - + } case Bytecodes::_iload_0: case Bytecodes::_lload_0: case Bytecodes::_fload_0: @@ -1000,9 +1002,9 @@ builder()->SetInsertPoint(done); PHINode *result; if (is_long) - result = builder()->CreatePHI(SharkType::jlong_type(), "result"); + result = builder()->CreatePHI(SharkType::jlong_type(), 0, "result"); else - result = builder()->CreatePHI(SharkType::jint_type(), "result"); + result = builder()->CreatePHI(SharkType::jint_type(), 0, "result"); result->addIncoming(special_result, special_case); result->addIncoming(general_result, general_case); @@ -1036,12 +1038,12 @@ value = constant->value(builder()); } if (!is_get || value == NULL) { - if (!is_field) - object = builder()->CreateInlineOop(field->holder()); - + if (!is_field) { + object = builder()->CreateInlineOop(field->holder()->java_mirror()); + } BasicType basic_type = field->type()->basic_type(); - const Type *stack_type = SharkType::to_stackType(basic_type); - const Type *field_type = SharkType::to_arrayType(basic_type); + Type *stack_type = SharkType::to_stackType(basic_type); + Type *field_type = SharkType::to_arrayType(basic_type); Value *addr = builder()->CreateAddressOfStructEntry( object, in_ByteSize(field->offset_in_bytes()), @@ -1072,8 +1074,9 @@ if (!field->type()->is_primitive_type()) builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr); - if (field->is_volatile()) - builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD); + if (field->is_volatile()) { + builder()->CreateFence(llvm::SequentiallyConsistent, llvm::CrossThread); + } } } @@ -1105,7 +1108,7 @@ builder()->CreateBr(done); builder()->SetInsertPoint(done); - PHINode *result = builder()->CreatePHI(SharkType::jint_type(), "result"); + PHINode *result = builder()->CreatePHI(SharkType::jint_type(), 0, "result"); result->addIncoming(LLVMValue::jint_constant(-1), lt); result->addIncoming(LLVMValue::jint_constant(0), eq); result->addIncoming(LLVMValue::jint_constant(1), gt); @@ -1152,7 +1155,7 @@ builder()->CreateBr(done); builder()->SetInsertPoint(done); - PHINode *result = builder()->CreatePHI(SharkType::jint_type(), "result"); + PHINode *result = builder()->CreatePHI(SharkType::jint_type(), 0, "result"); result->addIncoming(LLVMValue::jint_constant(-1), lt); result->addIncoming(LLVMValue::jint_constant(0), eq); result->addIncoming(LLVMValue::jint_constant(1), gt); --- old/src/share/vm/shark/sharkBuilder.cpp 2012-11-21 18:11:02.402704405 +0100 +++ new/src/share/vm/shark/sharkBuilder.cpp 2012-11-21 18:11:02.222704618 +0100 @@ -47,14 +47,14 @@ // Helpers for accessing structures Value* SharkBuilder::CreateAddressOfStructEntry(Value* base, ByteSize offset, - const Type* type, + Type* type, const char* name) { return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name); } LoadInst* SharkBuilder::CreateValueOfStructEntry(Value* base, ByteSize offset, - const Type* type, + Type* type, const char* name) { return CreateLoad( CreateAddressOfStructEntry( @@ -71,7 +71,7 @@ } Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, - const Type* element_type, + Type* element_type, int element_bytes, ByteSize base_offset, Value* index, @@ -114,7 +114,7 @@ // Helpers for creating intrinsics and external functions. -const Type* SharkBuilder::make_type(char type, bool void_ok) { +Type* SharkBuilder::make_type(char type, bool void_ok) { switch (type) { // Primitive types case 'c': @@ -146,6 +146,8 @@ return PointerType::getUnqual(SharkType::monitor_type()); case 'O': return SharkType::oop_type(); + case 'K': + return SharkType::klass_type(); // Miscellaneous case 'v': @@ -159,14 +161,14 @@ } } -const FunctionType* SharkBuilder::make_ftype(const char* params, +FunctionType* SharkBuilder::make_ftype(const char* params, const char* ret) { - std::vector param_types; + std::vector param_types; for (const char* c = params; *c; c++) param_types.push_back(make_type(*c, false)); assert(strlen(ret) == 1, "should be"); - const Type *return_type = make_type(*ret, true); + Type *return_type = make_type(*ret, true); return FunctionType::get(return_type, param_types, false); } @@ -274,7 +276,7 @@ } Value* SharkBuilder::is_subtype_of() { - return make_function((address) SharkRuntime::is_subtype_of, "OO", "c"); + return make_function((address) SharkRuntime::is_subtype_of, "KK", "c"); } Value* SharkBuilder::current_time_millis() { @@ -352,79 +354,14 @@ "T", "v"); } -// Low-level non-VM calls - -// The ARM-specific code here is to work around unimplemented -// atomic exchange and memory barrier intrinsics in LLVM. -// -// Delegating to external functions for these would normally -// incur a speed penalty, but Linux on ARM is a special case -// in that atomic operations on that platform are handled by -// external functions anyway. It would be *preferable* for -// the calls to be hidden away in LLVM, but it's not hurting -// performance so having the calls here is acceptable. -// -// If you are building Shark on a platform without atomic -// exchange and/or memory barrier intrinsics then it is only -// acceptable to mimic this approach if your platform cannot -// perform these operations without delegating to a function. - -#ifdef ARM -static jint zero_cmpxchg_int(volatile jint *ptr, jint oldval, jint newval) { - return Atomic::cmpxchg(newval, ptr, oldval); -} -#endif // ARM - -Value* SharkBuilder::cmpxchg_int() { - return make_function( -#ifdef ARM - (address) zero_cmpxchg_int, -#else - "llvm.atomic.cmp.swap.i32.p0i32", -#endif // ARM - "Iii", "i"); -} - -#ifdef ARM -static intptr_t zero_cmpxchg_ptr(volatile intptr_t* ptr, - intptr_t oldval, - intptr_t newval) { - return Atomic::cmpxchg_ptr(newval, ptr, oldval); -} -#endif // ARM - -Value* SharkBuilder::cmpxchg_ptr() { - return make_function( -#ifdef ARM - (address) zero_cmpxchg_ptr, -#else - "llvm.atomic.cmp.swap.i" LP64_ONLY("64") NOT_LP64("32") ".p0i" LP64_ONLY("64") NOT_LP64("32"), -#endif // ARM - "Xxx", "x"); -} - Value* SharkBuilder::frame_address() { return make_function("llvm.frameaddress", "i", "C"); } -Value* SharkBuilder::memory_barrier() { - return make_function( -#ifdef ARM - (address) 0xffff0fa0, // __kernel_dmb -#else - "llvm.memory.barrier", -#endif // ARM - "11111", "v"); -} - Value* SharkBuilder::memset() { -#if SHARK_LLVM_VERSION >= 28 // LLVM 2.8 added a fifth isVolatile field for memset // introduced with LLVM r100304 return make_function("llvm.memset.i32", "Cciii", "v"); -#else - return make_function("llvm.memset.i32", "Ccii", "v"); -#endif } Value* SharkBuilder::unimplemented() { @@ -441,43 +378,16 @@ // Public interface to low-level non-VM calls -CallInst* SharkBuilder::CreateCmpxchgInt(Value* exchange_value, - Value* dst, - Value* compare_value) { - return CreateCall3(cmpxchg_int(), dst, compare_value, exchange_value); -} - -CallInst* SharkBuilder::CreateCmpxchgPtr(Value* exchange_value, - Value* dst, - Value* compare_value) { - return CreateCall3(cmpxchg_ptr(), dst, compare_value, exchange_value); -} - CallInst* SharkBuilder::CreateGetFrameAddress() { return CreateCall(frame_address(), LLVMValue::jint_constant(0)); } -CallInst *SharkBuilder::CreateMemoryBarrier(int flags) { - Value *args[] = { - LLVMValue::bit_constant((flags & BARRIER_LOADLOAD) ? 1 : 0), - LLVMValue::bit_constant((flags & BARRIER_LOADSTORE) ? 1 : 0), - LLVMValue::bit_constant((flags & BARRIER_STORELOAD) ? 1 : 0), - LLVMValue::bit_constant((flags & BARRIER_STORESTORE) ? 1 : 0), - LLVMValue::bit_constant(1)}; - - return CreateCall(memory_barrier(), args, args + 5); -} - CallInst* SharkBuilder::CreateMemset(Value* dst, Value* value, Value* len, Value* align) { -#if SHARK_LLVM_VERSION >= 28 return CreateCall5(memset(), dst, value, len, align, LLVMValue::jint_constant(0)); -#else - return CreateCall4(memset(), dst, value, len, align); -#endif } CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) { @@ -510,11 +420,7 @@ if (isa(value->getType())) value = CreatePtrToInt(value, SharkType::intptr_type()); else if (value->getType()-> -#if SHARK_LLVM_VERSION >= 27 isIntegerTy() -#else - isInteger() -#endif ) value = CreateIntCast(value, SharkType::intptr_type(), false); else @@ -563,9 +469,19 @@ name); } +Value* SharkBuilder::CreateInlineMetadata(Metadata* metadata, llvm::PointerType* type, const char* name) { + assert(metadata != NULL, "inlined metadata must not be NULL"); + assert(metadata->is_metadata(), "sanity check"); + return CreateLoad( + CreateIntToPtr( + code_buffer_address(code_buffer()->inline_Metadata(metadata)), + PointerType::getUnqual(type)), + name); +} + Value* SharkBuilder::CreateInlineData(void* data, size_t size, - const Type* type, + Type* type, const char* name) { return CreateIntToPtr( code_buffer_address(code_buffer()->inline_data(data, size)), --- old/src/share/vm/shark/sharkBuilder.hpp 2012-11-21 18:11:03.767702793 +0100 +++ new/src/share/vm/shark/sharkBuilder.hpp 2012-11-21 18:11:03.522703083 +0100 @@ -57,18 +57,18 @@ public: llvm::Value* CreateAddressOfStructEntry(llvm::Value* base, ByteSize offset, - const llvm::Type* type, + llvm::Type* type, const char *name = ""); llvm::LoadInst* CreateValueOfStructEntry(llvm::Value* base, ByteSize offset, - const llvm::Type* type, + llvm::Type* type, const char *name = ""); // Helpers for accessing arrays. public: llvm::LoadInst* CreateArrayLength(llvm::Value* arrayoop); llvm::Value* CreateArrayAddress(llvm::Value* arrayoop, - const llvm::Type* element_type, + llvm::Type* element_type, int element_bytes, ByteSize base_offset, llvm::Value* index, @@ -85,8 +85,8 @@ // Helpers for creating intrinsics and external functions. private: - static const llvm::Type* make_type(char type, bool void_ok); - static const llvm::FunctionType* make_ftype(const char* params, + static llvm::Type* make_type(char type, bool void_ok); + static llvm::FunctionType* make_ftype(const char* params, const char* ret); llvm::Value* make_function(const char* name, const char* params, @@ -173,14 +173,7 @@ // Public interface to low-level non-VM calls. public: - llvm::CallInst* CreateCmpxchgInt(llvm::Value* exchange_value, - llvm::Value* dst, - llvm::Value* compare_value); - llvm::CallInst* CreateCmpxchgPtr(llvm::Value* exchange_value, - llvm::Value* dst, - llvm::Value* compare_value); llvm::CallInst* CreateGetFrameAddress(); - llvm::CallInst* CreateMemoryBarrier(int flags); llvm::CallInst* CreateMemset(llvm::Value* dst, llvm::Value* value, llvm::Value* len, @@ -209,9 +202,14 @@ llvm::Value* CreateInlineOop(ciObject* object, const char* name = "") { return CreateInlineOop(object->constant_encoding(), name); } + + llvm::Value* CreateInlineMetadata(Metadata* metadata, llvm::PointerType* type, const char* name = ""); + llvm::Value* CreateInlineMetadata(ciMetadata* metadata, llvm::PointerType* type, const char* name = "") { + return CreateInlineMetadata(metadata->constant_encoding(), type, name); + } llvm::Value* CreateInlineData(void* data, size_t size, - const llvm::Type* type, + llvm::Type* type, const char* name = ""); // Helpers for creating basic blocks. --- old/src/share/vm/shark/sharkCacheDecache.cpp 2012-11-21 18:11:04.796701580 +0100 +++ new/src/share/vm/shark/sharkCacheDecache.cpp 2012-11-21 18:11:04.589701824 +0100 @@ -107,11 +107,10 @@ void SharkDecacher::process_method_slot(Value** value, int offset) { // Decache the method pointer write_value_to_frame( - SharkType::Method*_type(), + SharkType::Method_type(), *value, offset); - oopmap()->set_oop(slot2reg(offset)); } void SharkDecacher::process_pc_slot(int offset) { @@ -205,7 +204,7 @@ void SharkCacher::process_method_slot(Value** value, int offset) { // Cache the method pointer - *value = read_value_from_frame(SharkType::Method*_type(), offset); + *value = read_value_from_frame(SharkType::Method_type(), offset); } void SharkFunctionEntryCacher::process_method_slot(Value** value, int offset) { @@ -230,7 +229,7 @@ } Value* SharkOSREntryCacher::CreateAddressOfOSRBufEntry(int offset, - const Type* type) { + Type* type) { Value *result = builder()->CreateStructGEP(osr_buf(), offset); if (type != SharkType::intptr_type()) result = builder()->CreateBitCast(result, PointerType::getUnqual(type)); @@ -254,12 +253,12 @@ } } -void SharkDecacher::write_value_to_frame(const Type* type, +void SharkDecacher::write_value_to_frame(Type* type, Value* value, int offset) { builder()->CreateStore(value, stack()->slot_addr(offset, type)); } -Value* SharkCacher::read_value_from_frame(const Type* type, int offset) { +Value* SharkCacher::read_value_from_frame(Type* type, int offset) { return builder()->CreateLoad(stack()->slot_addr(offset, type)); } --- old/src/share/vm/shark/sharkCacheDecache.hpp 2012-11-21 18:11:05.764700437 +0100 +++ new/src/share/vm/shark/sharkCacheDecache.hpp 2012-11-21 18:11:05.599700632 +0100 @@ -192,7 +192,7 @@ // Writer helper protected: - void write_value_to_frame(const llvm::Type* type, + void write_value_to_frame(llvm::Type* type, llvm::Value* value, int offset); }; @@ -321,7 +321,7 @@ // Writer helper protected: - llvm::Value* read_value_from_frame(const llvm::Type* type, int offset); + llvm::Value* read_value_from_frame(llvm::Type* type, int offset); }; class SharkJavaCallCacher : public SharkCacher { @@ -422,7 +422,7 @@ // Helper private: - llvm::Value* CreateAddressOfOSRBufEntry(int offset, const llvm::Type* type); + llvm::Value* CreateAddressOfOSRBufEntry(int offset, llvm::Type* type); }; #endif // SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP --- old/src/share/vm/shark/sharkCodeBuffer.hpp 2012-11-21 18:11:06.775699247 +0100 +++ new/src/share/vm/shark/sharkCodeBuffer.hpp 2012-11-21 18:11:06.577699480 +0100 @@ -81,6 +81,13 @@ return offset; } + int inline_Metadata(Metadata* metadata) const { + masm()->align(BytesPerWord); + int offset = masm()->offset(); + masm()->store_Metadata(metadata); + return offset; + } + // Inline a block of non-oop data into the buffer and return its offset. public: int inline_data(void *src, size_t size) const { --- old/src/share/vm/shark/sharkCompiler.cpp 2012-11-21 18:11:07.824698009 +0100 +++ new/src/share/vm/shark/sharkCompiler.cpp 2012-11-21 18:11:07.600698275 +0100 @@ -48,7 +48,6 @@ using namespace llvm; -#if SHARK_LLVM_VERSION >= 27 namespace { cl::opt MCPU("mcpu"); @@ -57,7 +56,6 @@ MAttrs("mattr", cl::CommaSeparated); } -#endif SharkCompiler::SharkCompiler() : AbstractCompiler() { @@ -72,6 +70,9 @@ // Initialize the native target InitializeNativeTarget(); + // MCJIT require a native AsmPrinter + InitializeNativeTargetAsmPrinter(); + // Create the two contexts which we'll use _normal_context = new SharkContext("normal"); _native_context = new SharkContext("native"); @@ -79,7 +80,6 @@ // Create the memory manager _memory_manager = new SharkMemoryManager(); -#if SHARK_LLVM_VERSION >= 27 // Finetune LLVM for the current host CPU. StringMap Features; bool gotCpuFeatures = llvm::sys::getHostCPUFeatures(Features); @@ -125,13 +125,6 @@ execution_engine()->addModule( _native_context->module()); -#else - _execution_engine = ExecutionEngine::createJIT( - _normal_context->module_provider(), - NULL, memory_manager(), CodeGenOpt::Default); - execution_engine()->addModuleProvider( - _native_context->module_provider()); -#endif // All done mark_initialized(); @@ -149,6 +142,10 @@ const char *name = methodname( target->holder()->name()->as_utf8(), target->name()->as_utf8()); + if (SharkShowCompiledMethods) { + tty->print_cr("Shark compiling method: %s", name); + } + // Do the typeflow analysis ciTypeFlow *flow; if (entry_bci == InvocationEntryBci) @@ -182,6 +179,9 @@ // Build the LLVM IR for the method Function *function = SharkFunction::build(env, &builder, flow, name); + if (SharkVerifyFunctions) { + verifyFunction(*function); + } // 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 @@ -269,7 +269,6 @@ free_queued_methods(); if (SharkPrintAsmOf != NULL) { -#if SHARK_LLVM_VERSION >= 27 #ifndef NDEBUG if (!fnmatch(SharkPrintAsmOf, name, 0)) { llvm::SetCurrentDebugType(X86_ONLY("x86-emitter") NOT_X86("jit")); @@ -280,21 +279,11 @@ llvm::DebugFlag = false; } #endif // !NDEBUG -#else - // NB you need to patch LLVM with http://tinyurl.com/yf3baln for this - std::vector 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); } + assert(code != NULL, "code must be != NULL"); entry->set_entry_point(code); entry->set_function(function); entry->set_context(context()); @@ -319,8 +308,8 @@ // 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"); + assert(Thread::current()->is_Compiler_thread(), "must be called by compiler thread"); + assert_locked_or_safepoint(CodeCache_lock); SharkEntry *entry = (SharkEntry *) code; entry->context()->push_to_free_queue(entry->function()); --- old/src/share/vm/shark/sharkConstant.cpp 2012-11-21 18:11:09.038696579 +0100 +++ new/src/share/vm/shark/sharkConstant.cpp 2012-11-21 18:11:08.861696791 +0100 @@ -37,10 +37,8 @@ ciType *type = NULL; if (constant.basic_type() == T_OBJECT) { ciEnv *env = ciEnv::current(); - if (constant.as_object()->is_klass()) - type = env->Class_klass(); - else - type = env->String_klass(); + assert(constant.as_object()->klass() == env->String_klass() || constant.as_object()->klass() == env->Class_klass(), "should be"); + type = constant.as_object()->klass(); } return new SharkConstant(constant, type); } @@ -108,17 +106,16 @@ // objects (which differ between ldc* and get*, thanks!) ciObject *object = constant.as_object(); assert(type != NULL, "shouldn't be"); - if (object->is_klass()) { - // The constant returned for a klass is the ciKlass - // for the entry, but we want the java_mirror. - ciKlass *klass = object->as_klass(); - if (!klass->is_loaded()) { + + if ((! object->is_null_object()) && object->klass() == ciEnv::current()->Class_klass()) { + ciKlass *klass = object->klass(); + if (! klass->is_loaded()) { _is_loaded = false; return; } - object = klass->java_mirror(); } - if (object->is_null_object() || !object->can_be_constant()) { + + if (object->is_null_object() || ! object->can_be_constant() || ! object->is_loaded()) { _is_loaded = false; return; } --- old/src/share/vm/shark/sharkContext.cpp 2012-11-21 18:11:10.010695438 +0100 +++ new/src/share/vm/shark/sharkContext.cpp 2012-11-21 18:11:09.827695650 +0100 @@ -29,6 +29,7 @@ #include "shark/llvmHeaders.hpp" #include "shark/sharkContext.hpp" #include "utilities/globalDefinitions.hpp" +#include "memory/allocation.hpp" using namespace llvm; @@ -52,6 +53,9 @@ _itableOffsetEntry_type = PointerType::getUnqual( ArrayType::get(jbyte_type(), itableOffsetEntry::size() * wordSize)); + _Metadata_type = PointerType::getUnqual( + ArrayType::get(jbyte_type(), sizeof(Metadata))); + _klass_type = PointerType::getUnqual( ArrayType::get(jbyte_type(), sizeof(Klass))); @@ -61,7 +65,7 @@ _jniHandleBlock_type = PointerType::getUnqual( ArrayType::get(jbyte_type(), sizeof(JNIHandleBlock))); - _Method*_type = PointerType::getUnqual( + _Method_type = PointerType::getUnqual( ArrayType::get(jbyte_type(), sizeof(Method))); _monitor_type = ArrayType::get( @@ -76,14 +80,14 @@ _zeroStack_type = PointerType::getUnqual( ArrayType::get(jbyte_type(), sizeof(ZeroStack))); - std::vector params; - params.push_back(Method*_type()); + std::vector params; + params.push_back(Method_type()); params.push_back(intptr_type()); params.push_back(thread_type()); _entry_point_type = FunctionType::get(jint_type(), params, false); params.clear(); - params.push_back(Method*_type()); + params.push_back(Method_type()); params.push_back(PointerType::getUnqual(jbyte_type())); params.push_back(intptr_type()); params.push_back(thread_type()); @@ -150,7 +154,7 @@ } } -class SharkFreeQueueItem : public CHeapObj { +class SharkFreeQueueItem : public CHeapObj { public: SharkFreeQueueItem(llvm::Function* function, SharkFreeQueueItem *next) : _function(function), _next(next) {} --- old/src/share/vm/shark/sharkContext.hpp 2012-11-21 18:11:10.935694351 +0100 +++ new/src/share/vm/shark/sharkContext.hpp 2012-11-21 18:11:10.767694544 +0100 @@ -42,11 +42,7 @@ private: llvm::Module* _module; -#if SHARK_LLVM_VERSION >= 27 public: -#else - private: -#endif llvm::Module* module() const { return _module; } @@ -59,127 +55,126 @@ // Module accessors public: -#if SHARK_LLVM_VERSION < 27 - llvm::ModuleProvider* module_provider() const { - return new llvm::ExistingModuleProvider(module()); - } -#endif void add_function(llvm::Function* function) const { module()->getFunctionList().push_back(function); } llvm::Constant* get_external(const char* name, - const llvm::FunctionType* sig) { + 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; + llvm::Type* _void_type; + llvm::IntegerType* _bit_type; + llvm::IntegerType* _jbyte_type; + llvm::IntegerType* _jshort_type; + llvm::IntegerType* _jint_type; + llvm::IntegerType* _jlong_type; + llvm::Type* _jfloat_type; + llvm::Type* _jdouble_type; public: - const llvm::Type* void_type() const { + llvm::Type* void_type() const { return _void_type; } - const llvm::IntegerType* bit_type() const { + llvm::IntegerType* bit_type() const { return _bit_type; } - const llvm::IntegerType* jbyte_type() const { + llvm::IntegerType* jbyte_type() const { return _jbyte_type; } - const llvm::IntegerType* jshort_type() const { + llvm::IntegerType* jshort_type() const { return _jshort_type; } - const llvm::IntegerType* jint_type() const { + llvm::IntegerType* jint_type() const { return _jint_type; } - const llvm::IntegerType* jlong_type() const { + llvm::IntegerType* jlong_type() const { return _jlong_type; } - const llvm::Type* jfloat_type() const { + llvm::Type* jfloat_type() const { return _jfloat_type; } - const llvm::Type* jdouble_type() const { + llvm::Type* jdouble_type() const { return _jdouble_type; } - const llvm::IntegerType* intptr_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* _Method*_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; + llvm::PointerType* _itableOffsetEntry_type; + llvm::PointerType* _jniEnv_type; + llvm::PointerType* _jniHandleBlock_type; + llvm::PointerType* _Metadata_type; + llvm::PointerType* _klass_type; + llvm::PointerType* _Method_type; + llvm::ArrayType* _monitor_type; + llvm::PointerType* _oop_type; + llvm::PointerType* _thread_type; + llvm::PointerType* _zeroStack_type; + llvm::FunctionType* _entry_point_type; + llvm::FunctionType* _osr_entry_point_type; public: - const llvm::PointerType* itableOffsetEntry_type() const { + llvm::PointerType* itableOffsetEntry_type() const { return _itableOffsetEntry_type; } - const llvm::PointerType* jniEnv_type() const { + llvm::PointerType* jniEnv_type() const { return _jniEnv_type; } - const llvm::PointerType* jniHandleBlock_type() const { + llvm::PointerType* jniHandleBlock_type() const { return _jniHandleBlock_type; } - const llvm::PointerType* klass_type() const { + llvm::PointerType* Metadata_type() const { + return _Metadata_type; + } + llvm::PointerType* klass_type() const { return _klass_type; } - const llvm::PointerType* Method*_type() const { - return _Method*_type; + llvm::PointerType* Method_type() const { + return _Method_type; } - const llvm::ArrayType* monitor_type() const { + llvm::ArrayType* monitor_type() const { return _monitor_type; } - const llvm::PointerType* oop_type() const { + llvm::PointerType* oop_type() const { return _oop_type; } - const llvm::PointerType* thread_type() const { + llvm::PointerType* thread_type() const { return _thread_type; } - const llvm::PointerType* zeroStack_type() const { + llvm::PointerType* zeroStack_type() const { return _zeroStack_type; } - const llvm::FunctionType* entry_point_type() const { + llvm::FunctionType* entry_point_type() const { return _entry_point_type; } - const llvm::FunctionType* osr_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]; + llvm::Type* _to_stackType[T_CONFLICT]; + llvm::Type* _to_arrayType[T_CONFLICT]; private: - const llvm::Type* map_type(const llvm::Type* const* table, + llvm::Type* map_type(llvm::Type* const* table, BasicType type) const { assert(type >= 0 && type < T_CONFLICT, "unhandled type"); - const llvm::Type* result = table[type]; + llvm::Type* result = table[type]; assert(result != NULL, "unhandled type"); return result; } public: - const llvm::Type* to_stackType(BasicType type) const { + llvm::Type* to_stackType(BasicType type) const { return map_type(_to_stackType, type); } - const llvm::Type* to_arrayType(BasicType type) const { + llvm::Type* to_arrayType(BasicType type) const { return map_type(_to_arrayType, type); } --- old/src/share/vm/shark/sharkFunction.hpp 2012-11-21 18:11:11.871693249 +0100 +++ new/src/share/vm/shark/sharkFunction.hpp 2012-11-21 18:11:11.689693464 +0100 @@ -91,7 +91,7 @@ bool is_osr() const { return flow()->is_osr_flow(); } - const llvm::FunctionType* entry_point_type() const { + llvm::FunctionType* entry_point_type() const { if (is_osr()) return SharkType::osr_entry_point_type(); else --- old/src/share/vm/shark/sharkIntrinsics.cpp 2012-11-21 18:11:12.920692015 +0100 +++ new/src/share/vm/shark/sharkIntrinsics.cpp 2012-11-21 18:11:12.723692248 +0100 @@ -171,7 +171,7 @@ builder()->CreateBr(done); builder()->SetInsertPoint(done); - PHINode *phi = builder()->CreatePHI(a->getType(), "result"); + PHINode *phi = builder()->CreatePHI(a->getType(), 0, "result"); phi->addIncoming(a, return_a); phi->addIncoming(b, return_b); @@ -210,7 +210,7 @@ Value *klass = builder()->CreateValueOfStructEntry( state()->pop()->jobject_value(), in_ByteSize(oopDesc::klass_offset_in_bytes()), - SharkType::oop_type(), + SharkType::klass_type(), "klass"); state()->push( @@ -265,8 +265,7 @@ "addr"); // Perform the operation - Value *result = builder()->CreateCmpxchgInt(x, addr, e); - + Value *result = builder()->CreateAtomicCmpXchg(addr, e, x, llvm::SequentiallyConsistent); // Push the result state()->push( SharkValue::create_jint( --- old/src/share/vm/shark/sharkMemoryManager.cpp 2012-11-21 18:11:14.171690547 +0100 +++ new/src/share/vm/shark/sharkMemoryManager.cpp 2012-11-21 18:11:13.997690750 +0100 @@ -79,7 +79,6 @@ mm()->setMemoryExecutable(); } -#if SHARK_LLVM_VERSION >= 27 void SharkMemoryManager::deallocateExceptionTable(void *ptr) { mm()->deallocateExceptionTable(ptr); } @@ -87,26 +86,23 @@ void SharkMemoryManager::deallocateFunctionBody(void *ptr) { mm()->deallocateFunctionBody(ptr); } -#else -void SharkMemoryManager::deallocateMemForFunction(const Function* F) { - return mm()->deallocateMemForFunction(F); -} -#endif uint8_t* SharkMemoryManager::allocateGlobal(uintptr_t Size, unsigned int Alignment) { return mm()->allocateGlobal(Size, Alignment); } -#if SHARK_LLVM_VERSION < 27 -void* SharkMemoryManager::getDlsymTable() const { - return mm()->getDlsymTable(); +void* SharkMemoryManager::getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) { + return mm()->getPointerToNamedFunction(Name, AbortOnFailure); +} + +uint8_t* SharkMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { + return mm()->allocateCodeSection(Size, Alignment, SectionID); } -void SharkMemoryManager::SetDlsymTable(void *ptr) { - mm()->SetDlsymTable(ptr); +uint8_t* SharkMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { + return mm()->allocateDataSection(Size, Alignment, SectionID); } -#endif void SharkMemoryManager::setPoisonMemory(bool poison) { mm()->setPoisonMemory(poison); --- old/src/share/vm/shark/sharkMemoryManager.hpp 2012-11-21 18:11:15.195689344 +0100 +++ new/src/share/vm/shark/sharkMemoryManager.hpp 2012-11-21 18:11:15.009689559 +0100 @@ -75,20 +75,15 @@ unsigned char* TableStart, unsigned char* TableEnd, unsigned char* FrameRegister); -#if SHARK_LLVM_VERSION < 27 - void* getDlsymTable() const; - void SetDlsymTable(void *ptr); -#endif + void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true); + uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID); + uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID); void setPoisonMemory(bool); uint8_t* allocateGlobal(uintptr_t, unsigned int); void setMemoryWritable(); void setMemoryExecutable(); -#if SHARK_LLVM_VERSION >= 27 void deallocateExceptionTable(void *ptr); void deallocateFunctionBody(void *ptr); -#else - void deallocateMemForFunction(const llvm::Function* F); -#endif unsigned char *allocateSpace(intptr_t Size, unsigned int Alignment); }; --- old/src/share/vm/shark/sharkNativeWrapper.cpp 2012-11-21 18:11:16.193688173 +0100 +++ new/src/share/vm/shark/sharkNativeWrapper.cpp 2012-11-21 18:11:16.006688392 +0100 @@ -59,7 +59,6 @@ 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 @@ -83,9 +82,9 @@ } // Start building the argument list - std::vector param_types; + std::vector param_types; std::vector param_values; - const PointerType *box_type = PointerType::getUnqual(SharkType::oop_type()); + PointerType *box_type = PointerType::getUnqual(SharkType::oop_type()); // First argument is the JNIEnv param_types.push_back(SharkType::jniEnv_type()); @@ -149,7 +148,7 @@ builder()->CreateBr(merge); builder()->SetInsertPoint(merge); - phi = builder()->CreatePHI(box_type, "boxed_object"); + phi = builder()->CreatePHI(box_type, 0, "boxed_object"); phi->addIncoming(ConstantPointerNull::get(box_type), null); phi->addIncoming(box, not_null); box = phi; @@ -170,7 +169,7 @@ // fall through default: - const Type *param_type = SharkType::to_stackType(arg_type(i)); + Type *param_type = SharkType::to_stackType(arg_type(i)); param_types.push_back(param_type); param_values.push_back( @@ -201,7 +200,7 @@ // Make the call BasicType result_type = target()->result_type(); - const Type* return_type; + Type* return_type; if (result_type == T_VOID) return_type = SharkType::void_type(); else if (is_returning_oop()) @@ -213,7 +212,7 @@ PointerType::getUnqual( FunctionType::get(return_type, param_types, false))); Value *result = builder()->CreateCall( - native_function, param_values.begin(), param_values.end()); + native_function, llvm::makeArrayRef(param_values)); // Start the transition back to _thread_in_Java CreateSetThreadState(_thread_in_native_trans); @@ -221,7 +220,7 @@ // Make sure new state is visible in the GC thread if (os::is_MP()) { if (UseMembar) - builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD); + builder()->CreateFence(llvm::SequentiallyConsistent, llvm::CrossThread); else CreateWriteMemorySerializePage(); } @@ -305,7 +304,7 @@ builder()->CreateBr(merge); builder()->SetInsertPoint(merge); - PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "result"); + PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), 0, "result"); phi->addIncoming(LLVMValue::null(), null); phi->addIncoming(unboxed_result, not_null); result = phi; --- old/src/share/vm/shark/sharkStack.cpp 2012-11-21 18:11:17.175687018 +0100 +++ new/src/share/vm/shark/sharkStack.cpp 2012-11-21 18:11:16.993687232 +0100 @@ -75,7 +75,7 @@ _method_slot_offset = offset++; if (setup_sp_and_method) { builder()->CreateStore( - method, slot_addr(method_slot_offset(), SharkType::Method*_type())); + method, slot_addr(method_slot_offset(), SharkType::Method_type())); } // Unextended SP @@ -163,7 +163,7 @@ } Value* SharkStack::slot_addr(int offset, - const Type* type, + Type* type, const char* name) const { bool needs_cast = type && type != SharkType::intptr_type(); --- old/src/share/vm/shark/sharkStack.hpp 2012-11-21 18:11:18.200685816 +0100 +++ new/src/share/vm/shark/sharkStack.hpp 2012-11-21 18:11:18.034686010 +0100 @@ -204,7 +204,7 @@ // Addresses of things in the frame public: llvm::Value* slot_addr(int offset, - const llvm::Type* type = NULL, + llvm::Type* type = NULL, const char* name = "") const; llvm::Value* monitor_addr(int index) const { --- old/src/share/vm/shark/sharkState.cpp 2012-11-21 18:11:19.207684635 +0100 +++ new/src/share/vm/shark/sharkState.cpp 2012-11-21 18:11:19.036684834 +0100 @@ -131,7 +131,7 @@ Value *this_method = this->method(); Value *other_method = other->method(); if (this_method != other_method) { - PHINode *phi = builder()->CreatePHI(SharkType::Method*_type(), "method"); + PHINode *phi = builder()->CreatePHI(SharkType::Method_type(), 0, "method"); phi->addIncoming(this_method, this_block); phi->addIncoming(other_method, other_block); set_method(phi); @@ -142,7 +142,7 @@ Value *other_oop_tmp = other->oop_tmp(); if (this_oop_tmp != other_oop_tmp) { assert(this_oop_tmp && other_oop_tmp, "can't merge NULL with non-NULL"); - PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "oop_tmp"); + PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), 0, "oop_tmp"); phi->addIncoming(this_oop_tmp, this_block); phi->addIncoming(other_oop_tmp, other_block); set_oop_tmp(phi); @@ -287,7 +287,7 @@ char name[18]; // Method - set_method(builder()->CreatePHI(SharkType::Method*_type(), "method")); + set_method(builder()->CreatePHI(SharkType::Method_type(), 0, "method")); // Local variables for (int i = 0; i < max_locals(); i++) { @@ -307,7 +307,7 @@ case T_ARRAY: snprintf(name, sizeof(name), "local_%d_", i); value = SharkValue::create_phi( - type, builder()->CreatePHI(SharkType::to_stackType(type), name)); + type, builder()->CreatePHI(SharkType::to_stackType(type), 0, name)); break; case T_ADDRESS: @@ -345,7 +345,7 @@ case T_ARRAY: snprintf(name, sizeof(name), "stack_%d_", i); value = SharkValue::create_phi( - type, builder()->CreatePHI(SharkType::to_stackType(type), name)); + type, builder()->CreatePHI(SharkType::to_stackType(type), 0, name)); break; case T_ADDRESS: --- old/src/share/vm/shark/sharkTopLevelBlock.cpp 2012-11-21 18:11:20.085683604 +0100 +++ new/src/share/vm/shark/sharkTopLevelBlock.cpp 2012-11-21 18:11:19.965683746 +0100 @@ -65,6 +65,7 @@ switch (bc()) { case Bytecodes::_ldc: case Bytecodes::_ldc_w: + case Bytecodes::_ldc2_w: if (!SharkConstant::for_ldc(iter())->is_loaded()) { set_trap( Deoptimization::make_trap_request( @@ -109,7 +110,8 @@ case Bytecodes::_invokespecial: case Bytecodes::_invokevirtual: case Bytecodes::_invokeinterface: - method = iter()->get_method(will_link); + ciSignature* sig; + method = iter()->get_method(will_link, &sig); assert(will_link, "typeflow responsibility"); if (!method->holder()->is_linked()) { @@ -562,12 +564,12 @@ Value *exception_klass = builder()->CreateValueOfStructEntry( xstack(0)->jobject_value(), in_ByteSize(oopDesc::klass_offset_in_bytes()), - SharkType::oop_type(), + SharkType::klass_type(), "exception_klass"); for (int i = 0; i < num_options; i++) { Value *check_klass = - builder()->CreateInlineOop(exc_handler(i)->catch_klass()); + builder()->CreateInlineMetadata(exc_handler(i)->catch_klass(), SharkType::klass_type()); BasicBlock *not_exact = function()->CreateBlock("not_exact"); BasicBlock *not_subtype = function()->CreateBlock("not_subtype"); @@ -823,7 +825,7 @@ builder()->CreateArrayAddress( array->jarray_value(), basic_type, index->jint_value())); - const Type *stack_type = SharkType::to_stackType(basic_type); + Type *stack_type = SharkType::to_stackType(basic_type); if (value->getType() != stack_type) value = builder()->CreateIntCast(value, stack_type, basic_type != T_CHAR); @@ -910,7 +912,7 @@ ShouldNotReachHere(); } - const Type *array_type = SharkType::to_arrayType(basic_type); + Type *array_type = SharkType::to_arrayType(basic_type); if (value->getType() != array_type) value = builder()->CreateIntCast(value, array_type, basic_type != T_CHAR); @@ -1102,9 +1104,9 @@ Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method) { return builder()->CreateBitCast( - builder()->CreateInlineOop(method), - SharkType::Method*_type(), - "callee"); + builder()->CreateInlineMetadata(method, SharkType::Method_type()), + SharkType::Method_type(), + "callee"); } Value *SharkTopLevelBlock::get_virtual_callee(SharkValue* receiver, @@ -1118,7 +1120,7 @@ return builder()->CreateLoad( builder()->CreateArrayAddress( klass, - SharkType::Method*_type(), + SharkType::Method_type(), vtableEntry::size() * wordSize, in_ByteSize(InstanceKlass::vtable_start_offset() * wordSize), LLVMValue::intptr_constant(vtable_index)), @@ -1136,7 +1138,7 @@ // Locate the receiver's itable Value *object_klass = builder()->CreateValueOfStructEntry( receiver->jobject_value(), in_ByteSize(oopDesc::klass_offset_in_bytes()), - SharkType::oop_type(), + SharkType::klass_type(), "object_klass"); Value *vtable_start = builder()->CreateAdd( @@ -1169,12 +1171,12 @@ } // Locate this interface's entry in the table - Value *iklass = builder()->CreateInlineOop(method->holder()); + Value *iklass = builder()->CreateInlineMetadata(method->holder(), SharkType::klass_type()); BasicBlock *loop_entry = builder()->GetInsertBlock(); builder()->CreateBr(loop); builder()->SetInsertPoint(loop); PHINode *itable_entry_addr = builder()->CreatePHI( - SharkType::intptr_type(), "itable_entry_addr"); + SharkType::intptr_type(), 0, "itable_entry_addr"); itable_entry_addr->addIncoming(itable_start, loop_entry); Value *itable_entry = builder()->CreateIntToPtr( @@ -1183,11 +1185,11 @@ Value *itable_iklass = builder()->CreateValueOfStructEntry( itable_entry, in_ByteSize(itableOffsetEntry::interface_offset_in_bytes()), - SharkType::oop_type(), + SharkType::klass_type(), "itable_iklass"); builder()->CreateCondBr( - builder()->CreateICmpEQ(itable_iklass, LLVMValue::null()), + builder()->CreateICmpEQ(itable_iklass, LLVMValue::nullKlass()), got_null, not_null); // A null entry means that the class doesn't implement the @@ -1231,7 +1233,7 @@ method->itable_index() * itableMethodEntry::size() * wordSize)), LLVMValue::intptr_constant( itableMethodEntry::method_offset_in_bytes())), - PointerType::getUnqual(SharkType::Method*_type())), + PointerType::getUnqual(SharkType::Method_type())), "callee"); } @@ -1243,7 +1245,9 @@ // Find the method being called bool will_link; - ciMethod *dest_method = iter()->get_method(will_link); + ciSignature* sig; + ciMethod *dest_method = iter()->get_method(will_link, &sig); + assert(will_link, "typeflow responsibility"); assert(dest_method->is_static() == is_static, "must match bc"); @@ -1259,10 +1263,17 @@ assert(holder_klass->is_interface() || holder_klass->super() == NULL || !is_interface, "must match bc"); + + bool is_forced_virtual = is_interface && holder_klass == java_lang_Object_klass(); + ciKlass *holder = iter()->get_declared_method_holder(); ciInstanceKlass *klass = ciEnv::get_instance_klass_for_declared_method_holder(holder); + if (is_forced_virtual) { + klass = java_lang_Object_klass(); + } + // Find the receiver in the stack. We do this before // trying to inline because the inliner can only use // zero-checked values, not being able to perform the @@ -1294,7 +1305,7 @@ // Find the method we are calling Value *callee; if (call_is_virtual) { - if (is_virtual) { + if (is_virtual || is_forced_virtual) { assert(klass->is_linked(), "scan_for_traps responsibility"); int vtable_index = call_method->resolve_vtable_index( target()->holder(), klass); @@ -1490,12 +1501,12 @@ // Get the class we're checking against builder()->SetInsertPoint(not_null); - Value *check_klass = builder()->CreateInlineOop(klass); + Value *check_klass = builder()->CreateInlineMetadata(klass, SharkType::klass_type()); // Get the class of the object being tested Value *object_klass = builder()->CreateValueOfStructEntry( object, in_ByteSize(oopDesc::klass_offset_in_bytes()), - SharkType::oop_type(), + SharkType::klass_type(), "object_klass"); // Perform the check @@ -1520,7 +1531,7 @@ // First merge builder()->SetInsertPoint(merge1); PHINode *nonnull_result = builder()->CreatePHI( - SharkType::jint_type(), "nonnull_result"); + SharkType::jint_type(), 0, "nonnull_result"); nonnull_result->addIncoming( LLVMValue::jint_constant(IC_IS_INSTANCE), is_instance); nonnull_result->addIncoming( @@ -1531,7 +1542,7 @@ // Second merge builder()->SetInsertPoint(merge2); PHINode *result = builder()->CreatePHI( - SharkType::jint_type(), "result"); + SharkType::jint_type(), 0, "result"); result->addIncoming(LLVMValue::jint_constant(IC_IS_NULL), null_block); result->addIncoming(nonnull_result, nonnull_block); @@ -1698,7 +1709,7 @@ heap_object = builder()->CreateIntToPtr( old_top, SharkType::oop_type(), "heap_object"); - Value *check = builder()->CreateCmpxchgPtr(new_top, top_addr, old_top); + Value *check = builder()->CreateAtomicCmpXchg(top_addr, old_top, new_top, llvm::SequentiallyConsistent); builder()->CreateCondBr( builder()->CreateICmpEQ(old_top, check), initialize, retry); @@ -1707,7 +1718,7 @@ builder()->SetInsertPoint(initialize); if (tlab_object) { PHINode *phi = builder()->CreatePHI( - SharkType::oop_type(), "fast_object"); + SharkType::oop_type(), 0, "fast_object"); phi->addIncoming(tlab_object, got_tlab); phi->addIncoming(heap_object, got_heap); fast_object = phi; @@ -1730,7 +1741,7 @@ Value *klass_addr = builder()->CreateAddressOfStructEntry( fast_object, in_ByteSize(oopDesc::klass_offset_in_bytes()), - PointerType::getUnqual(SharkType::oop_type()), + PointerType::getUnqual(SharkType::klass_type()), "klass_addr"); // Set the mark @@ -1744,7 +1755,7 @@ builder()->CreateStore(LLVMValue::intptr_constant(mark), mark_addr); // Set the class - Value *rtklass = builder()->CreateInlineOop(klass); + Value *rtklass = builder()->CreateInlineMetadata(klass, SharkType::klass_type()); builder()->CreateStore(rtklass, klass_addr); got_fast = builder()->GetInsertBlock(); @@ -1767,7 +1778,7 @@ builder()->SetInsertPoint(push_object); } if (fast_object) { - PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "object"); + PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), 0, "object"); phi->addIncoming(fast_object, got_fast); phi->addIncoming(slow_object, got_slow); object = phi; @@ -1849,8 +1860,9 @@ void SharkTopLevelBlock::acquire_method_lock() { Value *lockee; - if (target()->is_static()) + if (target()->is_static()) { lockee = builder()->CreateInlineOop(target()->holder()->java_mirror()); + } else lockee = local(0)->jobject_value(); @@ -1898,7 +1910,7 @@ Value *lock = builder()->CreatePtrToInt( monitor_header_addr, SharkType::intptr_type()); - Value *check = builder()->CreateCmpxchgPtr(lock, mark_addr, disp); + Value *check = builder()->CreateAtomicCmpXchg(mark_addr, disp, lock, llvm::Acquire); builder()->CreateCondBr( builder()->CreateICmpEQ(disp, check), acquired_fast, try_recursive); @@ -1983,7 +1995,7 @@ PointerType::getUnqual(SharkType::intptr_type()), "mark_addr"); - Value *check = builder()->CreateCmpxchgPtr(disp, mark_addr, lock); + Value *check = builder()->CreateAtomicCmpXchg(mark_addr, lock, disp, llvm::Release); builder()->CreateCondBr( builder()->CreateICmpEQ(lock, check), released_fast, slow_path); --- old/src/share/vm/shark/sharkTopLevelBlock.hpp 2012-11-21 18:11:21.162682341 +0100 +++ new/src/share/vm/shark/sharkTopLevelBlock.hpp 2012-11-21 18:11:20.962682576 +0100 @@ -290,7 +290,7 @@ int exception_action) { decache_for_VM_call(); stack()->CreateSetLastJavaFrame(); - llvm::CallInst *res = builder()->CreateCall(callee, args_start, args_end); + llvm::CallInst *res = builder()->CreateCall(callee, llvm::makeArrayRef(args_start, args_end)); stack()->CreateResetLastJavaFrame(); cache_after_VM_call(); if (exception_action & EAM_CHECK) { --- old/src/share/vm/shark/sharkType.hpp 2012-11-21 18:11:22.146681185 +0100 +++ new/src/share/vm/shark/sharkType.hpp 2012-11-21 18:11:21.984681376 +0100 @@ -40,82 +40,85 @@ // Basic types public: - static const llvm::Type* void_type() { + static llvm::Type* void_type() { return context().void_type(); } - static const llvm::IntegerType* bit_type() { + static llvm::IntegerType* bit_type() { return context().bit_type(); } - static const llvm::IntegerType* jbyte_type() { + static llvm::IntegerType* jbyte_type() { return context().jbyte_type(); } - static const llvm::IntegerType* jshort_type() { + static llvm::IntegerType* jshort_type() { return context().jshort_type(); } - static const llvm::IntegerType* jint_type() { + static llvm::IntegerType* jint_type() { return context().jint_type(); } - static const llvm::IntegerType* jlong_type() { + static llvm::IntegerType* jlong_type() { return context().jlong_type(); } - static const llvm::Type* jfloat_type() { + static llvm::Type* jfloat_type() { return context().jfloat_type(); } - static const llvm::Type* jdouble_type() { + static llvm::Type* jdouble_type() { return context().jdouble_type(); } - static const llvm::IntegerType* intptr_type() { + static llvm::IntegerType* intptr_type() { return context().intptr_type(); } // Compound types public: - static const llvm::PointerType* itableOffsetEntry_type() { + static llvm::PointerType* itableOffsetEntry_type() { return context().itableOffsetEntry_type(); } - static const llvm::PointerType* jniEnv_type() { + static llvm::PointerType* jniEnv_type() { return context().jniEnv_type(); } - static const llvm::PointerType* jniHandleBlock_type() { + static llvm::PointerType* jniHandleBlock_type() { return context().jniHandleBlock_type(); } - static const llvm::PointerType* klass_type() { + static llvm::PointerType* Metadata_type() { + return context().Metadata_type(); + } + static llvm::PointerType* klass_type() { return context().klass_type(); } - static const llvm::PointerType* Method*_type() { - return context().Method*_type(); + static llvm::PointerType* Method_type() { + return context().Method_type(); } - static const llvm::ArrayType* monitor_type() { + static llvm::ArrayType* monitor_type() { return context().monitor_type(); } - static const llvm::PointerType* oop_type() { + static llvm::PointerType* oop_type() { return context().oop_type(); } - static const llvm::PointerType* thread_type() { + static llvm::PointerType* thread_type() { return context().thread_type(); } - static const llvm::PointerType* zeroStack_type() { + static llvm::PointerType* zeroStack_type() { return context().zeroStack_type(); } - static const llvm::FunctionType* entry_point_type() { + static llvm::FunctionType* entry_point_type() { return context().entry_point_type(); } - static const llvm::FunctionType* osr_entry_point_type() { + static llvm::FunctionType* osr_entry_point_type() { return context().osr_entry_point_type(); } // Mappings public: - static const llvm::Type* to_stackType(BasicType type) { + static llvm::Type* to_stackType(BasicType type) { return context().to_stackType(type); } - static const llvm::Type* to_stackType(ciType* type) { + static llvm::Type* to_stackType(ciType* type) { return to_stackType(type->basic_type()); } - static const llvm::Type* to_arrayType(BasicType type) { + static llvm::Type* to_arrayType(BasicType type) { return context().to_arrayType(type); } - static const llvm::Type* to_arrayType(ciType* type) { + static llvm::Type* to_arrayType(ciType* type) { return to_arrayType(type->basic_type()); } }; --- old/src/share/vm/shark/sharkValue.cpp 2012-11-21 18:11:23.140680023 +0100 +++ new/src/share/vm/shark/sharkValue.cpp 2012-11-21 18:11:22.946680249 +0100 @@ -233,7 +233,7 @@ assert(type() == other->type(), "should be"); assert(zero_checked() == other->zero_checked(), "should be"); - PHINode *phi = builder->CreatePHI(SharkType::to_stackType(type()), name); + PHINode *phi = builder->CreatePHI(SharkType::to_stackType(type()), 0, name); phi->addIncoming(this->generic_value(), this_block); phi->addIncoming(other->generic_value(), other_block); return SharkValue::create_generic(type(), phi, zero_checked()); --- old/src/share/vm/shark/shark_globals.hpp 2012-11-21 18:11:24.158678828 +0100 +++ new/src/share/vm/shark/shark_globals.hpp 2012-11-21 18:11:23.984679031 +0100 @@ -40,6 +40,9 @@ product(intx, SharkMaxInlineSize, 32, \ "Maximum bytecode size of methods to inline when using Shark") \ \ + product(bool, EliminateNestedLocks, true, \ + "Eliminate nested locks of the same object when possible") \ + \ /* compiler debugging */ \ develop(ccstr, SharkPrintTypeflowOf, NULL, \ "Print the typeflow of the specified method") \ @@ -58,6 +61,13 @@ \ diagnostic(bool, SharkPerformanceWarnings, false, \ "Warn about things that could be made faster") \ + \ + develop(bool, SharkVerifyFunctions, false, \ + "Runs LLVM verify over LLVM IR") \ + \ + develop(bool, SharkShowCompiledMethods, false, \ + "Prints method signature whenever a method is compiled in Shark") \ + SHARK_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)