From gbenson at redhat.com Tue Jun 2 07:17:56 2009 From: gbenson at redhat.com (Gary Benson) Date: Tue, 2 Jun 2009 15:17:56 +0100 Subject: Shark exception processing improvements (part 2) Message-ID: <20090602141756.GB3173@redhat.com> Hi all, This commit fixes a bug where if exceptions thrown during monitor setup and teardown were caught, the handler they entered would be entered as if the monitor that failed were live. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 6b95c888541f -r b7825ac40fd9 ChangeLog --- a/ChangeLog Fri May 29 12:13:53 2009 -0400 +++ b/ChangeLog Tue Jun 02 15:14:15 2009 +0100 @@ -1,3 +1,25 @@ +2009-06-02 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::ExceptionAction): Replaced with... + (SharkTopLevelBlock::ExceptionActionMask): New enum. + (SharkTopLevelBlock::check_pending_exception): Changed type + of action argument from ExceptionAction to int. + (SharkTopLevelBlock::handle_exception): Likewise. + (SharkTopLevelBlock::call_vm): Likewise. + (SharkTopLevelBlock::acquire_lock): Likewise. + (SharkTopLevelBlock::release_lock): Likewise. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::check_pending_exception): Changed type + of action argument from ExceptionAction to int, and added + monitor-fudging support. + (SharkTopLevelBlock::handle_exception): Changed type of + action argument from ExceptionAction to int. + (SharkTopLevelBlock::acquire_lock): Changed type of action + argument from ExceptionAction to int, and added monitor- + fudging to the VM call. + (SharkTopLevelBlock::release_lock): Likewise. + 2009-05-29 Omair Majid * rt/net/sourceforge/jnlp/JREDesc.java: diff -r 6b95c888541f -r b7825ac40fd9 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri May 29 12:13:53 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Tue Jun 02 15:14:15 2009 +0100 @@ -331,9 +331,9 @@ builder()->SetInsertPoint(in_bounds); } -void SharkTopLevelBlock::check_pending_exception(ExceptionAction action) +void SharkTopLevelBlock::check_pending_exception(int action) { - assert(action != EX_CHECK_NONE, "shouldn't be"); + assert(action & EAM_CHECK, "should be"); BasicBlock *exception = function()->CreateBlock("exception"); BasicBlock *no_exception = function()->CreateBlock("no_exception"); @@ -349,16 +349,23 @@ builder()->SetInsertPoint(exception); builder()->CreateStore(LLVMValue::null(), pending_exception_addr); SharkState *saved_state = current_state()->copy(); - handle_exception(pending_exception, action); + if (action & EAM_MONITOR_FUDGE) { + // The top monitor is marked live, but the exception was thrown + // while setting it up or tearing it down. We need to mark it + // dead before we enter any exception handlers as they will not + // expect it to be there. + set_num_monitors(num_monitors() - 1); + action ^= EAM_MONITOR_FUDGE; + } + handle_exception(pending_exception, action); set_current_state(saved_state); builder()->SetInsertPoint(no_exception); } -void SharkTopLevelBlock::handle_exception(Value* exception, - ExceptionAction action) +void SharkTopLevelBlock::handle_exception(Value* exception, int action) { - if (action == EX_CHECK_FULL && num_exceptions() != 0) { + if (action & EAM_HANDLE && num_exceptions() != 0) { // Clear the stack and push the exception onto it. // We do this now to protect it across the VM call // we may be about to make. @@ -1631,7 +1638,7 @@ release_lock(EX_CHECK_FULL); } -void SharkTopLevelBlock::acquire_lock(Value *lockee, ExceptionAction ea) +void SharkTopLevelBlock::acquire_lock(Value *lockee, int exception_action) { BasicBlock *try_recursive = function()->CreateBlock("try_recursive"); BasicBlock *got_recursive = function()->CreateBlock("got_recursive"); @@ -1705,7 +1712,9 @@ // It's not a recursive case so we need to drop into the runtime builder()->SetInsertPoint(not_recursive); - call_vm(SharkRuntime::monitorenter(), monitor_addr, ea); + call_vm( + SharkRuntime::monitorenter(), monitor_addr, + exception_action | EAM_MONITOR_FUDGE); BasicBlock *acquired_slow = builder()->GetInsertBlock(); builder()->CreateBr(lock_acquired); @@ -1714,7 +1723,7 @@ current_state()->merge(fast_state, acquired_fast, acquired_slow); } -void SharkTopLevelBlock::release_lock(ExceptionAction ea) +void SharkTopLevelBlock::release_lock(int exception_action) { BasicBlock *not_recursive = function()->CreateBlock("not_recursive"); BasicBlock *released_fast = function()->CreateBlock("released_fast"); @@ -1757,7 +1766,9 @@ // Need to drop into the runtime to release this one builder()->SetInsertPoint(slow_path); - call_vm(SharkRuntime::monitorexit(), monitor_addr, ea); + call_vm( + SharkRuntime::monitorexit(), monitor_addr, + exception_action | EAM_MONITOR_FUDGE); BasicBlock *released_slow = builder()->GetInsertBlock(); builder()->CreateBr(lock_released); diff -r 6b95c888541f -r b7825ac40fd9 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Fri May 29 12:13:53 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Tue Jun 02 15:14:15 2009 +0100 @@ -237,28 +237,34 @@ SharkState* saved_state, llvm::BasicBlock* continue_block); // Exceptions - enum ExceptionAction { - EX_CHECK_NONE, // don't check for pending exceptions - EX_CHECK_NO_CATCH, // if there is a pending exception then throw it - EX_CHECK_FULL // if there is a pending exception then catch it - }; // if it has a handler or throw it otherwise - void check_pending_exception(ExceptionAction action); - void handle_exception(llvm::Value* exception, ExceptionAction action); + enum ExceptionActionMask { + // The actual bitmasks that things test against + EAM_CHECK = 1, // whether to check for pending exceptions + EAM_HANDLE = 2, // whether to attempt to handle pending exceptions + EAM_MONITOR_FUDGE = 4, // whether the monitor count needs adjusting + + // More convenient values for passing + EX_CHECK_NONE = 0, + EX_CHECK_NO_CATCH = EAM_CHECK, + EX_CHECK_FULL = EAM_CHECK | EAM_HANDLE + }; + void check_pending_exception(int action); + void handle_exception(llvm::Value* exception, int action); // VM calls private: llvm::CallInst* call_vm(llvm::Constant* callee, llvm::Value** args_start, llvm::Value** args_end, - ExceptionAction ea) + int exception_action) { current_state()->decache_for_VM_call(); function()->set_last_Java_frame(); llvm::CallInst *res = builder()->CreateCall(callee, args_start, args_end); function()->reset_last_Java_frame(); current_state()->cache_after_VM_call(); - if (ea != EX_CHECK_NONE) { - check_pending_exception(ea); + if (exception_action) { + check_pending_exception(exception_action); current_state()->set_has_safepointed(true); } return res; @@ -266,40 +272,40 @@ public: llvm::CallInst* call_vm(llvm::Constant* callee, - ExceptionAction ea) + int exception_action) { llvm::Value *args[] = {thread()}; - return call_vm(callee, args, args + 1, ea); + return call_vm(callee, args, args + 1, exception_action); } llvm::CallInst* call_vm(llvm::Constant* callee, llvm::Value* arg1, - ExceptionAction ea) + int exception_action) { llvm::Value *args[] = {thread(), arg1}; - return call_vm(callee, args, args + 2, ea); + return call_vm(callee, args, args + 2, exception_action); } llvm::CallInst* call_vm(llvm::Constant* callee, llvm::Value* arg1, llvm::Value* arg2, - ExceptionAction ea) + int exception_action) { llvm::Value *args[] = {thread(), arg1, arg2}; - return call_vm(callee, args, args + 3, ea); + return call_vm(callee, args, args + 3, exception_action); } llvm::CallInst* call_vm(llvm::Constant* callee, llvm::Value* arg1, llvm::Value* arg2, llvm::Value* arg3, - ExceptionAction ea) + int exception_action) { llvm::Value *args[] = {thread(), arg1, arg2, arg3}; - return call_vm(callee, args, args + 4, ea); + return call_vm(callee, args, args + 4, exception_action); } // Synchronization private: - void acquire_lock(llvm::Value* lockee, ExceptionAction ea); - void release_lock(ExceptionAction ea); + void acquire_lock(llvm::Value* lockee, int exception_action); + void release_lock(int exception_action); public: void acquire_method_lock(); From gbenson at redhat.com Wed Jun 3 06:36:04 2009 From: gbenson at redhat.com (Gary Benson) Date: Wed, 3 Jun 2009 14:36:04 +0100 Subject: Shark direct call improvements Message-ID: <20090603133603.GA19979@redhat.com> Hi all, This commit replaces the interpreter-style lookup of the callee in the constant pool with a server-JIT-style callee inlined in the code buffer for direct calls (ie invokestatic, invokespecial, and final invokevirtual). This gives a small speedup in itself, but opens the door to a ton of other optimizations. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r e01a6da1a425 -r 6bbac4cbc210 ChangeLog --- a/ChangeLog Tue Jun 02 15:41:45 2009 +0100 +++ b/ChangeLog Wed Jun 03 14:32:52 2009 +0100 @@ -1,3 +1,33 @@ +2009-06-03 Gary Benson + + * ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp + (MacroAssembler::store_oop): New method. + * ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp + (MacroAssembler::store_oop): Likewise. + + * ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp + (Relocation::pd_address_in_code): Implement. + + * ports/hotspot/src/share/vm/shark/sharkCompiler.cpp + (SharkCompiler::compile_method): Create CodeBuffer + with space for relocations. + + * ports/hotspot/src/share/vm/shark/sharkFunction.hpp + (SharkFunction::code_offset): Renamed as... + (SharkFunction::create_unique_pc_offset): New method. + (SharkFunction::CreateAddressOfCodeBufferEntry): Likewise. + (SharkFunction::CreateAddressOfOopInCodeBuffer): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp + (SharkDecacher::start_frame): Updated to use new offset code. + (SharkDecacher::start_stack): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::scan_for_traps): Direct calls need no + checking. + (SharkTopLevelBlock::get_direct_callee): Replace constant + pool lookup with oop load from CodeBuffer. + 2009-06-02 Gary Benson * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp --- a/ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp Tue Jun 02 15:41:45 2009 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp Wed Jun 03 14:32:52 2009 +0100 @@ -60,6 +60,12 @@ sync(); } +void MacroAssembler::store_oop(jobject obj) +{ + code_section()->relocate(pc(), oop_Relocation::spec_for_immediate()); + emit_address((address) obj); +} + static void _UnimplementedStub() { report_unimplemented(__FILE__, __LINE__); diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp --- a/ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp Tue Jun 02 15:41:45 2009 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp Wed Jun 03 14:32:52 2009 +0100 @@ -1,6 +1,6 @@ /* * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2007, 2008 Red Hat, Inc. + * Copyright 2007, 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 @@ -45,8 +45,10 @@ void align(int modulus); void bang_stack_with_offset(int offset); bool needs_explicit_null_check(intptr_t offset); + public: void advance(int bytes); + void store_oop(jobject obj); }; #ifdef ASSERT diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp --- a/ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp Tue Jun 02 15:41:45 2009 +0100 +++ b/ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp Wed Jun 03 14:32:52 2009 +0100 @@ -48,7 +48,8 @@ address* Relocation::pd_address_in_code() { - Unimplemented(); + // Relocations in Shark are just stored directly + return (address *) addr(); } int Relocation::pd_breakpoint_size() diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Tue Jun 02 15:41:45 2009 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Wed Jun 03 14:32:52 2009 +0100 @@ -31,7 +31,7 @@ void SharkDecacher::start_frame() { // Start recording the debug information - _pc_offset = function()->code_offset(); + _pc_offset = function()->create_unique_pc_offset(); _oopmap = new OopMap( oopmap_slot_munge(function()->oopmap_frame_size()), oopmap_slot_munge(function()->arg_size())); @@ -119,8 +119,7 @@ { // Record the PC builder()->CreateStore( - builder()->CreateAdd( - function()->base_pc(), LLVMValue::intptr_constant(pc_offset())), + function()->CreateAddressOfCodeBufferEntry(pc_offset()), function()->CreateAddressOfFrameEntry(offset)); } diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkCompiler.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Tue Jun 02 15:41:45 2009 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Wed Jun 03 14:32:52 2009 +0100 @@ -116,8 +116,7 @@ env->set_dependencies(new Dependencies(env)); // Create the CodeBuffer and MacroAssembler - BufferBlob *bb = BufferBlob::create("shark_temp", 256 * K); - CodeBuffer cb(bb->instructions_begin(), bb->instructions_size()); + CodeBuffer cb("Shark", 256 * K, 64 * K); cb.initialize_oop_recorder(env->oop_recorder()); MacroAssembler *masm = new MacroAssembler(&cb); @@ -148,9 +147,6 @@ env->comp_level(), false, false); - - // Free the BufferBlob - BufferBlob::free(bb); } diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkFunction.hpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Tue Jun 02 15:41:45 2009 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Wed Jun 03 14:32:52 2009 +0100 @@ -137,6 +137,28 @@ return flow()->method(); } + // CodeBuffer interface + public: + int create_unique_pc_offset() const + { + int offset = masm()->offset(); + masm()->advance(1); + return offset; + } + llvm::Value* CreateAddressOfCodeBufferEntry(int offset) const + { + return builder()->CreateAdd(base_pc(), LLVMValue::intptr_constant(offset)); + } + llvm::Value* CreateAddressOfOopInCodeBuffer(ciObject* object) const + { + masm()->align(BytesPerWord); + int offset = masm()->offset(); + masm()->store_oop(object->encoding()); + return builder()->CreateIntToPtr( + CreateAddressOfCodeBufferEntry(offset), + llvm::PointerType::getUnqual(SharkType::jobject_type())); + } + // Block management private: llvm::BasicBlock* _block_insertion_point; @@ -217,17 +239,6 @@ private: llvm::Value* CreateBuildFrame(); - // OopMap support - public: - // Every time a new, distinct pc is required, an extra byte is - // emitted into the codebuffer - int code_offset() const - { - int offset = masm()->offset(); - masm()->advance(1); // keeps PCs unique - return offset; - } - private: int _extended_frame_size; int _stack_slots_offset; diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Tue Jun 02 15:41:45 2009 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Jun 03 14:32:52 2009 +0100 @@ -91,28 +91,26 @@ index = iter()->get_field_index(); break; - case Bytecodes::_invokespecial: - case Bytecodes::_invokestatic: case Bytecodes::_invokevirtual: + method = iter()->get_method(will_link); + assert(will_link, "typeflow responsibility"); + + // If this is a non-final invokevirtual then we need to + // check that its holder is linked, because its vtable + // won't have been set up otherwise. + if (!method->is_final_method() && !method->holder()->is_linked()) { + set_trap( + Deoptimization::make_trap_request( + Deoptimization::Reason_uninitialized, + Deoptimization::Action_reinterpret), bci()); + return; + } + break; + case Bytecodes::_invokeinterface: method = iter()->get_method(will_link); assert(will_link, "typeflow responsibility"); - // If this is a non-final invokevirtual then there won't - // be a pool access. We do need to check that its holder - // is linked, however, because its vtable won't have been - // set up otherwise. - if (bc() == Bytecodes::_invokevirtual && !method->is_final_method()) { - if (!method->holder()->is_linked()) { - set_trap( - Deoptimization::make_trap_request( - Deoptimization::Reason_uninitialized, - Deoptimization::Action_reinterpret), bci()); - return; - } - break; - } - // Continue to the check index = iter()->get_method_index(); break; @@ -897,15 +895,10 @@ // invokevirtual is direct in some circumstances. Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method) { - SharkConstantPool constants(this); - Value *cache = constants.cache_entry_at(iter()->get_method_index()); - return builder()->CreateValueOfStructEntry( - cache, - bc() == Bytecodes::_invokevirtual ? - ConstantPoolCacheEntry::f2_offset() : - ConstantPoolCacheEntry::f1_offset(), - SharkType::methodOop_type(), - "callee"); + return builder()->CreateLoad( + builder()->CreateBitCast( + function()->CreateAddressOfOopInCodeBuffer(method), + PointerType::getUnqual(SharkType::methodOop_type())), "callee"); } // Non-direct virtual calls are handled here From gbenson at redhat.com Wed Jun 3 08:22:16 2009 From: gbenson at redhat.com (Gary Benson) Date: Wed, 3 Jun 2009 16:22:16 +0100 Subject: Shark codebuffer refactoring Message-ID: <20090603152216.GD19979@redhat.com> Hi all, This commit moves the interface to the CodeBuffer from SharkFunction into a new class, SharkCodeBuffer, accessed through the SharkBuilder. This makes the oop-inlining code I wrote this morning accessible from anywhere in Shark. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r d50608f15874 -r 724f230eea38 ChangeLog --- a/ChangeLog Wed Jun 03 09:37:51 2009 -0400 +++ b/ChangeLog Wed Jun 03 11:15:36 2009 -0400 @@ -1,3 +1,43 @@ +2009-06-03 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp: + New file. + + * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp + (SharkBuilder::_code_buffer): New field. + (SharkBuilder::code_buffer): New method. + (SharkBuilder::set_code_buffer): Likewise. + (SharkBuilder::code_buffer_address): Likewise. + (SharkBuilder::CreateInlineOop): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkCompiler.cpp + (SharkCompiler::compile_method): Use a SharkCodeBuffer + instead of a normal CodeBuffer and MacroAssembler, and + hook it into the SharkBuilder. + + * ports/hotspot/src/share/vm/shark/sharkFunction.hpp + (SharkFunction::SharkFunction): Removed masm argument + and initialization. + (SharkFunction::_masm): Removed. + (SharkFunction::_base_pc): Likewise. + (SharkFunction::masm): Likewise. + (SharkFunction::base_pc): Likewise. + (SharkFunction::create_unique_pc_offset): Likewise. + (SharkFunction::CreateAddressOfCodeBufferEntry): Likewise. + (SharkFunction::CreateAddressOfOopInCodeBuffer): Likewise. + * ports/hotspot/src/share/vm/shark/sharkFunction.cpp + (SharkFunction::initialize): Use the new code to allocate + the SharkEntry, and set the base_pc for the SharkCodeBuffer. + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::get_direct_callee): Use new code. + + * ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp + (SharkDecacher::start_frame): Use new code. + (SharkDecacher::start_stack): Likewise. + + * ports/hotspot/src/share/vm/includeDB_shark: Updated. + 2009-06-03 Gary Benson * ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp: diff -r d50608f15874 -r 724f230eea38 ports/hotspot/src/share/vm/includeDB_shark --- a/ports/hotspot/src/share/vm/includeDB_shark Wed Jun 03 09:37:51 2009 -0400 +++ b/ports/hotspot/src/share/vm/includeDB_shark Wed Jun 03 11:15:36 2009 -0400 @@ -107,6 +107,7 @@ sharkBuilder.hpp llvmHeaders.hpp sharkBuilder.hpp llvmValue.hpp sharkBuilder.hpp sizes.hpp +sharkBuilder.hpp sharkCodeBuffer.hpp sharkBuilder.hpp sharkCompiler.hpp sharkBuilder.hpp sharkType.hpp sharkBuilder.hpp sharkValue.hpp @@ -128,10 +129,13 @@ sharkCacheDecache.hpp sharkFunction.hpp sharkCacheDecache.hpp sharkStateScanner.hpp +sharkCodeBuffer.hpp allocation.hpp +sharkCodeBuffer.hpp codeBuffer.hpp +sharkCodeBuffer.hpp llvmHeaders.hpp + sharkCompiler.cpp abstractCompiler.hpp sharkCompiler.cpp ciEnv.hpp sharkCompiler.cpp ciMethod.hpp -sharkCompiler.cpp codeBuffer.hpp sharkCompiler.cpp debug.hpp sharkCompiler.cpp debugInfoRec.hpp sharkCompiler.cpp dependencies.hpp @@ -141,6 +145,7 @@ sharkCompiler.cpp oopRecorder.hpp sharkCompiler.cpp shark_globals.hpp sharkCompiler.cpp sharkBuilder.hpp +sharkCompiler.cpp sharkCodeBuffer.hpp sharkCompiler.cpp sharkCompiler.hpp sharkCompiler.cpp sharkEntry.hpp sharkCompiler.cpp sharkFunction.hpp diff -r d50608f15874 -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkBuilder.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Wed Jun 03 09:37:51 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Wed Jun 03 11:15:36 2009 -0400 @@ -360,4 +360,35 @@ LLVMValue::intptr_constant(~(s - 1)), name); } + + // CodeBuffer interface + private: + SharkCodeBuffer* _code_buffer; + + public: + SharkCodeBuffer* code_buffer() const + { + return _code_buffer; + } + void set_code_buffer(SharkCodeBuffer* code_buffer) + { + _code_buffer = code_buffer; + } + + public: + llvm::Value* code_buffer_address(int offset) + { + return CreateAdd( + code_buffer()->base_pc(), LLVMValue::intptr_constant(offset)); + } + + public: + llvm::Value* CreateInlineOop(ciObject* object, const char* name = "") + { + return CreateLoad( + CreateIntToPtr( + code_buffer_address(code_buffer()->inline_oop(object)), + llvm::PointerType::getUnqual(SharkType::jobject_type())), + name); + } }; diff -r d50608f15874 -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Wed Jun 03 09:37:51 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Wed Jun 03 11:15:36 2009 -0400 @@ -31,7 +31,7 @@ void SharkDecacher::start_frame() { // Start recording the debug information - _pc_offset = function()->create_unique_pc_offset(); + _pc_offset = builder()->code_buffer()->create_unique_offset(); _oopmap = new OopMap( oopmap_slot_munge(function()->oopmap_frame_size()), oopmap_slot_munge(function()->arg_size())); @@ -119,7 +119,7 @@ { // Record the PC builder()->CreateStore( - function()->CreateAddressOfCodeBufferEntry(pc_offset()), + builder()->code_buffer_address(pc_offset()), function()->CreateAddressOfFrameEntry(offset)); } diff -r d50608f15874 -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp Wed Jun 03 11:15:36 2009 -0400 @@ -0,0 +1,94 @@ +/* + * 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 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); + } + + private: + CodeBuffer _cb; + MacroAssembler* _masm; + llvm::Value* _base_pc; + + public: + CodeBuffer* cb() + { + return &_cb; + } + + private: + MacroAssembler* masm() const + { + return _masm; + } + + public: + llvm::Value* base_pc() const + { + return _base_pc; + } + void set_base_pc(llvm::Value* base_pc) + { + assert(_base_pc == NULL, "only do this once"); + _base_pc = base_pc; + } + + // Allocate some space in the buffer and return its address. + // This buffer will have been relocated by the time the method + // is installed, so you can't inline the result in code. + public: + void* malloc(size_t size) const + { + masm()->align(BytesPerWord); + void *result = masm()->pc(); + masm()->advance(size); + return result; + } + + // Create a unique offset in the buffer. + public: + int create_unique_offset() const + { + int offset = masm()->offset(); + masm()->advance(1); + return offset; + } + + // Inline an oop into the buffer and return its offset. + public: + int inline_oop(ciObject* object) const + { + masm()->align(BytesPerWord); + int offset = masm()->offset(); + masm()->store_oop(object->encoding()); + return offset; + } +}; diff -r d50608f15874 -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkCompiler.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Wed Jun 03 09:37:51 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Wed Jun 03 11:15:36 2009 -0400 @@ -115,14 +115,16 @@ env->debug_info()->set_oopmaps(&oopmaps); env->set_dependencies(new Dependencies(env)); - // Create the CodeBuffer and MacroAssembler - CodeBuffer cb("Shark", 256 * K, 64 * K); - cb.initialize_oop_recorder(env->oop_recorder()); - MacroAssembler *masm = new MacroAssembler(&cb); + // Create the code buffer and hook it into the builder + SharkCodeBuffer cb(env->oop_recorder()); + builder()->set_code_buffer(&cb); - // Compile the method into the CodeBuffer + // Compile the method ciBytecodeStream iter(target); - SharkFunction function(this, name, flow, &iter, masm); + SharkFunction function(this, name, flow, &iter); + + // Unhook the code buffer + builder()->set_code_buffer(NULL); // Install the method into the VM CodeOffsets offsets; @@ -138,7 +140,7 @@ entry_bci, &offsets, 0, - &cb, + cb.cb(), 0, &oopmaps, &handler_table, diff -r d50608f15874 -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkFunction.cpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Wed Jun 03 09:37:51 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Wed Jun 03 11:15:36 2009 -0400 @@ -33,8 +33,8 @@ void SharkFunction::initialize() { // Emit the entry point - SharkEntry *entry = (SharkEntry *) masm()->pc(); - masm()->advance(sizeof(SharkEntry)); + SharkEntry *entry = + (SharkEntry *) builder()->code_buffer()->malloc(sizeof(SharkEntry)); // Create the function _function = builder()->CreateFunction(name()); @@ -45,8 +45,9 @@ Function::arg_iterator ai = function()->arg_begin(); Argument *method = ai++; method->setName("method"); - _base_pc = ai++; - _base_pc->setName("base_pc"); + Argument *base_pc = ai++; + base_pc->setName("base_pc"); + builder()->code_buffer()->set_base_pc(base_pc); _thread = ai++; _thread->setName("thread"); diff -r d50608f15874 -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkFunction.hpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Wed Jun 03 09:37:51 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Wed Jun 03 11:15:36 2009 -0400 @@ -32,13 +32,11 @@ SharkFunction(SharkCompiler* compiler, const char* name, ciTypeFlow* flow, - ciBytecodeStream* iter, - MacroAssembler* masm) + ciBytecodeStream* iter) : _compiler(compiler), _name(name), _flow(flow), - _iter(iter), - _masm(masm) + _iter(iter) { initialize(); } private: @@ -49,10 +47,8 @@ const char* _name; ciTypeFlow* _flow; ciBytecodeStream* _iter; - MacroAssembler* _masm; llvm::Function* _function; SharkTopLevelBlock** _blocks; - llvm::Value* _base_pc; llvm::Value* _thread; int _max_monitors; GrowableArray _deferred_zero_checks; @@ -74,10 +70,6 @@ { return _iter; } - MacroAssembler* masm() const - { - return _masm; - } llvm::Function* function() const { return _function; @@ -85,10 +77,6 @@ SharkTopLevelBlock* block(int i) const { return _blocks[i]; - } - llvm::Value* base_pc() const - { - return _base_pc; } llvm::Value* thread() const { @@ -135,28 +123,6 @@ ciMethod* target() const { return flow()->method(); - } - - // CodeBuffer interface - public: - int create_unique_pc_offset() const - { - int offset = masm()->offset(); - masm()->advance(1); - return offset; - } - llvm::Value* CreateAddressOfCodeBufferEntry(int offset) const - { - return builder()->CreateAdd(base_pc(), LLVMValue::intptr_constant(offset)); - } - llvm::Value* CreateAddressOfOopInCodeBuffer(ciObject* object) const - { - masm()->align(BytesPerWord); - int offset = masm()->offset(); - masm()->store_oop(object->encoding()); - return builder()->CreateIntToPtr( - CreateAddressOfCodeBufferEntry(offset), - llvm::PointerType::getUnqual(SharkType::jobject_type())); } // Block management diff -r d50608f15874 -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Jun 03 09:37:51 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Jun 03 11:15:36 2009 -0400 @@ -895,10 +895,10 @@ // invokevirtual is direct in some circumstances. Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method) { - return builder()->CreateLoad( - builder()->CreateBitCast( - function()->CreateAddressOfOopInCodeBuffer(method), - PointerType::getUnqual(SharkType::methodOop_type())), "callee"); + return builder()->CreateBitCast( + builder()->CreateInlineOop(method), + SharkType::methodOop_type(), + "callee"); } // Non-direct virtual calls are handled here From gbenson at redhat.com Thu Jun 4 06:55:14 2009 From: gbenson at redhat.com (Gary Benson) Date: Thu, 4 Jun 2009 14:55:14 +0100 Subject: Shark ldc improvements Message-ID: <20090604135514.GC3156@redhat.com> Hi all, This commit replaced the interpreter-style lookup of class and string constants in ldc and friends with inlined oops using the code I wrote yesterday. getfield and getstatic also use the code, for constant fields, so they've been altered too, although the way HotSpot lays things out means that getfield and getstatic never inline constants (they get loaded from the object instead...) Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 724f230eea38 ChangeLog --- a/ChangeLog Wed Jun 03 11:15:36 2009 -0400 +++ b/ChangeLog Thu Jun 04 09:47:24 2009 -0400 @@ -1,3 +1,32 @@ +2009-06-04 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkConstant.hpp: New file. + * ports/hotspot/src/share/vm/shark/sharkConstant.cpp: Likewise. + + * ports/hotspot/src/share/vm/shark/sharkBlock.hpp + (SharkBlock::lookup_for_ldc): Removed. + (SharkBlock::do_ldc): Likewise. + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::parse_bytecode): Use new code for ldc and friends. + (SharkBlock::do_field_access): Use new code for constant fields. + (SharkBlock::lookup_for_ldc): Removed. + + * ports/hotspot/src/share/vm/shark/sharkInliner.cpp + (SharkInlinerHelper::is_inlinable): Use new code for ldc and friends. + (SharkInlinerHelper::do_field_access): Use new code for constant fields. + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::lookup_for_ldc): Removed. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::scan_for_traps): Use new code to for ldc and + constant field traps. + (SharkTopLevelBlock::lookup_for_ldc): Removed. + + * ports/hotspot/src/share/vm/shark/sharkValue.hpp + (SharkValue::from_ciConstant): Removed. + + * ports/hotspot/src/share/vm/includeDB_shark: Updated. + 2009-06-03 Gary Benson * ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp: diff -r 724f230eea38 ports/hotspot/src/share/vm/includeDB_shark --- a/ports/hotspot/src/share/vm/includeDB_shark Wed Jun 03 11:15:36 2009 -0400 +++ b/ports/hotspot/src/share/vm/includeDB_shark Thu Jun 04 09:47:24 2009 -0400 @@ -73,6 +73,7 @@ sharkBlock.cpp shark_globals.hpp sharkBlock.cpp sharkBlock.hpp sharkBlock.cpp sharkBuilder.hpp +sharkBlock.cpp sharkConstant.hpp sharkBlock.cpp sharkRuntime.hpp sharkBlock.cpp sharkState.inline.hpp sharkBlock.cpp sharkValue.hpp @@ -83,6 +84,7 @@ sharkBlock.hpp debug.hpp sharkBlock.hpp llvmHeaders.hpp sharkBlock.hpp sharkBuilder.hpp +sharkBlock.hpp sharkConstant.hpp sharkBlock.hpp sharkState.hpp sharkBlock.hpp sharkValue.hpp @@ -158,6 +160,16 @@ sharkCompiler.hpp llvmHeaders.hpp sharkCompiler.hpp sharkMemoryManager.hpp +sharkConstant.cpp ciStreams.hpp +sharkConstant.cpp sharkBuilder.hpp +sharkConstant.cpp sharkConstant.hpp +sharkConstant.cpp sharkValue.hpp + +sharkConstant.hpp allocation.hpp +sharkConstant.hpp ciStreams.hpp +sharkConstant.hpp sharkBuilder.hpp +sharkConstant.hpp sharkValue.hpp + sharkConstantPool.cpp allocation.hpp sharkConstantPool.cpp constantPoolOop.hpp sharkConstantPool.cpp cpCacheOop.hpp @@ -215,6 +227,7 @@ sharkInliner.cpp ciMethod.hpp sharkInliner.cpp ciStreams.hpp sharkInliner.cpp shark_globals.hpp +sharkInliner.cpp sharkConstant.hpp sharkInliner.cpp sharkInliner.hpp sharkInliner.cpp sharkIntrinsics.hpp sharkInliner.cpp sharkState.inline.hpp @@ -302,6 +315,7 @@ sharkTopLevelBlock.cpp shark_globals.hpp sharkTopLevelBlock.cpp sharkTopLevelBlock.hpp sharkTopLevelBlock.cpp sharkBuilder.hpp +sharkTopLevelBlock.cpp sharkConstant.hpp sharkTopLevelBlock.cpp sharkConstantPool.hpp sharkTopLevelBlock.cpp sharkInliner.hpp sharkTopLevelBlock.cpp sharkRuntime.hpp diff -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Wed Jun 03 11:15:36 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Thu Jun 04 09:47:24 2009 -0400 @@ -163,7 +163,7 @@ case Bytecodes::_ldc: case Bytecodes::_ldc_w: case Bytecodes::_ldc2_w: - do_ldc(); + push(SharkConstant::for_ldc(iter())->value(builder())); break; case Bytecodes::_iload_0: @@ -996,7 +996,9 @@ object = value->generic_value(); } if (is_get && field->is_constant()) { - value = SharkValue::from_ciConstant(field->constant_value()); + SharkConstant *constant = SharkConstant::for_field(iter()); + if (constant->is_loaded()) + value = constant->value(builder()); } if (!is_get || value == NULL) { if (!is_field) @@ -1163,11 +1165,6 @@ ShouldNotCallThis(); } -Value* SharkBlock::lookup_for_ldc() -{ - ShouldNotCallThis(); -} - Value* SharkBlock::lookup_for_field_access() { ShouldNotCallThis(); diff -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Wed Jun 03 11:15:36 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Thu Jun 04 09:47:24 2009 -0400 @@ -202,7 +202,6 @@ // Helpers protected: virtual void do_zero_check(SharkValue* value); - virtual llvm::Value* lookup_for_ldc(); virtual llvm::Value* lookup_for_field_access(); // Leaf calls @@ -239,16 +238,6 @@ virtual int trap_request(); virtual int trap_bci(); virtual void do_trap(int trap_request); - - // ldc* - private: - void do_ldc() - { - SharkValue *value = SharkValue::from_ciConstant(iter()->get_constant()); - if (value == NULL) - value = SharkValue::create_jobject(lookup_for_ldc(), true); - push(value); - } // arraylength protected: diff -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkConstant.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkConstant.cpp Thu Jun 04 09:47:24 2009 -0400 @@ -0,0 +1,121 @@ +/* + * 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/_sharkConstant.cpp.incl" + +using namespace llvm; + +SharkConstant* SharkConstant::for_ldc(ciBytecodeStream *iter) +{ + return new SharkConstant(iter->get_constant(), NULL); +} + +SharkConstant* SharkConstant::for_field(ciBytecodeStream *iter) +{ + bool will_link; + ciField *field = iter->get_field(will_link); + assert(will_link, "typeflow responsibility"); + + return new SharkConstant(field->constant_value(), field->type()); +} + +SharkConstant::SharkConstant(ciConstant constant, ciType *type) +{ + SharkValue *value = NULL; + + switch (constant.basic_type()) { + case T_BOOLEAN: + case T_BYTE: + case T_CHAR: + case T_SHORT: + case T_INT: + value = SharkValue::jint_constant(constant.as_int()); + break; + + case T_LONG: + value = SharkValue::jlong_constant(constant.as_long()); + break; + + case T_FLOAT: + value = SharkValue::jfloat_constant(constant.as_float()); + break; + + case T_DOUBLE: + value = SharkValue::jdouble_constant(constant.as_double()); + break; + + case T_OBJECT: + case T_ARRAY: + break; + + case T_ILLEGAL: + // out of memory + _is_loaded = false; + return; + + default: + tty->print_cr("Unhandled type %s", type2name(constant.basic_type())); + ShouldNotReachHere(); + } + + // Handle primitive types. We create SharkValues for these + // now; doing so doesn't emit any code, and it allows us to + // delegate a bunch of stuff to the SharkValue code. + if (value) { + _value = value; + _is_loaded = true; + _is_nonzero = value->zero_checked(); + _is_two_word = value->is_two_word(); + return; + } + + // Handle reference types. This is tricky because some + // ciObjects are psuedo-objects that refer to oops which + // have yet to be created. We need to spot the unloaded + // objects (which differ between ldc* and get*, thanks!) + ciObject *object = constant.as_object(); + 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()) { + _is_loaded = false; + return; + } + object = klass->java_mirror(); + } + if (object->is_null_object() || !object->has_encoding()) { + _is_loaded = false; + return; + } + + _value = NULL; + _object = object; + _type = type ? type : ciType::make(T_OBJECT); + _is_loaded = true; + _is_nonzero = true; + _is_two_word = false; +} diff -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkConstant.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkConstant.hpp Thu Jun 04 09:47:24 2009 -0400 @@ -0,0 +1,68 @@ +/* + * 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 SharkConstant : public ResourceObj { + public: + static SharkConstant* for_ldc(ciBytecodeStream* iter); + static SharkConstant* for_field(ciBytecodeStream* iter); + + private: + SharkConstant(ciConstant constant, ciType* type); + + private: + SharkValue* _value; + ciObject* _object; + ciType* _type; + bool _is_loaded; + bool _is_nonzero; + bool _is_two_word; + + public: + bool is_loaded() const + { + return _is_loaded; + } + bool is_nonzero() const + { + assert(is_loaded(), "should be"); + return _is_nonzero; + } + bool is_two_word() const + { + assert(is_loaded(), "should be"); + return _is_two_word; + } + + public: + SharkValue* value(SharkBuilder* builder) + { + assert(is_loaded(), "should be"); + if (_value == NULL) { + _value = SharkValue::create_generic( + _type, builder->CreateInlineOop(_object), _is_nonzero); + } + return _value; + } +}; diff -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkInliner.cpp --- a/ports/hotspot/src/share/vm/shark/sharkInliner.cpp Wed Jun 03 11:15:36 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkInliner.cpp Thu Jun 04 09:47:24 2009 -0400 @@ -267,7 +267,7 @@ ResourceMark rm; initialize_for_check(); - SharkValue *sv; + SharkConstant *sc; bool a, b, c, d; iter()->reset_to_bci(0); @@ -323,11 +323,11 @@ case Bytecodes::_ldc: case Bytecodes::_ldc_w: case Bytecodes::_ldc2_w: - sv = SharkValue::from_ciConstant(iter()->get_constant()); - if (sv == NULL) + sc = SharkConstant::for_ldc(iter()); + if (!sc->is_loaded()) return false; - push(sv->zero_checked()); - if (sv->is_two_word()) + push(sc->is_nonzero()); + if (sc->is_two_word()) push(false); break; @@ -753,9 +753,9 @@ if (is_get) { bool result_pushed = false; if (field->is_constant()) { - SharkValue *value = SharkValue::from_ciConstant(field->constant_value()); - if (value != NULL) { - push(value->zero_checked()); + SharkConstant *sc = SharkConstant::for_field(iter()); + if (sc->is_loaded()) { + push(sc->is_nonzero()); result_pushed = true; } } diff -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Jun 03 11:15:36 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Thu Jun 04 09:47:24 2009 -0400 @@ -48,7 +48,7 @@ switch (bc()) { case Bytecodes::_ldc: case Bytecodes::_ldc_w: - if (iter()->is_unresolved_string() || iter()->is_unresolved_klass()) { + if (!SharkConstant::for_ldc(iter())->is_loaded()) { set_trap( Deoptimization::make_trap_request( Deoptimization::Reason_uninitialized, @@ -80,10 +80,9 @@ if (is_field) break; - // There won't be a pool access if this is a getstatic that - // resolves to a handled constant either + // There won't be a pool access if this is a constant getstatic if (bc() == Bytecodes::_getstatic && field->is_constant()) { - if (SharkValue::from_ciConstant(field->constant_value())) + if (SharkConstant::for_field(iter())->is_loaded()) break; } @@ -607,37 +606,6 @@ } builder()->CreateRetVoid(); -} - -Value *SharkTopLevelBlock::lookup_for_ldc() -{ - int index = iter()->get_constant_index(); - constantTag tag = target()->holder()->constant_pool_tag_at(index); - - SharkConstantPool constants(this); - Value *entry = constants.object_at(index); - - Value *klass_part; - switch (tag.value()) { - case JVM_CONSTANT_String: - return entry; - - case JVM_CONSTANT_Class: - klass_part = builder()->CreateAddressOfStructEntry( - entry, - in_ByteSize(klassOopDesc::klass_part_offset_in_bytes()), - SharkType::klass_type(), - "klass_part"); - // XXX FIXME: We need a memory barrier before this load - return builder()->CreateValueOfStructEntry( - klass_part, - in_ByteSize(Klass::java_mirror_offset_in_bytes()), - SharkType::oop_type(), - "java_mirror"); - - default: - ShouldNotReachHere(); - } } Value* SharkTopLevelBlock::lookup_for_field_access() diff -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Wed Jun 03 11:15:36 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Thu Jun 04 09:47:24 2009 -0400 @@ -222,7 +222,6 @@ // Helpers private: - llvm::Value* lookup_for_ldc(); llvm::Value* lookup_for_field_access(); void do_branch(int successor_index); diff -r 724f230eea38 ports/hotspot/src/share/vm/shark/sharkValue.hpp --- a/ports/hotspot/src/share/vm/shark/sharkValue.hpp Wed Jun 03 11:15:36 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkValue.hpp Thu Jun 04 09:47:24 2009 -0400 @@ -145,45 +145,6 @@ return create_jobject(LLVMValue::null(), false); } static inline SharkValue* address_constant(int bci); - - // Typed conversion from HotSpot ciConstants - public: - static SharkValue* from_ciConstant(ciConstant value) - { - switch (value.basic_type()) { - case T_BOOLEAN: - return SharkValue::jint_constant(value.as_boolean()); - - case T_BYTE: - return SharkValue::jint_constant(value.as_byte()); - - case T_CHAR: - return SharkValue::jint_constant(value.as_char()); - - case T_SHORT: - return SharkValue::jint_constant(value.as_short()); - - case T_INT: - return SharkValue::jint_constant(value.as_int()); - - case T_LONG: - return SharkValue::jlong_constant(value.as_long()); - - case T_FLOAT: - return SharkValue::jfloat_constant(value.as_float()); - - case T_DOUBLE: - return SharkValue::jdouble_constant(value.as_double()); - - case T_OBJECT: - case T_ARRAY: - return NULL; - - default: - tty->print_cr("Unhandled type %s", type2name(value.basic_type())); - ShouldNotReachHere(); - } - } // Type-losing conversions -- use with care! public: From gbenson at redhat.com Thu Jun 4 08:13:35 2009 From: gbenson at redhat.com (Gary Benson) Date: Thu, 4 Jun 2009 16:13:35 +0100 Subject: Shark getstatic and putstatic improvements Message-ID: <20090604151335.GD3156@redhat.com> Hi all, This commit replaced the interpreter-style constant pool lookup of the receiving class for getstatic and putstatic with inlined oops. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 89bd8e0f38c5 ChangeLog --- a/ChangeLog Thu Jun 04 09:48:19 2009 -0400 +++ b/ChangeLog Thu Jun 04 11:07:23 2009 -0400 @@ -1,3 +1,20 @@ +2009-06-04 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkBlock.hpp + (SharkBlock::lookup_for_field_access): Removed. + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::do_field_access): Inline receiver for static fields. + (SharkBlock::lookup_for_field_access): Removed. + + * ports/hotspot/src/share/vm/shark/sharkInliner.cpp + (SharkInlinerHelper::do_field_access): Allow static fields. + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkBlock::lookup_for_field_access): Removed. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::scan_for_traps): Removed static field traps. + (SharkBlock::lookup_for_field_access): Removed. + 2009-06-04 Gary Benson * ports/hotspot/src/share/vm/shark/sharkConstant.hpp: New file. diff -r 89bd8e0f38c5 ports/hotspot/src/share/vm/shark/sharkBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Thu Jun 04 09:48:19 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Thu Jun 04 11:07:23 2009 -0400 @@ -1002,7 +1002,7 @@ } if (!is_get || value == NULL) { if (!is_field) - object = lookup_for_field_access(); + object = builder()->CreateInlineOop(field->holder()); BasicType basic_type = field->type()->basic_type(); const Type *stack_type = SharkType::to_stackType(basic_type); @@ -1165,11 +1165,6 @@ ShouldNotCallThis(); } -Value* SharkBlock::lookup_for_field_access() -{ - ShouldNotCallThis(); -} - void SharkBlock::do_arraylength() { ShouldNotCallThis(); diff -r 89bd8e0f38c5 ports/hotspot/src/share/vm/shark/sharkBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Thu Jun 04 09:48:19 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Thu Jun 04 11:07:23 2009 -0400 @@ -202,7 +202,6 @@ // Helpers protected: virtual void do_zero_check(SharkValue* value); - virtual llvm::Value* lookup_for_field_access(); // Leaf calls protected: diff -r 89bd8e0f38c5 ports/hotspot/src/share/vm/shark/sharkInliner.cpp --- a/ports/hotspot/src/share/vm/shark/sharkInliner.cpp Thu Jun 04 09:48:19 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkInliner.cpp Thu Jun 04 11:07:23 2009 -0400 @@ -760,12 +760,8 @@ } } - if (!result_pushed) { - if (!is_field) - return false; - + if (!result_pushed) push(false); - } if (field->type()->is_two_word()) push(false); diff -r 89bd8e0f38c5 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Thu Jun 04 09:48:19 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Thu Jun 04 11:07:23 2009 -0400 @@ -74,20 +74,6 @@ Deoptimization::Action_none), bci()); return; } - - // If this is a getfield or putfield then there won't be a - // pool access and we're done - if (is_field) - break; - - // There won't be a pool access if this is a constant getstatic - if (bc() == Bytecodes::_getstatic && field->is_constant()) { - if (SharkConstant::for_field(iter())->is_loaded()) - break; - } - - // Continue to the check - index = iter()->get_field_index(); break; case Bytecodes::_invokevirtual: @@ -606,17 +592,6 @@ } builder()->CreateRetVoid(); -} - -Value* SharkTopLevelBlock::lookup_for_field_access() -{ - SharkConstantPool constants(this); - Value *cache = constants.cache_entry_at(iter()->get_field_index()); - - return builder()->CreateValueOfStructEntry( - cache, ConstantPoolCacheEntry::f1_offset(), - SharkType::jobject_type(), - "object"); } void SharkTopLevelBlock::do_arraylength() diff -r 89bd8e0f38c5 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Thu Jun 04 09:48:19 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Thu Jun 04 11:07:23 2009 -0400 @@ -220,9 +220,8 @@ public: void emit_IR(); - // Helpers + // Branch helpers private: - llvm::Value* lookup_for_field_access(); void do_branch(int successor_index); // Zero checks From gbenson at redhat.com Fri Jun 5 03:53:24 2009 From: gbenson at redhat.com (Gary Benson) Date: Fri, 5 Jun 2009 11:53:24 +0100 Subject: Shark new improvements Message-ID: <20090605105323.GA3171@redhat.com> Hi all, This commit replaces the interpreter-style constant pool lookup of class to be instantiated in the "new" bytecode with an inlined oop. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 2a14fec2301f -r 4dbf479c5609 ChangeLog --- a/ChangeLog Thu Jun 04 11:07:53 2009 -0400 +++ b/ChangeLog Fri Jun 05 06:47:14 2009 -0400 @@ -1,3 +1,9 @@ +2009-06-05 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::do_new): Removed constant pool lookup. + (SharkTopLevelBlock::scan_for_traps): Add traps for new. + 2009-06-04 Gary Benson * ports/hotspot/src/share/vm/shark/sharkBlock.hpp diff -r 2a14fec2301f -r 4dbf479c5609 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Thu Jun 04 11:07:53 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri Jun 05 06:47:14 2009 -0400 @@ -40,6 +40,7 @@ ciField *field; ciMethod *method; + ciInstanceKlass *klass; bool will_link; bool is_field; @@ -98,6 +99,30 @@ // Continue to the check index = iter()->get_method_index(); + break; + + case Bytecodes::_new: + klass = iter()->get_klass(will_link)->as_instance_klass(); + assert(will_link, "typeflow responsibility"); + + // Bail out if the class is unloaded + if (iter()->is_unresolved_klass() || !klass->is_initialized()) { + set_trap( + Deoptimization::make_trap_request( + Deoptimization::Reason_uninitialized, + Deoptimization::Action_reinterpret), bci()); + return; + } + + // Bail out if the class cannot be instantiated + if (klass->is_abstract() || klass->is_interface() || + klass->name() == ciSymbol::java_lang_Class()) { + set_trap( + Deoptimization::make_trap_request( + Deoptimization::Reason_unhandled, + Deoptimization::Action_reinterpret), bci()); + return; + } break; } @@ -1291,7 +1316,6 @@ ciInstanceKlass* klass = iter()->get_klass(will_link)->as_instance_klass(); assert(will_link, "typeflow responsibility"); - BasicBlock *tlab_alloc = NULL; BasicBlock *got_tlab = NULL; BasicBlock *heap_alloc = NULL; BasicBlock *retry = NULL; @@ -1310,33 +1334,22 @@ Value *slow_object = NULL; Value *object = NULL; - SharkConstantPool constants(this); - // The fast path if (!Klass::layout_helper_needs_slow_path(klass->layout_helper())) { if (UseTLAB) { - tlab_alloc = function()->CreateBlock("tlab_alloc"); got_tlab = function()->CreateBlock("got_tlab"); + heap_alloc = function()->CreateBlock("heap_alloc"); } - heap_alloc = function()->CreateBlock("heap_alloc"); retry = function()->CreateBlock("retry"); got_heap = function()->CreateBlock("got_heap"); initialize = function()->CreateBlock("initialize"); slow_alloc_and_init = function()->CreateBlock("slow_alloc_and_init"); push_object = function()->CreateBlock("push_object"); - builder()->CreateCondBr( - builder()->CreateICmpEQ( - constants.tag_at(iter()->get_klass_index()), - LLVMValue::jbyte_constant(JVM_CONSTANT_Class)), - UseTLAB ? tlab_alloc : heap_alloc, slow_alloc_and_init); - size_t size_in_bytes = klass->size_helper() << LogHeapWordSize; // Thread local allocation if (UseTLAB) { - builder()->SetInsertPoint(tlab_alloc); - Value *top_addr = builder()->CreateAddressOfStructEntry( thread(), Thread::tlab_top_offset(), PointerType::getUnqual(SharkType::intptr_type()), @@ -1361,11 +1374,11 @@ builder()->CreateStore(new_top, top_addr); builder()->CreateBr(initialize); + + builder()->SetInsertPoint(heap_alloc); } // Heap allocation - builder()->SetInsertPoint(heap_alloc); - Value *top_addr = builder()->CreateIntToPtr( builder()->pointer_constant(Universe::heap()->top_addr()), PointerType::getUnqual(SharkType::intptr_type()), @@ -1438,7 +1451,7 @@ builder()->CreateStore(LLVMValue::intptr_constant(mark), mark_addr); // Set the class - Value *rtklass = constants.object_at(iter()->get_klass_index()); + Value *rtklass = builder()->CreateInlineOop(klass); builder()->CreateStore(rtklass, klass_addr); got_fast = builder()->GetInsertBlock(); From gbenson at redhat.com Fri Jun 5 05:22:47 2009 From: gbenson at redhat.com (Gary Benson) Date: Fri, 5 Jun 2009 13:22:47 +0100 Subject: Shark checkcast and instanceof improvements (part 1) Message-ID: <20090605122247.GB3171@redhat.com> Hi all, This commit replaces the interpreter-style constant pool lookup of the class to be checked against in the instanceof and checkcast bytecodes with an inlined oop. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r a2125c262913 ChangeLog --- a/ChangeLog Fri Jun 05 12:12:47 2009 +0100 +++ b/ChangeLog Fri Jun 05 13:21:26 2009 +0100 @@ -1,3 +1,12 @@ +2009-06-05 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::do_full_instance_check): Add class argument. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::do_instance_check): Removed constant pool check. + (SharkTopLevelBlock::do_full_instance_check): Removed constant + pool lookup. + 2009-06-05 Gary Benson * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp diff -r a2125c262913 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri Jun 05 12:12:47 2009 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri Jun 05 13:21:26 2009 +0100 @@ -1166,23 +1166,17 @@ void SharkTopLevelBlock::do_instance_check() { - constantTag tag = - target()->holder()->constant_pool_tag_at(iter()->get_klass_index()); - if (!tag.is_klass()) { - assert(tag.is_unresolved_klass(), "should be"); + bool will_link; + ciKlass *klass = iter()->get_klass(will_link); + + if (will_link) + do_full_instance_check(klass); + else do_trapping_instance_check(); - } - else { - do_full_instance_check(); - } } -void SharkTopLevelBlock::do_full_instance_check() +void SharkTopLevelBlock::do_full_instance_check(ciKlass* klass) { - bool will_link; - ciKlass *klass = iter()->get_klass(will_link); - assert(will_link, "should do"); - BasicBlock *not_null = function()->CreateBlock("not_null"); BasicBlock *subtype_check = function()->CreateBlock("subtype_check"); BasicBlock *is_instance = function()->CreateBlock("is_instance"); @@ -1208,8 +1202,7 @@ // Get the class we're checking against builder()->SetInsertPoint(not_null); - SharkConstantPool constants(this); - Value *check_klass = constants.object_at(iter()->get_klass_index()); + Value *check_klass = builder()->CreateInlineOop(klass); // Get the class of the object being tested Value *object_klass = builder()->CreateValueOfStructEntry( diff -r a2125c262913 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Fri Jun 05 12:12:47 2009 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Fri Jun 05 13:21:26 2009 +0100 @@ -386,7 +386,7 @@ // checkcast and instanceof private: - void do_full_instance_check(); + void do_full_instance_check(ciKlass* klass); void do_trapping_instance_check(); void do_instance_check(); From gbenson at redhat.com Fri Jun 5 06:48:49 2009 From: gbenson at redhat.com (Gary Benson) Date: Fri, 5 Jun 2009 14:48:49 +0100 Subject: Shark checkcast and instanceof improvements (part 2) Message-ID: <20090605134849.GC3171@redhat.com> Hi all, This commit adds some compile-time type checking to the instanceof and checkcast bytecodes. It doesn't actually do anything at the moment because of the way Shark handles state (see PR IcedTea/346) but hopefully I can change that soon. Cheers, Gary -- http://gbenson.net/ From gbenson at redhat.com Fri Jun 5 11:15:35 2009 From: gbenson at redhat.com (Gary Benson) Date: Fri, 5 Jun 2009 19:15:35 +0100 Subject: Shark checkcast and instanceof improvements (part 3) Message-ID: <20090605181535.GA10309@redhat.com> Hi all, This commit adds special handling to instanceof instructions that are immediately followed by an ifeq or an ifne. The instructions are compiled as a pair, with the value checked by the instanceof annotated with updated type information in the branch of the if corresponding to the instanceof returning 1. This means that if the branch then contains a checkcast then that checkcast will be eliminated with a static check. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 8ba2783ba3b0 -r afa643fbffde ChangeLog --- a/ChangeLog Fri Jun 05 10:25:13 2009 -0400 +++ b/ChangeLog Fri Jun 05 19:11:26 2009 +0100 @@ -1,4 +1,33 @@ -2009-06-05 Omair Majid +2009-06-06 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkBlock.hpp + (SharkBlock::maybe_do_instanceof_if): New method. + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::maybe_do_instanceof_if): New method. + (SharkBlock::parse_bytecode): Use the above for + instanceof immediately followed by ifeq or ifne. + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::do_if_helper): New method. + (SharkTopLevelBlock::static_subtype_check): Likewise. + (SharkTopLevelBlock::maybe_do_instanceof_if): Likewise. + (SharkTopLevelBlock::do_optimized_instance_check): Removed. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::do_if_helper): New method. + (SharkTopLevelBlock::do_if): Use the above. + (SharkTopLevelBlock::static_subtype_check): New method. + (SharkTopLevelBlock::do_instance_check): Use the above. + (SharkTopLevelBlock::maybe_do_instanceof_if): New method. + (SharkTopLevelBlock::do_optimized_instance_check): Removed. + (SharkTopLevelBlock::do_full_instance_check): Removed + now-unnecessary state copy and merge. + + * ports/hotspot/src/share/vm/shark/sharkState.hpp + (SharkState::replace_all): New method. + * ports/hotspot/src/share/vm/shark/sharkState.cpp + (SharkState::replace_all): Likewise. + +2009-06-06 Omair Majid * patches/icedtea-webstart.patch: Make javax.jnlp package visible to javac. diff -r 8ba2783ba3b0 -r afa643fbffde ports/hotspot/src/share/vm/shark/sharkBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Fri Jun 05 10:25:13 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Fri Jun 05 19:11:26 2009 +0100 @@ -825,8 +825,38 @@ do_call(); break; + case Bytecodes::_instanceof: + // This is a very common construct: + // + // if (object instanceof Klass) { + // something = (Klass) object; + // ... + // } + // + // which gets compiled to something like this: + // + // 28: aload 9 + // 30: instanceof + // 33: ifeq 52 + // 36: aload 9 + // 38: checkcast + // + // Handling both bytecodes at once allows us + // to eliminate the checkcast. + if (iter()->next_bci() < limit && + (iter()->next_bc() == Bytecodes::_ifeq || + iter()->next_bc() == Bytecodes::_ifne) && + (!UseLoopSafepoints || + iter()->next_get_dest() > iter()->next_bci())) { + if (maybe_do_instanceof_if()) { + iter()->next(); + if (SharkTraceBytecodes) + tty->print_cr("%4d: %s", bci(), Bytecodes::name(bc())); + break; + } + } + // fall through case Bytecodes::_checkcast: - case Bytecodes::_instanceof: do_instance_check(); break; @@ -1225,6 +1255,11 @@ ShouldNotCallThis(); } +bool SharkBlock::maybe_do_instanceof_if() +{ + ShouldNotCallThis(); +} + void SharkBlock::do_new() { ShouldNotCallThis(); diff -r 8ba2783ba3b0 -r afa643fbffde ports/hotspot/src/share/vm/shark/sharkBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Fri Jun 05 10:25:13 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Fri Jun 05 19:11:26 2009 +0100 @@ -326,6 +326,7 @@ // checkcast and instanceof protected: virtual void do_instance_check(); + virtual bool maybe_do_instanceof_if(); // new and *newarray protected: diff -r 8ba2783ba3b0 -r afa643fbffde ports/hotspot/src/share/vm/shark/sharkState.cpp --- a/ports/hotspot/src/share/vm/shark/sharkState.cpp Fri Jun 05 10:25:13 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkState.cpp Fri Jun 05 19:11:26 2009 +0100 @@ -225,6 +225,21 @@ set_has_safepointed(this->has_safepointed() && other->has_safepointed()); } +void SharkState::replace_all(SharkValue* old_value, SharkValue* new_value) +{ + // Local variables + for (int i = 0; i < max_locals(); i++) { + if (local(i) == old_value) + set_local(i, new_value); + } + + // Expression stack + for (int i = 0; i < stack_depth(); i++) { + if (stack(i) == old_value) + set_stack(i, new_value); + } +} + void SharkState::decache_for_Java_call(ciMethod* callee) { assert(function() && method(), "you cannot decache here"); diff -r 8ba2783ba3b0 -r afa643fbffde ports/hotspot/src/share/vm/shark/sharkState.hpp --- a/ports/hotspot/src/share/vm/shark/sharkState.hpp Fri Jun 05 10:25:13 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkState.hpp Fri Jun 05 19:11:26 2009 +0100 @@ -187,6 +187,10 @@ llvm::BasicBlock* other_block, llvm::BasicBlock* this_block); + // Value replacement + public: + void replace_all(SharkValue* old_value, SharkValue* new_value); + // Cache and decache public: void decache_for_Java_call(ciMethod* callee); diff -r 8ba2783ba3b0 -r afa643fbffde ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri Jun 05 10:25:13 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri Jun 05 19:11:26 2009 +0100 @@ -772,8 +772,11 @@ } // All propagation of state from one block to the next (via -// dest->add_incoming) is handled by the next three methods -// (do_branch, do_if and do_switch) and by handle_exception. +// dest->add_incoming) is handled by these methods: +// do_branch +// do_if_helper +// do_switch +// handle_exception void SharkTopLevelBlock::do_branch(int successor_index) { @@ -795,16 +798,24 @@ llvm_a = a->jint_value(); llvm_b = b->jint_value(); } + do_if_helper(p, llvm_b, llvm_a, current_state(), current_state()); +} +void SharkTopLevelBlock::do_if_helper(ICmpInst::Predicate p, + Value* b, + Value* a, + SharkState* if_taken_state, + SharkState* not_taken_state) +{ SharkTopLevelBlock *if_taken = successor(ciTypeFlow::IF_TAKEN); SharkTopLevelBlock *not_taken = successor(ciTypeFlow::IF_NOT_TAKEN); builder()->CreateCondBr( - builder()->CreateICmp(p, llvm_a, llvm_b), + builder()->CreateICmp(p, a, b), if_taken->entry_block(), not_taken->entry_block()); - if_taken->add_incoming(current_state()); - not_taken->add_incoming(current_state()); + if_taken->add_incoming(if_taken_state); + not_taken->add_incoming(not_taken_state); } void SharkTopLevelBlock::do_switch() @@ -1164,40 +1175,48 @@ current_state()->set_has_safepointed(true); } +bool SharkTopLevelBlock::static_subtype_check(ciKlass* check_klass, + ciKlass* object_klass) +{ + // If the class we're checking against is java.lang.Object + // then this is a no brainer. Apparently this can happen + // in reflective code... + if (check_klass == function()->env()->Object_klass()) + return true; + + // Perform a subtype check. NB in opto's code for this + // (GraphKit::static_subtype_check) it says that static + // interface types cannot be trusted, and if opto can't + // trust them then I assume we can't either. + if (!object_klass->is_interface()) { + if (object_klass == check_klass) + return true; + + if (object_klass->is_loaded() && check_klass->is_loaded()) { + if (object_klass->is_subtype_of(check_klass)) + return true; + } + } + + return false; +} + void SharkTopLevelBlock::do_instance_check() { // Get the class we're checking against bool will_link; ciKlass *check_klass = iter()->get_klass(will_link); - // If the class we're checking against is java.lang.Object - // then this is a no brainer. Apparently this can happen - // in reflective code... - if (check_klass == function()->env()->Object_klass()) { - do_optimized_instance_check(); - return; - } - // Get the class of the object we're checking ciKlass *object_klass = xstack(0)->type()->as_klass(); - // If the classes are defined enough now then we - // don't need a runtime check. NB opto's code for - // this (GraphKit::static_subtype_check) says we - // cannot trust static interface types yet, hence - // the extra check - if (!object_klass->is_interface()) { - if (object_klass == check_klass) { - do_optimized_instance_check(); - return; + // Can we optimize this check away? + if (static_subtype_check(check_klass, object_klass)) { + if (bc() == Bytecodes::_instanceof) { + pop(); + push(SharkValue::jint_constant(1)); } - - if (object_klass->is_loaded() && check_klass->is_loaded()) { - if (object_klass->is_subtype_of(check_klass)) { - do_optimized_instance_check(); - return; - } - } + return; } // Need to check this one at runtime @@ -1207,14 +1226,69 @@ do_trapping_instance_check(check_klass); } -void SharkTopLevelBlock::do_optimized_instance_check() +bool SharkTopLevelBlock::maybe_do_instanceof_if() { - if (bc() == Bytecodes::_instanceof) { - pop(); - push(SharkValue::jint_constant(1)); + // Get the class we're checking against + bool will_link; + ciKlass *check_klass = iter()->get_klass(will_link); + + // If the class is unloaded then the instanceof + // cannot possibly succeed. + if (!will_link) + return false; + + // Keep a copy of the object we're checking + SharkValue *old_object = xstack(0); + + // Get the class of the object we're checking + ciKlass *object_klass = old_object->type()->as_klass(); + + // If the instanceof can be optimized away at compile time + // then any subsequent checkcasts will be too so we handle + // it normally. + if (static_subtype_check(check_klass, object_klass)) + return false; + + // Perform the instance check + do_full_instance_check(check_klass); + Value *result = pop()->jint_value(); + + // Create the casted object + SharkValue *new_object = SharkValue::create_generic( + check_klass, old_object->jobject_value(), old_object->zero_checked()); + + // Create two copies of the current state, one with the + // original object and one with all instances of the + // original object replaced with the new, casted object. + SharkState *new_state = current_state(); + SharkState *old_state = new_state->copy(); + new_state->replace_all(old_object, new_object); + + // Perform the check-and-branch + switch (iter()->next_bc()) { + case Bytecodes::_ifeq: + // branch if not an instance + do_if_helper( + ICmpInst::ICMP_EQ, + LLVMValue::jint_constant(0), result, + old_state, new_state); + break; + + case Bytecodes::_ifne: + // branch if an instance + do_if_helper( + ICmpInst::ICMP_NE, + LLVMValue::jint_constant(0), result, + new_state, old_state); + break; + + default: + ShouldNotReachHere(); } + + return true; } - + void SharkTopLevelBlock::do_full_instance_check(ciKlass* klass) { BasicBlock *not_null = function()->CreateBlock("not_null"); @@ -1238,7 +1312,6 @@ builder()->CreateICmpEQ(object, LLVMValue::null()), merge2, not_null); BasicBlock *null_block = builder()->GetInsertBlock(); - SharkState *null_state = current_state()->copy(); // Get the class we're checking against builder()->SetInsertPoint(not_null); @@ -1282,7 +1355,6 @@ // Second merge builder()->SetInsertPoint(merge2); - current_state()->merge(null_state, null_block, nonnull_block); PHINode *result = builder()->CreatePHI( SharkType::jint_type(), "result"); result->addIncoming(LLVMValue::jint_constant(IC_IS_NULL), null_block); diff -r 8ba2783ba3b0 -r afa643fbffde ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Fri Jun 05 10:25:13 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Fri Jun 05 19:11:26 2009 +0100 @@ -358,6 +358,11 @@ // if* private: + void do_if_helper(llvm::ICmpInst::Predicate p, + llvm::Value* b, + llvm::Value* a, + SharkState* if_taken_state, + SharkState* not_taken_state); void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a); // tableswitch and lookupswitch @@ -386,11 +391,12 @@ // checkcast and instanceof private: - void do_optimized_instance_check(); + bool static_subtype_check(ciKlass* check_klass, ciKlass* object_klass); void do_full_instance_check(ciKlass* klass); void do_trapping_instance_check(ciKlass* klass); void do_instance_check(); + bool maybe_do_instanceof_if(); // new and *newarray private: From gbenson at redhat.com Mon Jun 8 03:08:17 2009 From: gbenson at redhat.com (Gary Benson) Date: Mon, 8 Jun 2009 11:08:17 +0100 Subject: Shark invokeinterface improvements (part 1) Message-ID: <20090608100817.GA5081@redhat.com> Hi all, This commit removes a huge amount of code that handles an edge case for invokeinterface that only occurs with broken (IMO) but spec-compliant bytecode. I want to refactor invokeinterface and this code was making it a pain in the ass. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r a4f54a28260b ChangeLog --- a/ChangeLog Fri Jun 05 19:19:36 2009 +0100 +++ b/ChangeLog Mon Jun 08 11:04:42 2009 +0100 @@ -1,3 +1,14 @@ +2009-06-08 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::get_virtual_callee): Removed. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::scan_for_traps): Catch invokeinterface + edge case. + (SharkTopLevelBlock::get_interface_callee): Removed code to + handle invokeinterface edge case. + (SharkTopLevelBlock::get_virtual_callee): Removed. + 2009-06-06 Gary Benson * ports/hotspot/src/share/vm/shark/sharkBlock.hpp diff -r a4f54a28260b ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri Jun 05 19:19:36 2009 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Mon Jun 08 11:04:42 2009 +0100 @@ -97,6 +97,16 @@ method = iter()->get_method(will_link); assert(will_link, "typeflow responsibility"); + // Handle the case where we encounter an invokeinterface but + // should really have an invokevirtual since the resolved + // method is a virtual method in java.lang.Object. This is + // a legal corner case in the spec, and while javac does not + // generate this code there's no reason a compliant Java + // compiler should not. See cpCacheOop.cpp and + // interpreterRuntime.cpp for more details. + if (method->holder() == function()->env()->Object_klass()) + Unimplemented(); + // Continue to the check index = iter()->get_method_index(); break; @@ -900,107 +910,19 @@ "callee"); } -// Interpreter-style virtual call lookup -Value* SharkTopLevelBlock::get_virtual_callee(Value *cache, - SharkValue *receiver) -{ - BasicBlock *final = function()->CreateBlock("final"); - BasicBlock *not_final = function()->CreateBlock("not_final"); - BasicBlock *got_callee = function()->CreateBlock("got_callee"); - - Value *flags = builder()->CreateValueOfStructEntry( - cache, ConstantPoolCacheEntry::flags_offset(), - SharkType::intptr_type(), - "flags"); - - const int mask = 1 << ConstantPoolCacheEntry::vfinalMethod; - builder()->CreateCondBr( - builder()->CreateICmpNE( - builder()->CreateAnd(flags, LLVMValue::intptr_constant(mask)), - LLVMValue::intptr_constant(0)), - final, not_final); - - // For final methods f2 is the actual address of the method - builder()->SetInsertPoint(final); - Value *final_callee = builder()->CreateValueOfStructEntry( - cache, ConstantPoolCacheEntry::f2_offset(), - SharkType::methodOop_type(), - "final_callee"); - builder()->CreateBr(got_callee); - - // For non-final methods f2 is the index into the vtable - builder()->SetInsertPoint(not_final); - Value *klass = builder()->CreateValueOfStructEntry( - receiver->jobject_value(), - in_ByteSize(oopDesc::klass_offset_in_bytes()), - SharkType::jobject_type(), - "klass"); - - Value *index = builder()->CreateValueOfStructEntry( - cache, ConstantPoolCacheEntry::f2_offset(), - SharkType::intptr_type(), - "index"); - - Value *nonfinal_callee = builder()->CreateLoad( - builder()->CreateArrayAddress( - klass, - SharkType::methodOop_type(), - vtableEntry::size() * wordSize, - in_ByteSize(instanceKlass::vtable_start_offset() * wordSize), - index), - "nonfinal_callee"); - builder()->CreateBr(got_callee); - - builder()->SetInsertPoint(got_callee); - PHINode *callee = builder()->CreatePHI( - SharkType::methodOop_type(), "callee"); - callee->addIncoming(final_callee, final); - callee->addIncoming(nonfinal_callee, not_final); - - return callee; -} - -// Interpreter-style interface call lookup +// Interface calls are handled here Value* SharkTopLevelBlock::get_interface_callee(SharkValue *receiver) { SharkConstantPool constants(this); Value *cache = constants.cache_entry_at(iter()->get_method_index()); - BasicBlock *hacky = function()->CreateBlock("hacky"); - BasicBlock *normal = function()->CreateBlock("normal"); BasicBlock *loop = function()->CreateBlock("loop"); BasicBlock *got_null = function()->CreateBlock("got_null"); BasicBlock *not_null = function()->CreateBlock("not_null"); BasicBlock *next = function()->CreateBlock("next"); BasicBlock *got_entry = function()->CreateBlock("got_entry"); - BasicBlock *got_callee = function()->CreateBlock("got_callee"); - - Value *flags = builder()->CreateValueOfStructEntry( - cache, ConstantPoolCacheEntry::flags_offset(), - SharkType::intptr_type(), - "flags"); - - const int mask = 1 << ConstantPoolCacheEntry::methodInterface; - builder()->CreateCondBr( - builder()->CreateICmpNE( - builder()->CreateAnd(flags, LLVMValue::intptr_constant(mask)), - LLVMValue::intptr_constant(0)), - hacky, normal); - - // Workaround for the case where we encounter an invokeinterface, - // but should really have an invokevirtual since the resolved - // method is a virtual method in java.lang.Object. This is a - // corner case in the spec but is presumably legal, and while - // javac does not generate this code there's no reason it could - // not be produced by a compliant java compiler. See - // cpCacheOop.cpp for more details. - builder()->SetInsertPoint(hacky); - Value *hacky_callee = get_virtual_callee(cache, receiver); - BasicBlock *got_hacky = builder()->GetInsertBlock(); - builder()->CreateBr(got_callee); // Locate the receiver's itable - builder()->SetInsertPoint(normal); Value *object_klass = builder()->CreateValueOfStructEntry( receiver->jobject_value(), in_ByteSize(oopDesc::klass_offset_in_bytes()), SharkType::jobject_type(), @@ -1038,11 +960,12 @@ SharkType::jobject_type(), "iklass"); + BasicBlock *loop_entry = builder()->GetInsertBlock(); builder()->CreateBr(loop); builder()->SetInsertPoint(loop); PHINode *itable_entry_addr = builder()->CreatePHI( SharkType::intptr_type(), "itable_entry_addr"); - itable_entry_addr->addIncoming(itable_start, normal); + itable_entry_addr->addIncoming(itable_start, loop_entry); Value *itable_entry = builder()->CreateIntToPtr( itable_entry_addr, SharkType::itableOffsetEntry_type(), "itable_entry"); @@ -1091,7 +1014,7 @@ SharkType::intptr_type(), "index"); - Value *normal_callee = builder()->CreateLoad( + return builder()->CreateLoad( builder()->CreateIntToPtr( builder()->CreateAdd( builder()->CreateAdd( @@ -1106,17 +1029,7 @@ LLVMValue::intptr_constant( itableMethodEntry::method_offset_in_bytes())), PointerType::getUnqual(SharkType::methodOop_type())), - "normal_callee"); - BasicBlock *got_normal = builder()->GetInsertBlock(); - builder()->CreateBr(got_callee); - - builder()->SetInsertPoint(got_callee); - PHINode *callee = builder()->CreatePHI( - SharkType::methodOop_type(), "callee"); - callee->addIncoming(hacky_callee, got_hacky); - callee->addIncoming(normal_callee, got_normal); - - return callee; + "callee"); } void SharkTopLevelBlock::do_call() diff -r a4f54a28260b ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Fri Jun 05 19:19:36 2009 +0100 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Mon Jun 08 11:04:42 2009 +0100 @@ -383,8 +383,6 @@ llvm::Value* get_direct_callee(ciMethod* method); llvm::Value* get_virtual_callee(SharkValue* receiver, ciMethod* method); - - llvm::Value* get_virtual_callee(llvm::Value* cache, SharkValue* receiver); llvm::Value* get_interface_callee(SharkValue* receiver); void do_call(); From gbenson at redhat.com Tue Jun 9 04:09:11 2009 From: gbenson at redhat.com (Gary Benson) Date: Tue, 9 Jun 2009 12:09:11 +0100 Subject: Shark invokeinterface improvements (part 2) Message-ID: <20090609110911.GE3177@redhat.com> Hi all, This commit replaces the interpreter-style constant pool lookup of the method and itable index with compile time lookups. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 0be8e3334758 -r d55dfba8404f ChangeLog --- a/ChangeLog Mon Jun 08 14:26:32 2009 -0400 +++ b/ChangeLog Tue Jun 09 06:22:07 2009 -0400 @@ -1,3 +1,18 @@ +2009-06-09 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::get_interface_callee): New argument. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::scan_for_traps): Update traps for + invokeinterface. + (SharkTopLevelBlock::get_callee): Pass method to + get_interface_callee. + (SharkTopLevelBlock::get_interface_callee): Removed constant + pool lookup. + + * patches/hotspot/default/icedtea-shark.patch + (ciMethod::itable_index): New method. + 2009-06-08 Omair Majid * Makefile.am diff -r 0be8e3334758 -r d55dfba8404f ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Mon Jun 08 14:26:32 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Tue Jun 09 06:22:07 2009 -0400 @@ -107,8 +107,14 @@ if (method->holder() == function()->env()->Object_klass()) Unimplemented(); - // Continue to the check - index = iter()->get_method_index(); + // Bail out if the holder is unloaded + if (!method->holder()->is_linked()) { + set_trap( + Deoptimization::make_trap_request( + Deoptimization::Reason_uninitialized, + Deoptimization::Action_reinterpret), bci()); + return; + } break; case Bytecodes::_new: @@ -873,7 +879,7 @@ case CALL_VIRTUAL: return get_virtual_callee(receiver, method); case CALL_INTERFACE: - return get_interface_callee(receiver); + return get_interface_callee(receiver, method); default: ShouldNotReachHere(); } @@ -911,11 +917,9 @@ } // Interface calls are handled here -Value* SharkTopLevelBlock::get_interface_callee(SharkValue *receiver) +Value* SharkTopLevelBlock::get_interface_callee(SharkValue *receiver, + ciMethod* method) { - SharkConstantPool constants(this); - Value *cache = constants.cache_entry_at(iter()->get_method_index()); - BasicBlock *loop = function()->CreateBlock("loop"); BasicBlock *got_null = function()->CreateBlock("got_null"); BasicBlock *not_null = function()->CreateBlock("not_null"); @@ -955,11 +959,7 @@ itable_start, BytesPerLong, itable_start_name); // Locate this interface's entry in the table - Value *iklass = builder()->CreateValueOfStructEntry( - cache, ConstantPoolCacheEntry::f1_offset(), - SharkType::jobject_type(), - "iklass"); - + Value *iklass = builder()->CreateInlineOop(method->holder()); BasicBlock *loop_entry = builder()->GetInsertBlock(); builder()->CreateBr(loop); builder()->SetInsertPoint(loop); @@ -1009,11 +1009,6 @@ offset = builder()->CreateIntCast(offset, SharkType::intptr_type(), false); - Value *index = builder()->CreateValueOfStructEntry( - cache, ConstantPoolCacheEntry::f2_offset(), - SharkType::intptr_type(), - "index"); - return builder()->CreateLoad( builder()->CreateIntToPtr( builder()->CreateAdd( @@ -1022,10 +1017,8 @@ builder()->CreatePtrToInt( object_klass, SharkType::intptr_type()), offset), - builder()->CreateShl( - index, - LLVMValue::intptr_constant( - exact_log2(itableMethodEntry::size() * wordSize)))), + LLVMValue::intptr_constant( + method->itable_index() * itableMethodEntry::size() * wordSize)), LLVMValue::intptr_constant( itableMethodEntry::method_offset_in_bytes())), PointerType::getUnqual(SharkType::methodOop_type())), diff -r 0be8e3334758 -r d55dfba8404f ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Mon Jun 08 14:26:32 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Tue Jun 09 06:22:07 2009 -0400 @@ -383,7 +383,7 @@ llvm::Value* get_direct_callee(ciMethod* method); llvm::Value* get_virtual_callee(SharkValue* receiver, ciMethod* method); - llvm::Value* get_interface_callee(SharkValue* receiver); + llvm::Value* get_interface_callee(SharkValue* receiver, ciMethod* method); void do_call(); From gbenson at redhat.com Tue Jun 9 05:59:36 2009 From: gbenson at redhat.com (Gary Benson) Date: Tue, 9 Jun 2009 13:59:36 +0100 Subject: Shark clearout Message-ID: <20090609125936.GH3177@redhat.com> Hi all, My commits over the past week have replaced all constant pool accesses in Shark. This commit removes the constant pool access code itself, and some hacks that were required to support it. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r d55dfba8404f -r ff13b7d6e330 ChangeLog --- a/ChangeLog Tue Jun 09 06:22:07 2009 -0400 +++ b/ChangeLog Tue Jun 09 08:53:57 2009 -0400 @@ -1,3 +1,17 @@ +2009-06-09 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::scan_for_traps): Removed unused code. + + * ports/hotspot/src/share/vm/shark/sharkConstantPool.hpp: Removed. + * ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp: Likewise. + + * patches/hotspot/default/icedtea-shark.patch + (ciInstanceKlass::is_cache_entry_resolved): Removed. + (ciInstanceKlass::constant_pool_tag_at): Likewise. + + * ports/hotspot/src/share/vm/includeDB_shark: Updated. + 2009-06-09 Gary Benson * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp diff -r d55dfba8404f -r ff13b7d6e330 patches/hotspot/default/icedtea-shark.patch --- a/patches/hotspot/default/icedtea-shark.patch Tue Jun 09 06:22:07 2009 -0400 +++ b/patches/hotspot/default/icedtea-shark.patch Tue Jun 09 08:53:57 2009 -0400 @@ -337,46 +337,40 @@ } // ------------------------------------------------------------------ -diff -r 5297ff20101d openjdk-ecj/hotspot/src/share/vm/ci/ciInstanceKlass.cpp ---- openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Mon Dec 15 15:32:37 2008 +0000 -+++ openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Tue Apr 21 09:47:27 2009 +0100 -@@ -548,3 +548,23 @@ - } - return impl; +diff -r 12c97e7e55eb -r e6fef2ef2fea openjdk/hotspot/src/share/vm/ci/ciMethod.cpp +--- openjdk/hotspot/src/share/vm/ci/ciMethod.cpp Tue Jun 09 09:17:11 2009 +0100 ++++ openjdk/hotspot/src/share/vm/ci/ciMethod.cpp Tue Jun 09 10:04:02 2009 +0100 +@@ -229,6 +229,20 @@ } -+ + + +#ifdef SHARK +// ------------------------------------------------------------------ -+// ciInstanceKlass::constant_pool_tag_at ++// ciMethod::itable_index +// -+// What is in this constant pool slot? -+constantTag ciInstanceKlass::constant_pool_tag_at(int index) { ++// Get the position of this method's entry in the itable, if any. ++int ciMethod::itable_index() { ++ check_is_loaded(); ++ assert(holder()->is_linked(), "must be linked"); + VM_ENTRY_MARK; -+ return get_instanceKlass()->constants()->tag_at(index); -+} -+ -+// ------------------------------------------------------------------ -+// ciInstanceKlass::is_cache_entry_resolved -+// -+// Is this entry in the constant pool cache resolved? -+bool ciInstanceKlass::is_cache_entry_resolved(int index, Bytecodes::Code opcode) { -+ VM_ENTRY_MARK; -+ return get_instanceKlass()->constants()->cache()->entry_at(index)->is_resolved(opcode); ++ return klassItable::compute_itable_index(get_methodOop()); +} +#endif // SHARK -diff -r 5297ff20101d openjdk-ecj/hotspot/src/share/vm/ci/ciInstanceKlass.hpp ---- openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Mon Dec 15 15:32:37 2008 +0000 -+++ openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Tue Apr 21 09:47:27 2009 +0100 -@@ -198,4 +198,12 @@ - // What kind of ciObject is this? - bool is_instance_klass() { return true; } - bool is_java_klass() { return true; } + ++ + // ------------------------------------------------------------------ + // ciMethod::native_entry + // +diff -r 12c97e7e55eb -r e6fef2ef2fea openjdk/hotspot/src/share/vm/ci/ciMethod.hpp +--- openjdk/hotspot/src/share/vm/ci/ciMethod.hpp Tue Jun 09 09:17:11 2009 +0100 ++++ openjdk/hotspot/src/share/vm/ci/ciMethod.hpp Tue Jun 09 10:04:02 2009 +0100 +@@ -139,6 +139,9 @@ + + // Runtime information. + int vtable_index(); +#ifdef SHARK -+ // What is in this constant pool slot? -+ constantTag constant_pool_tag_at(int index); -+ -+ // Is this entry in the constant pool cache resolved? -+ bool is_cache_entry_resolved(int index, Bytecodes::Code opcode); ++ int itable_index(); +#endif // SHARK - }; + address native_entry(); + address interpreter_entry(); + diff -r d55dfba8404f -r ff13b7d6e330 ports/hotspot/src/share/vm/includeDB_shark --- a/ports/hotspot/src/share/vm/includeDB_shark Tue Jun 09 06:22:07 2009 -0400 +++ b/ports/hotspot/src/share/vm/includeDB_shark Tue Jun 09 08:53:57 2009 -0400 @@ -170,24 +170,6 @@ sharkConstant.hpp sharkBuilder.hpp sharkConstant.hpp sharkValue.hpp -sharkConstantPool.cpp allocation.hpp -sharkConstantPool.cpp constantPoolOop.hpp -sharkConstantPool.cpp cpCacheOop.hpp -sharkConstantPool.cpp debug.hpp -sharkConstantPool.cpp llvmHeaders.hpp -sharkConstantPool.cpp llvmValue.hpp -sharkConstantPool.cpp methodOop.hpp -sharkConstantPool.cpp sharkBuilder.hpp -sharkConstantPool.cpp sharkConstantPool.hpp -sharkConstantPool.cpp sharkState.inline.hpp -sharkConstantPool.cpp sharkType.hpp -sharkConstantPool.cpp sharkValue.hpp - -sharkConstantPool.hpp allocation.hpp -sharkConstantPool.hpp llvmHeaders.hpp -sharkConstantPool.hpp sharkBuilder.hpp -sharkConstantPool.hpp sharkTopLevelBlock.hpp - sharkEntry.cpp sharkEntry.hpp sharkEntry.hpp llvmHeaders.hpp @@ -316,7 +298,6 @@ sharkTopLevelBlock.cpp sharkTopLevelBlock.hpp sharkTopLevelBlock.cpp sharkBuilder.hpp sharkTopLevelBlock.cpp sharkConstant.hpp -sharkTopLevelBlock.cpp sharkConstantPool.hpp sharkTopLevelBlock.cpp sharkInliner.hpp sharkTopLevelBlock.cpp sharkRuntime.hpp sharkTopLevelBlock.cpp sharkState.inline.hpp diff -r d55dfba8404f -r ff13b7d6e330 ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp --- a/ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp Tue Jun 09 06:22:07 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -/* - * 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/_sharkConstantPool.cpp.incl" - -using namespace llvm; - -Value *SharkConstantPool::constants() -{ - Value *m = method(); - if (m != _constants_method) { - _constants = builder()->CreateValueOfStructEntry( - m, methodOopDesc::constants_offset(), - SharkType::oop_type(), "constants"); - _constants_method = m; - } - return _constants; -} - -Value *SharkConstantPool::tags() -{ - Value *cp = constants(); - if (cp != _tags_constants) { - _tags = builder()->CreateValueOfStructEntry( - cp, in_ByteSize(constantPoolOopDesc::tags_offset_in_bytes()), - SharkType::oop_type(), "tags"); - _tags_constants = cp; - } - return _tags; -} - -Value *SharkConstantPool::cache() -{ - Value *cp = constants(); - if (cp != _cache_constants) { - _cache = builder()->CreateValueOfStructEntry( - cp, in_ByteSize(constantPoolOopDesc::cache_offset_in_bytes()), - SharkType::oop_type(), "cache"); - _cache_constants = cp; - } - return _cache; -} - -Value *SharkConstantPool::object_at(int which) -{ - return builder()->CreateLoad( - builder()->CreateArrayAddress( - constants(), - T_OBJECT, in_ByteSize(sizeof(constantPoolOopDesc)), - LLVMValue::jint_constant(which))); -} - -Value *SharkConstantPool::tag_at(int which) -{ - return builder()->CreateLoad( - builder()->CreateArrayAddress( - tags(), T_BYTE, LLVMValue::jint_constant(which))); -} - -Value *SharkConstantPool::cache_entry_at(int which) -{ - // Takes a constant pool cache index in byte-swapped byte order - // (which comes from the bytecodes after rewriting). This is a - // bizarre hack but it's the same as - // constantPoolOopDesc::field_or_method_at(). - which = Bytes::swap_u2(which); - assert(target()->holder()->is_cache_entry_resolved(which, block()->bc()), - "should be"); - - return builder()->CreateIntToPtr( - builder()->CreateAdd( - builder()->CreatePtrToInt( - cache(), SharkType::intptr_type()), - LLVMValue::intptr_constant( - in_bytes(constantPoolCacheOopDesc::base_offset()) + - which * sizeof(ConstantPoolCacheEntry))), - SharkType::cpCacheEntry_type()); -} - -Value *SharkConstantPool::java_mirror() -{ - Value *cp = constants(); - - Value *pool_holder = builder()->CreateValueOfStructEntry( - cp, - in_ByteSize(constantPoolOopDesc::pool_holder_offset_in_bytes()), - SharkType::oop_type(), - "pool_holder"); - - Value *klass_part = builder()->CreateAddressOfStructEntry( - pool_holder, - in_ByteSize(klassOopDesc::klass_part_offset_in_bytes()), - SharkType::klass_type(), - "klass_part"); - - // XXX should there be a memory barrier before this load? - return builder()->CreateValueOfStructEntry( - klass_part, - in_ByteSize(Klass::java_mirror_offset_in_bytes()), - SharkType::oop_type(), - "java_mirror"); -} diff -r d55dfba8404f -r ff13b7d6e330 ports/hotspot/src/share/vm/shark/sharkConstantPool.hpp --- a/ports/hotspot/src/share/vm/shark/sharkConstantPool.hpp Tue Jun 09 06:22:07 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * 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 SharkConstantPool : public StackObj { - public: - SharkConstantPool(SharkTopLevelBlock* block) - : _block(block), - _constants_method(NULL), - _tags_constants(NULL), - _cache_constants(NULL) {} - - private: - SharkTopLevelBlock* _block; - - private: - SharkTopLevelBlock* block() const - { - return _block; - } - SharkBuilder* builder() const - { - return block()->builder(); - } - ciMethod* target() const - { - return block()->target(); - } - llvm::Value* method() const - { - return block()->method(); - } - - private: - llvm::Value* _constants; // The constant pool, a constantPoolOop - llvm::Value* _constants_method; // The method _constants was loaded from - - llvm::Value* _tags; // The tags array, a typeArrayOop - llvm::Value* _tags_constants; // The constantPoolOop _tags is in - - llvm::Value* _cache; // The cache, a constantPoolCacheOop - llvm::Value* _cache_constants; // The constantPoolCacheOop _cache is in - - private: - llvm::Value* constants(); - llvm::Value* tags(); - llvm::Value* cache(); - - public: - llvm::Value* object_at(int which); - llvm::Value* tag_at(int which); - llvm::Value* cache_entry_at(int which); - llvm::Value* java_mirror(); -}; diff -r d55dfba8404f -r ff13b7d6e330 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Tue Jun 09 06:22:07 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Tue Jun 09 08:53:57 2009 -0400 @@ -43,8 +43,6 @@ ciInstanceKlass *klass; bool will_link; bool is_field; - - int index = -1; switch (bc()) { case Bytecodes::_ldc: @@ -140,18 +138,6 @@ return; } break; - } - - // If we found a constant pool access on this bytecode then check it - if (index != -1) { - if (!target()->holder()->is_cache_entry_resolved( - Bytes::swap_u2(index), bc())) { - set_trap( - Deoptimization::make_trap_request( - Deoptimization::Reason_uninitialized, - Deoptimization::Action_reinterpret), bci()); - return; - } } } From gbenson at redhat.com Wed Jun 10 05:30:47 2009 From: gbenson at redhat.com (Gary Benson) Date: Wed, 10 Jun 2009 13:30:47 +0100 Subject: Shark invoke* improvements Message-ID: <20090610123047.GA26952@redhat.com> Hi all, The work I've done over the past week has made the callee-fetching part of Shark's invoke* bytecodes a lot less like the interpreter's and a lot more like the Server compiler's. This has allowed me to drop in a block of code from Server that uses class heirachy analysis to convert virtual calls to direct ones. Now, the difference here is fairly small (callee-fetching is just two loads for a virtual call against one for a direct) but direct calls can be inlined -- and an inlined call is a vast performance boost on Shark where calls are expensive. I ran SPECjvm98 on this one. Most of the benchmarks improved slightly, except the mtrt one which improved by 120%! Turns out it has an awful lot of inlinable virtual calls :) Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 188882817ac2 -r ce70ed27635c ChangeLog --- a/ChangeLog Wed Jun 10 14:13:59 2009 +0200 +++ b/ChangeLog Wed Jun 10 13:22:21 2009 +0100 @@ -1,3 +1,19 @@ +2009-06-10 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::CallType): Removed. + (SharkTopLevelBlock::get_call_type): Likewise. + (SharkTopLevelBlock::get_callee): Likewise. + (SharkTopLevelBlock::improve_virtual_call): New method. + (SharkTopLevelBlock::get_virtual_callee): Updated. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::scan_for_traps): Updated call traps. + (SharkTopLevelBlock::get_call_type): Removed. + (SharkTopLevelBlock::get_callee): Likewise. + (SharkTopLevelBlock::improve_virtual_call): New method. + (SharkTopLevelBlock::get_virtual_callee): Updated. + (SharkTopLevelBlock::do_call): Replaced callee selection. + 2009-06-10 Xerxes R?nby PR icedtea/323 diff -r 188882817ac2 -r ce70ed27635c ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Jun 10 14:13:59 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Jun 10 13:22:21 2009 +0100 @@ -75,37 +75,13 @@ } break; + case Bytecodes::_invokestatic: + case Bytecodes::_invokespecial: case Bytecodes::_invokevirtual: - method = iter()->get_method(will_link); - assert(will_link, "typeflow responsibility"); - - // If this is a non-final invokevirtual then we need to - // check that its holder is linked, because its vtable - // won't have been set up otherwise. - if (!method->is_final_method() && !method->holder()->is_linked()) { - set_trap( - Deoptimization::make_trap_request( - Deoptimization::Reason_uninitialized, - Deoptimization::Action_reinterpret), bci()); - return; - } - break; - case Bytecodes::_invokeinterface: method = iter()->get_method(will_link); assert(will_link, "typeflow responsibility"); - // Handle the case where we encounter an invokeinterface but - // should really have an invokevirtual since the resolved - // method is a virtual method in java.lang.Object. This is - // a legal corner case in the spec, and while javac does not - // generate this code there's no reason a compliant Java - // compiler should not. See cpCacheOop.cpp and - // interpreterRuntime.cpp for more details. - if (method->holder() == function()->env()->Object_klass()) - Unimplemented(); - - // Bail out if the holder is unloaded if (!method->holder()->is_linked()) { set_trap( Deoptimization::make_trap_request( @@ -841,39 +817,78 @@ } } -// Figure out what type of call this is. -// - Direct calls are where the callee is fixed. -// - Interface and Virtual calls require lookup at runtime. -// NB some invokevirtuals can be resolved to direct calls. -SharkTopLevelBlock::CallType SharkTopLevelBlock::get_call_type(ciMethod* method) +ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller, + ciInstanceKlass* klass, + ciMethod* dest_method, + ciType* receiver_type) { - if (bc() == Bytecodes::_invokeinterface) - return CALL_INTERFACE; - else if (bc() == Bytecodes::_invokevirtual && !method->is_final_method()) - return CALL_VIRTUAL; - else - return CALL_DIRECT; + // If the method is obviously final then we are already done + if (dest_method->can_be_statically_bound()) + return dest_method; + + // Array methods are all inherited from Object and are monomorphic + if (receiver_type->is_array_klass() && + dest_method->holder() == function()->env()->Object_klass()) + return dest_method; + + // All other interesting cases are instance classes + if (!receiver_type->is_instance_klass()) + return NULL; + + // Attempt to improve the receiver + ciInstanceKlass* actual_receiver = klass; + ciInstanceKlass *improved_receiver = receiver_type->as_instance_klass(); + if (improved_receiver->is_loaded() && + improved_receiver->is_initialized() && + !improved_receiver->is_interface() && + improved_receiver->is_subtype_of(actual_receiver)) { + actual_receiver = improved_receiver; + } + + // Attempt to find a monomorphic target for this call using + // class heirachy analysis. + ciInstanceKlass *calling_klass = caller->holder(); + ciMethod* monomorphic_target = + dest_method->find_monomorphic_target(calling_klass, klass, actual_receiver); + if (monomorphic_target != NULL) { + assert(!monomorphic_target->is_abstract(), "shouldn't be"); + + // Opto has a bunch of type checking here that I don't + // understand. It's to inhibit casting in one direction, + // possibly because objects in Opto can have inexact + // types, but I can't even tell which direction it + // doesn't like. For now I'm going to block *any* cast. + if (monomorphic_target != dest_method) { +#ifndef PRODUCT + tty->print_cr("found monomorphic target, but inhibited cast:"); + tty->print(" dest_method = "); + dest_method->print_short_name(tty); + tty->cr(); + tty->print(" monomorphic_target = "); + monomorphic_target->print_short_name(tty); + tty->cr(); +#endif // !PRODUCT + monomorphic_target = NULL; + } + } + + // Replace the virtual call with a direct one. This makes + // us dependent on that target method not getting overridden + // by dynamic class loading. + if (monomorphic_target != NULL) { + function()->env()->dependencies()->assert_unique_concrete_method( + actual_receiver, monomorphic_target); + return monomorphic_target; + } + + // Because Opto distinguishes exact types from inexact ones + // it can perform a further optimization to replace calls + // with non-monomorphic targets if the receiver has an exact + // type. We don't mark types this way, so we can't do this. + + return NULL; } -Value *SharkTopLevelBlock::get_callee(CallType call_type, - ciMethod* method, - SharkValue* receiver) -{ - switch (call_type) { - case CALL_DIRECT: - return get_direct_callee(method); - case CALL_VIRTUAL: - return get_virtual_callee(receiver, method); - case CALL_INTERFACE: - return get_interface_callee(receiver, method); - default: - ShouldNotReachHere(); - } -} - -// Direct calls can be made when the callee is fixed. -// invokestatic and invokespecial are always direct; -// invokevirtual is direct in some circumstances. Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method) { return builder()->CreateBitCast( @@ -882,9 +897,8 @@ "callee"); } -// Non-direct virtual calls are handled here Value *SharkTopLevelBlock::get_virtual_callee(SharkValue* receiver, - ciMethod* method) + int vtable_index) { Value *klass = builder()->CreateValueOfStructEntry( receiver->jobject_value(), @@ -898,11 +912,10 @@ SharkType::methodOop_type(), vtableEntry::size() * wordSize, in_ByteSize(instanceKlass::vtable_start_offset() * wordSize), - LLVMValue::intptr_constant(method->vtable_index())), + LLVMValue::intptr_constant(vtable_index)), "callee"); } -// Interface calls are handled here Value* SharkTopLevelBlock::get_interface_callee(SharkValue *receiver, ciMethod* method) { @@ -1013,31 +1026,78 @@ void SharkTopLevelBlock::do_call() { + // Set frequently used booleans + bool is_static = bc() == Bytecodes::_invokestatic; + bool is_virtual = bc() == Bytecodes::_invokevirtual; + bool is_interface = bc() == Bytecodes::_invokeinterface; + + // Find the method being called bool will_link; - ciMethod *method = iter()->get_method(will_link); + ciMethod *dest_method = iter()->get_method(will_link); assert(will_link, "typeflow responsibility"); + assert(dest_method->is_static() == is_static, "must match bc"); - // Figure out what type of call this is - CallType call_type = get_call_type(method); + // Find the class of the method being called. Note + // that the superclass check in the second assertion + // is to cope with a hole in the spec that allows for + // invokeinterface instructions where the resolved + // method is a virtual method in java.lang.Object. + // javac doesn't generate code like that, but there's + // no reason a compliant Java compiler might not. + ciInstanceKlass *holder_klass = dest_method->holder(); + assert(holder_klass->is_loaded(), "scan_for_traps responsibility"); + assert(holder_klass->is_interface() || + holder_klass->super() == NULL || + !is_interface, "must match bc"); + ciKlass *holder = iter()->get_declared_method_holder(); + ciInstanceKlass *klass = + ciEnv::get_instance_klass_for_declared_method_holder(holder); // 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 // check itself. SharkValue *receiver = NULL; - if (bc() != Bytecodes::_invokestatic) { - receiver = xstack(method->arg_size() - 1); + if (!is_static) { + receiver = xstack(dest_method->arg_size() - 1); check_null(receiver); } + // Try to improve non-direct calls + bool call_is_virtual = is_virtual || is_interface; + ciMethod *call_method = dest_method; + if (call_is_virtual) { + ciMethod *optimized_method = improve_virtual_call( + target(), klass, dest_method, receiver->type()); + if (optimized_method) { + call_method = optimized_method; + call_is_virtual = false; + } + } + // Try to inline the call - if (call_type == CALL_DIRECT) { - if (SharkInliner::attempt_inline(method, current_state(), thread())) + if (!call_is_virtual) { + if (SharkInliner::attempt_inline(call_method, current_state(), thread())) return; } // Find the method we are calling - Value *callee = get_callee(call_type, method, receiver); + Value *callee; + if (call_is_virtual) { + if (is_virtual) { + int vtable_index = call_method->resolve_vtable_index( + target()->holder(), klass); + assert(vtable_index >= 0, "should be"); + callee = get_virtual_callee(receiver, vtable_index); + } + else { + assert(is_interface, "should be"); + callee = get_interface_callee(receiver, call_method); + } + } + else { + callee = get_direct_callee(call_method); + } // Load the SharkEntry from the callee Value *base_pc = builder()->CreateValueOfStructEntry( @@ -1056,9 +1116,9 @@ "entry_point"); // Make the call - current_state()->decache_for_Java_call(method); + current_state()->decache_for_Java_call(call_method); builder()->CreateCall3(entry_point, callee, base_pc, thread()); - current_state()->cache_after_Java_call(method); + current_state()->cache_after_Java_call(call_method); // Check for pending exceptions check_pending_exception(EX_CHECK_FULL); diff -r 188882817ac2 -r ce70ed27635c ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Wed Jun 10 14:13:59 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Wed Jun 10 13:22:21 2009 +0100 @@ -371,18 +371,12 @@ // invoke* private: - enum CallType { - CALL_DIRECT, - CALL_VIRTUAL, - CALL_INTERFACE - }; - CallType get_call_type(ciMethod* method); - llvm::Value* get_callee(CallType call_type, - ciMethod* method, - SharkValue* receiver); - + ciMethod* improve_virtual_call(ciMethod* caller, + ciInstanceKlass* klass, + ciMethod* dest_method, + ciType* receiver_type); llvm::Value* get_direct_callee(ciMethod* method); - llvm::Value* get_virtual_callee(SharkValue* receiver, ciMethod* method); + llvm::Value* get_virtual_callee(SharkValue* receiver, int vtable_index); llvm::Value* get_interface_callee(SharkValue* receiver, ciMethod* method); void do_call(); From xerxes at zafena.se Wed Jun 10 06:16:27 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Wed, 10 Jun 2009 15:16:27 +0200 Subject: [Fwd: Re: RFC: [patch] Zero/Shark -Xcheck:jni fix for pr 323] Message-ID: <4A2FB22B.5020502@zafena.se> Committed: http://icedtea.classpath.org/hg/icedtea6?cmd=changeset;node=188882817ac2 -------------- next part -------------- An embedded message was scrubbed... From: =?ISO-8859-1?Q?Xerxes_R=E5nby?= Subject: Re: RFC: [patch] Zero/Shark -Xcheck:jni fix for pr 323 Date: Wed, 10 Jun 2009 15:10:13 +0200 Size: 3678 Url: http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20090610/096ad9bc/attachment.eml From xerxes at zafena.se Tue Jun 16 06:13:38 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Tue, 16 Jun 2009 15:13:38 +0200 Subject: [patch] RFC: shark llvm 2.6svn r73431 api breakage fix Message-ID: <4A379A82.9060902@zafena.se> http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-June/023073.html Add Sub Mul Neg have been split into FAdd FSub FMul FNeg for improved integer / floatingpoint operation llvm_api_breakage.patch improves floatingpoint performance by taking advandtage of this change. The llvm 2.6svn tip have improved support for vector types since r73431 and some api's have changed to return Constant* instead of ConstantFP* llvm_api_breakage_2.patch fixes this issue. Cheers Xerxes -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm_api_breakage.patch Type: text/x-patch Size: 2850 bytes Desc: not available Url : http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20090616/d9beef0c/attachment.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm_api_breakage_2.patch Type: text/x-patch Size: 917 bytes Desc: not available Url : http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20090616/d9beef0c/attachment-0001.bin From xerxes at zafena.se Tue Jun 16 07:17:50 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Tue, 16 Jun 2009 16:17:50 +0200 Subject: [patch] RFC: shark llvm 2.6svn r73431 api breakage fix - changelog entry In-Reply-To: <4A379A82.9060902@zafena.se> References: <4A379A82.9060902@zafena.se> Message-ID: <4A37A98E.2020500@zafena.se> Suggested changelog entry: 2009-06-16 Xerxes R?nby * ports/hotspot/src/share/vm/shark/llvmValue.hpp (jfloat_constant): Return llvm::Constant* when llvm version are 2.6 or later to handle llvm r73431 API change. (jdouble_constant): Likewise. * ports/hotspot/src/share/vm/shark/sharkBlock.cpp (SharkBlock::parse_bytecode): Updated to use CreateFAdd CreateFSub, CreateFMul and CreateFNeg for jfloat and jdouble when llvm version are 2.6 or later. Xerxes R?nby skrev: > http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-June/023073.html > Add Sub Mul Neg have been split into FAdd FSub FMul FNeg for improved > integer / floatingpoint operation > llvm_api_breakage.patch > improves floatingpoint performance by taking advandtage of this change. > > The llvm 2.6svn tip have improved support for vector types since > r73431 and some api's have changed to return Constant* instead of > ConstantFP* > llvm_api_breakage_2.patch > fixes this issue. > > Cheers > Xerxes From xerxes at zafena.se Tue Jun 16 11:02:21 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Tue, 16 Jun 2009 20:02:21 +0200 Subject: [patch] RFC: shark llvm 2.6svn r73431 api breakage fix In-Reply-To: <4A379A82.9060902@zafena.se> References: <4A379A82.9060902@zafena.se> Message-ID: <4A37DE2D.3050808@zafena.se> Den 2009-06-16 15:13, Xerxes R?nby skrev: > +#ifdef SHARK_LLVM_VERSION>= 26 > note to self: change this to +#if SHARK_LLVM_VERSION >= 26 in llvm_api_breakage_2.patch From gbenson at redhat.com Wed Jun 17 06:42:02 2009 From: gbenson at redhat.com (Gary Benson) Date: Wed, 17 Jun 2009 14:42:02 +0100 Subject: Temporarily remove frame cache from Shark Message-ID: <20090617134201.GA3221@redhat.com> Hi all, This commit removes the frame cache from Shark. I'm working on a big refactor that'll make Shark a lot cleaner and easier to hack on, and will open the door to some new optimizations. The frame cache is totally in the way of this, so I thought I'd blow it away temporarily. Shark will be slightly slower for a while. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r e6350d5249d3 -r 4a617634d81c ChangeLog --- a/ChangeLog Tue Jun 16 10:58:00 2009 -0400 +++ b/ChangeLog Wed Jun 17 14:37:31 2009 +0100 @@ -1,3 +1,41 @@ +2009-06-17 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp + (SharkCacherDecacher::SharkCacherDecacher): Remove frame cache code. + (SharkCacherDecacher::_frame_cache): Removed. + (SharkCacherDecacher::frame_cache): Likewise. + (SharkDecacher::SharkDecacher): Removed frame cache code. + (SharkJavaCallDecacher::SharkJavaCallDecacher): Likewise. + (SharkVMCallDecacher::SharkVMCallDecacher): Likewise. + (SharkTrapDecacher::SharkTrapDecacher): Likewise. + (SharkCacher::SharkCacher): Likewise. + (SharkJavaCallCacher::SharkJavaCallCcacher): Likewise. + (SharkVMCallCacher::SharkVMCallCacher): Likewise. + (SharkFunctionEntryCacher::SharkFunctionEntryCacher): Likewise. + * ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp + (SharkDecacher::write_value_to_frame): Remove frame cache code. + (SharkDecacher::read_value_from_frame): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkState.hpp + (SharkState::_frame_cache): Removed. + (SharkState::frame_cache): Likewise. + * ports/hotspot/src/share/vm/shark/sharkState.cpp + (SharkState::SharkState): Remove frame cache code. + (SharkState::initialize): Likewise. + (SharkState::equal_to): Likewise. + (SharkState::merge): Likewise. + (SharkState::decache_for_Java_call): Likewise. + (SharkState::cache_after_Java_call): Likewise. + (SharkState::decache_for_VM_call): Likewise. + (SharkState::cache_after_VM_call): Likewise. + (SharkState::decache_for_trap): Likewise. + (SharkEntryState::SharkEntryState): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkFrameCache.hpp: Removed. + * ports/hotspot/src/share/vm/shark/sharkFrameCache.cpp: Likewise. + + * ports/hotspot/src/share/vm/includeDB_shark: Updated. + 2009-06-16 Omair Majid * rt/javax/jnlp/SingleInstanceListener.java: New file. diff -r e6350d5249d3 -r 4a617634d81c ports/hotspot/src/share/vm/includeDB_shark --- a/ports/hotspot/src/share/vm/includeDB_shark Tue Jun 16 10:58:00 2009 -0400 +++ b/ports/hotspot/src/share/vm/includeDB_shark Wed Jun 17 14:37:31 2009 +0100 @@ -120,14 +120,12 @@ sharkCacheDecache.cpp llvmValue.hpp sharkCacheDecache.cpp sharkBuilder.hpp sharkCacheDecache.cpp sharkCacheDecache.hpp -sharkCacheDecache.cpp sharkFrameCache.hpp sharkCacheDecache.cpp sharkFunction.hpp sharkCacheDecache.cpp sharkState.inline.hpp sharkCacheDecache.hpp ciMethod.hpp sharkCacheDecache.hpp debugInfoRec.hpp sharkCacheDecache.hpp sharkBuilder.hpp -sharkCacheDecache.hpp sharkFrameCache.hpp sharkCacheDecache.hpp sharkFunction.hpp sharkCacheDecache.hpp sharkStateScanner.hpp @@ -174,15 +172,6 @@ sharkEntry.hpp llvmHeaders.hpp -sharkFrameCache.cpp allocation.hpp -sharkFrameCache.cpp llvmHeaders.hpp -sharkFrameCache.cpp sharkFrameCache.hpp -sharkFrameCache.cpp sharkFunction.hpp - -sharkFrameCache.hpp allocation.hpp -sharkFrameCache.hpp llvmHeaders.hpp -sharkFrameCache.hpp sharkFunction.hpp - sharkFunction.cpp allocation.hpp sharkFunction.cpp ciTypeFlow.hpp sharkFunction.cpp debug.hpp @@ -260,7 +249,6 @@ sharkState.cpp ciTypeFlow.hpp sharkState.cpp sharkBuilder.hpp sharkState.cpp sharkCacheDecache.hpp -sharkState.cpp sharkFrameCache.hpp sharkState.cpp sharkState.inline.hpp sharkState.cpp sharkTopLevelBlock.hpp sharkState.cpp sharkType.hpp @@ -270,11 +258,11 @@ sharkState.hpp ciMethod.hpp sharkState.hpp llvmHeaders.hpp sharkState.hpp sharkBuilder.hpp -sharkState.hpp sharkFrameCache.hpp sharkState.hpp sharkValue.hpp sharkState.inline.hpp sharkBlock.hpp sharkState.inline.hpp sharkBuilder.hpp +sharkState.inline.hpp sharkFunction.hpp sharkState.inline.hpp sharkState.hpp sharkStateScanner.cpp sharkState.inline.hpp diff -r e6350d5249d3 -r 4a617634d81c ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Tue Jun 16 10:58:00 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Wed Jun 17 14:37:31 2009 +0100 @@ -225,17 +225,12 @@ Value* value, int offset) { - if (frame_cache()->value(offset) != value) { - builder()->CreateStore( - value, - function()->CreateAddressOfFrameEntry(offset, type)); - } + builder()->CreateStore( + value, function()->CreateAddressOfFrameEntry(offset, type)); } Value* SharkCacher::read_value_from_frame(const Type* type, int offset) { - Value *result = builder()->CreateLoad( + return builder()->CreateLoad( function()->CreateAddressOfFrameEntry(offset, type)); - frame_cache()->set_value(offset, result); - return result; } diff -r e6350d5249d3 -r 4a617634d81c ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp --- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp Tue Jun 16 10:58:00 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp Wed Jun 17 14:37:31 2009 +0100 @@ -37,17 +37,8 @@ class SharkCacherDecacher : public SharkStateScanner { protected: - SharkCacherDecacher(SharkFunction* function, SharkFrameCache* frame_cache) - : SharkStateScanner(function), _frame_cache(frame_cache) {} - - private: - SharkFrameCache* _frame_cache; - - protected: - SharkFrameCache* frame_cache() const - { - return _frame_cache; - } + SharkCacherDecacher(SharkFunction* function) + : SharkStateScanner(function) {} protected: SharkBuilder* builder() const @@ -67,8 +58,8 @@ class SharkDecacher : public SharkCacherDecacher { protected: - SharkDecacher(SharkFunction* function, SharkFrameCache* frame_cache, int bci) - : SharkCacherDecacher(function, frame_cache), _bci(bci) {} + SharkDecacher(SharkFunction* function, int bci) + : SharkCacherDecacher(function), _bci(bci) {} private: int _bci; @@ -223,11 +214,8 @@ class SharkJavaCallDecacher : public SharkDecacher { public: - SharkJavaCallDecacher(SharkFunction* function, - SharkFrameCache* frame_cache, - int bci, - ciMethod* callee) - : SharkDecacher(function, frame_cache, bci), _callee(callee) {} + SharkJavaCallDecacher(SharkFunction* function, int bci, ciMethod* callee) + : SharkDecacher(function, bci), _callee(callee) {} private: ciMethod* _callee; @@ -271,10 +259,8 @@ class SharkVMCallDecacher : public SharkDecacher { public: - SharkVMCallDecacher(SharkFunction* function, - SharkFrameCache* frame_cache, - int bci) - : SharkDecacher(function, frame_cache, bci) {} + SharkVMCallDecacher(SharkFunction* function, int bci) + : SharkDecacher(function, bci) {} // Stack slot helpers protected: @@ -309,10 +295,8 @@ class SharkTrapDecacher : public SharkDecacher { public: - SharkTrapDecacher(SharkFunction* function, - SharkFrameCache* frame_cache, - int bci) - : SharkDecacher(function, frame_cache, bci) {} + SharkTrapDecacher(SharkFunction* function, int bci) + : SharkDecacher(function, bci) {} // Stack slot helpers protected: @@ -347,8 +331,8 @@ class SharkCacher : public SharkCacherDecacher { protected: - SharkCacher(SharkFunction* function, SharkFrameCache* frame_cache) - : SharkCacherDecacher(function, frame_cache) {} + SharkCacher(SharkFunction* function) + : SharkCacherDecacher(function) {} // Callbacks protected: @@ -377,10 +361,8 @@ class SharkJavaCallCacher : public SharkCacher { public: - SharkJavaCallCacher(SharkFunction* function, - SharkFrameCache* frame_cache, - ciMethod* callee) - : SharkCacher(function, frame_cache), _callee(callee) {} + SharkJavaCallCacher(SharkFunction* function, ciMethod* callee) + : SharkCacher(function), _callee(callee) {} private: ciMethod* _callee; @@ -402,8 +384,8 @@ class SharkVMCallCacher : public SharkCacher { public: - SharkVMCallCacher(SharkFunction* function, SharkFrameCache* frame_cache) - : SharkCacher(function, frame_cache) {} + SharkVMCallCacher(SharkFunction* function) + : SharkCacher(function) {} // Stack slot helper protected: @@ -415,10 +397,8 @@ class SharkFunctionEntryCacher : public SharkCacher { public: - SharkFunctionEntryCacher(SharkFunction* function, - SharkFrameCache* frame_cache, - llvm::Value* method) - : SharkCacher(function, frame_cache), _method(method) {} + SharkFunctionEntryCacher(SharkFunction* function, llvm::Value* method) + : SharkCacher(function), _method(method) {} private: llvm::Value* _method; diff -r e6350d5249d3 -r 4a617634d81c ports/hotspot/src/share/vm/shark/sharkFrameCache.cpp --- a/ports/hotspot/src/share/vm/shark/sharkFrameCache.cpp Tue Jun 16 10:58:00 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * 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/_sharkFrameCache.cpp.incl" - -using namespace llvm; - -SharkFrameCache::SharkFrameCache(SharkFunction *function) - : _frame_size(function->extended_frame_size()) -{ - _values = NEW_RESOURCE_ARRAY(Value*, frame_size()); - memset(_values, 0, frame_size() * sizeof(Value *)); -} - -SharkFrameCache::SharkFrameCache(const SharkFrameCache* cache) - : _frame_size(cache->frame_size()) -{ - _values = NEW_RESOURCE_ARRAY(Value*, frame_size()); - memcpy(_values, cache->_values, frame_size() * sizeof(Value *)); -} - -bool SharkFrameCache::equal_to(SharkFrameCache* other) -{ - if (frame_size() != other->frame_size()) - return false; - - for (int i = 0; i < frame_size(); i++) { - if (value(i) != other->value(i)) - return false; - } - - return true; -} - -void SharkFrameCache::merge(SharkFrameCache* other) -{ - assert(frame_size() == other->frame_size(), "should be"); - - for (int i = 0; i < frame_size(); i++) { - if (value(i) != other->value(i)) - set_value(i, NULL); - } -} diff -r e6350d5249d3 -r 4a617634d81c ports/hotspot/src/share/vm/shark/sharkFrameCache.hpp --- a/ports/hotspot/src/share/vm/shark/sharkFrameCache.hpp Tue Jun 16 10:58:00 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * 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 SharkFrameCache : public ResourceObj { - public: - SharkFrameCache(SharkFunction* function); - - protected: - SharkFrameCache(const SharkFrameCache* cache); - - private: - int _frame_size; - llvm::Value** _values; - - private: - int frame_size() const - { - return _frame_size; - } - - public: - llvm::Value* value(int slot) - { - assert(slot >= 0 && slot < frame_size(), "bad index"); - return _values[slot]; - } - void set_value(int slot, llvm::Value* value) - { - assert(slot >= 0 && slot < frame_size(), "bad index"); - _values[slot] = value; - } - - // Comparison - public: - bool equal_to(SharkFrameCache* other); - - // Copy and merge - public: - SharkFrameCache *copy() const - { - return new SharkFrameCache(this); - } - void merge(SharkFrameCache* other); -}; diff -r e6350d5249d3 -r 4a617634d81c ports/hotspot/src/share/vm/shark/sharkState.cpp --- a/ports/hotspot/src/share/vm/shark/sharkState.cpp Tue Jun 16 10:58:00 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkState.cpp Wed Jun 17 14:37:31 2009 +0100 @@ -33,7 +33,6 @@ _function(function), _method(NULL), _oop_tmp(NULL), - _frame_cache(NULL), _has_safepointed(false) { initialize(NULL); @@ -44,7 +43,6 @@ _function(state->function()), _method(state->method()), _oop_tmp(state->oop_tmp()), - _frame_cache(NULL), _has_safepointed(state->has_safepointed()) { initialize(state); @@ -73,13 +71,7 @@ value = value->clone(); push(value); } - - if (state->frame_cache()) - _frame_cache = state->frame_cache()->copy(); } - else if (function()) { - _frame_cache = new SharkFrameCache(function()); - } set_num_monitors(state ? state->num_monitors() : 0); } @@ -146,19 +138,6 @@ } } - // Frame cache - if (frame_cache() == NULL) { - if (other->frame_cache() != NULL) - return false; - } - else { - if (other->frame_cache() == NULL) - return false; - - if (!frame_cache()->equal_to(other->frame_cache())) - return false; - } - return true; } @@ -218,9 +197,6 @@ } } - // Frame cache - frame_cache()->merge(other->frame_cache()); - // Safepointed status set_has_safepointed(this->has_safepointed() && other->has_safepointed()); } @@ -243,8 +219,7 @@ void SharkState::decache_for_Java_call(ciMethod* callee) { assert(function() && method(), "you cannot decache here"); - SharkJavaCallDecacher( - function(), frame_cache(), block()->bci(), callee).scan(this); + SharkJavaCallDecacher(function(), block()->bci(), callee).scan(this); pop(callee->arg_size()); } @@ -269,25 +244,25 @@ if (type->is_two_word()) push(NULL); } - SharkJavaCallCacher(function(), frame_cache(), callee).scan(this); + SharkJavaCallCacher(function(), callee).scan(this); } void SharkState::decache_for_VM_call() { assert(function() && method(), "you cannot decache here"); - SharkVMCallDecacher(function(), frame_cache(), block()->bci()).scan(this); + SharkVMCallDecacher(function(), block()->bci()).scan(this); } void SharkState::cache_after_VM_call() { assert(function() && method(), "you cannot cache here"); - SharkVMCallCacher(function(), frame_cache()).scan(this); + SharkVMCallCacher(function()).scan(this); } void SharkState::decache_for_trap() { assert(function() && method(), "you cannot decache here"); - SharkTrapDecacher(function(), frame_cache(), block()->bci()).scan(this); + SharkTrapDecacher(function(), block()->bci()).scan(this); } SharkEntryState::SharkEntryState(SharkTopLevelBlock* block, Value* method) @@ -326,7 +301,7 @@ } set_local(i, value); } - SharkFunctionEntryCacher(function(), frame_cache(), method).scan(this); + SharkFunctionEntryCacher(function(), method).scan(this); } SharkPHIState::SharkPHIState(SharkTopLevelBlock* block) diff -r e6350d5249d3 -r 4a617634d81c ports/hotspot/src/share/vm/shark/sharkState.hpp --- a/ports/hotspot/src/share/vm/shark/sharkState.hpp Tue Jun 16 10:58:00 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkState.hpp Wed Jun 17 14:37:31 2009 +0100 @@ -39,7 +39,6 @@ SharkBlock* _block; SharkFunction* _function; llvm::Value* _method; - SharkFrameCache* _frame_cache; SharkValue** _locals; SharkValue** _stack; SharkValue** _sp; @@ -56,10 +55,6 @@ { return _function; } - SharkFrameCache *frame_cache() const - { - return _frame_cache; - } public: inline SharkBuilder* builder() const; From xerxes at zafena.se Wed Jun 17 07:35:07 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Wed, 17 Jun 2009 16:35:07 +0200 Subject: RFC: Shark llvm2.6 api changes to Threads and JIT Initialization Message-ID: <4A38FF1B.80303@zafena.se> Hi this the second issue of the Shark daily digest, today we will talk about changes to the llvm API for the next llvm version 2.6 that are allready in use in the 2.6svn trunk. If you want to be a early shark then this is for you! API issue 1 LLVM are adding multi-threaded support and clients who make us of the LLVM API have to change accordingly. http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-June/023080.html Quote "The major CHANGE is: the JIT will no longer be safe for executing threaded applications without first invoking llvm_start_multithreaded ()." API issue 2 Another change are to the Initialization of the JIT. Before the creation of the ExecutionEngine the JIT for the target shark are running on have to explicitly be initialized. Without the initialization creation of the execution engine will return null and makes shark segfault. The functions used for this Initialization are named: llvm::InitializeMSILTarget() llvm::InitializeMSP430Target() llvm::InitializeXCoreTarget() llvm::InitializePIC16Target() llvm::InitializeCellSPUTarget() llvm::InitializeMipsTarget() llvm::InitializeARMTarget() llvm::InitializeIA64Target() llvm::InitializeAlphaTarget() llvm::InitializePowerPCTarget() llvm::InitializeSparcTarget() llvm::InitializeX86Target() fix 1: we have to invent a large #if block to deal with this fix 2: or persuade the llvm people to create a llvm::InitializeMyTarget() fix 3: do like llvm internally and add some macros to convert LLVM_NATIVE_ARCH into the correct methodname: here are the llvm fix for lli http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090615/078864.html Patch The attached patch fixes issue 1 and gives an example for issue 2 on X86. Cheers Xerxes -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm_api_breakage_3.patch Type: text/x-patch Size: 1621 bytes Desc: not available Url : http://mail.openjdk.java.net/pipermail/zero-dev/attachments/20090617/3f4ac711/attachment.bin From xerxes at zafena.se Wed Jun 17 10:25:54 2009 From: xerxes at zafena.se (=?ISO-8859-1?Q?Xerxes_R=E5nby?=) Date: Wed, 17 Jun 2009 19:25:54 +0200 Subject: RFC: Shark llvm2.6 api changes to Threads and JIT Initialization In-Reply-To: <4A38FF1B.80303@zafena.se> References: <4A38FF1B.80303@zafena.se> Message-ID: <4A392722.6080007@zafena.se> Den 2009-06-17 16:35, Xerxes R?nby skrev: > > fix 2: or persuade the llvm people to create a llvm::InitializeMyTarget() > The llvm developers quickly created what we wanted: include llvm/trunk/include/llvm/Target/TargetSelect.h and use // If we have a native target, initialize it to ensure it is linked in and // usable by the JIT. InitializeNativeTarget(); http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090615/078885.html the llvm examples have been changed to use the jit in this way: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090615/078888.html Cheers Xerxes From gbenson at redhat.com Thu Jun 18 02:26:17 2009 From: gbenson at redhat.com (Gary Benson) Date: Thu, 18 Jun 2009 10:26:17 +0100 Subject: RFC: Shark llvm2.6 api changes to Threads and JIT Initialization In-Reply-To: <4A392722.6080007@zafena.se> References: <4A38FF1B.80303@zafena.se> <4A392722.6080007@zafena.se> Message-ID: <20090618092617.GA3159@redhat.com> Xerxes R?nby wrote: > Den 2009-06-17 16:35, Xerxes R?nby skrev: > > fix 2: or persuade the llvm people to create a llvm::InitializeMyTarget() > > The llvm developers quickly created what we wanted: > > include > llvm/trunk/include/llvm/Target/TargetSelect.h > and use > // If we have a native target, initialize it to ensure it is linked in and > // usable by the JIT. > InitializeNativeTarget(); It was kind of odd that they didn't do that already :) Cheers, Gary -- http://gbenson.net/ From gbenson at redhat.com Thu Jun 18 09:12:39 2009 From: gbenson at redhat.com (Gary Benson) Date: Thu, 18 Jun 2009 17:12:39 +0100 Subject: Big Shark refactoring Message-ID: <20090618161239.GB3159@redhat.com> Hi all, There's a lot of information that needs passing around during a Shark compilation, and previously this has been done in a pretty ad-hoc way. This commit rationalizes this, by creating two new classes which wrap all compilation- and method-specific data. Classes requiring this data can then extend one or the other of these classes to get all the information they need. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r e86b8e1d9de6 -r 4e8a6af384a1 ChangeLog --- a/ChangeLog Thu Jun 18 10:58:02 2009 +0200 +++ b/ChangeLog Thu Jun 18 12:00:59 2009 -0400 @@ -1,3 +1,156 @@ +2009-06-18 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkInvariants.hpp: New file. + * ports/hotspot/src/share/vm/shark/sharkInvariants.cpp: Likewise. + + * ports/hotspot/src/share/vm/shark/sharkFunction.hpp + (SharkFunction): Made a subclass of SharkTargetInvariants. + (SharkFunction::SharkFunction): Updated constructor. + (SharkFunction::_compiler): Removed. + (SharkFunction::_flow): Likewise. + (SharkFunction::_iter): Likewise. + (SharkFunction::_thread): Likewise. + (SharkFunction::_max_monitors): Likewise. + (SharkFunction::compiler): Likewise. + (SharkFunction::flow): Likewise. + (SharkFunction::iter): Likewise. + (SharkFunction::thread): Likewise. + (SharkFunction::max_monitors): Likewise. + (SharkFunction::builder): Likewise. + (SharkFunction::arg_size): Likewise. + (SharkFunction::debug_info): Likewise. + (SharkFunction::env): Likewise. + (SharkFunction::max_locals): Likewise. + (SharkFunction::max_stack): Likewise. + (SharkFunction::target): Likewise. + * ports/hotspot/src/share/vm/shark/sharkFunction.hpp + (SharkFunction::initialize): Updated. + + * ports/hotspot/src/share/vm/shark/sharkBlock.hpp + (SharkBlock): Made a subclass of SharkTargetInvariants. + (SharkBlock::SharkBlock): Updated constructors. + (SharkBlock::_builder): Removed. + (SharkBlock::_target): Likewise. + (SharkBlock::_thread): Likewise. + (SharkBlock::builder): Likewise. + (SharkBlock::target): Likewise. + (SharkBlock::thread): Likewise. + (SharkBlock::max_locals): Likewise. + (SharkBlock::max_stack): Likewise. + * ports/hotspot/src/share/vm/shark/sharkBlock.cpp + (SharkBlock::initial_current_state): Use SharkState::copy. + + * ports/hotspot/src/share/vm/shark/sharkState.hpp + (SharkState): Made a subclass of SharkTargetInvariants. + (SharkState::SharkState): Updated constructors. + (SharkState::_block): Removed. + (SharkState::_function): Likewise. + (SharkState::block): Likewise. + (SharkState::function): Likewise. + (SharkState::builder): Likewise. + (SharkState::max_locals): Likewise. + (SharkState::max_stack): Likewise. + (SharkState::max_monitors): Likewise. + (SharkState::pop): Likewise. + (SharkState::copy): Updated. + (SharkState::decache_for_Java_call): Moved to SharkTopLevelBlock. + (SharkState::cache_after_Java_call): Likewise. + (SharkState::decache_for_VM_call): Likewise. + (SharkState::cache_after_VM_call): Likewise. + (SharkState::decache_for_trap): Likewise. + (SharkPHIState::_block): New field. + (SharkPHIState::block): New method. + * ports/hotspot/src/share/vm/shark/sharkState.inline.hpp: Removed. + * ports/hotspot/src/share/vm/shark/sharkState.cpp + (SharkState::equal_to): Updated. + (SharkState::decache_for_Java_call): Moved to SharkTopLevelBlock. + (SharkState::cache_after_Java_call): Likewise. + (SharkState::decache_for_VM_call): Likewise. + (SharkState::cache_after_VM_call): Likewise. + (SharkState::decache_for_trap): Likewise. + (SharkEntryState::SharkEntryState): Updated. + (SharkPHIState::SharkPHIState): Likewise. + (SharkPHIState::add_incoming): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp + (SharkStateScanner): Made a subclass of SharkTargetInvariants. + (SharkStateScanner::SharkStateScanner): Updated constructor. + (SharkStateScanner::start_stack): Updated arguments. + (SharkStateScanner::start_locals): Likewise. + (SharkStateScanner::stack_integrity_checks): Made non-static. + (SharkStateScanner::locals_integrity_checks): Likewise. + * ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp + (SharkStateScanner::scan): Updated. + (SharkStateScanner::locals_integrity_checks): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp + (SharkCacherDecacher::builder): Removed. + (SharkDecacher::debug_info): Likewise. + (SharkDecacher::start_stack): Updated arguments. + (SharkDecacher::start_locals): Likewise. + * ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp + (SharkDecacher::start_frame): Updated. + (SharkDecacher::start_stack): Likewise.. + (SharkDecacher::start_locals): Likewise. + (SharkDecacher::end_frame): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkInliner.hpp + (SharkInliner::attempt_inline): Removed thread argument. + * ports/hotspot/src/share/vm/shark/sharkInliner.cpp + (SharkInlineBlock): Made a subclass of SharkTargetInvariants. + (SharkInlineBlock::SharkInlineBlock): Updated constructor. + (SharkInlinerHelper::SharkInlinerHelper): Likewise. + (SharkInlinerHelper::_thread): Removed. + (SharkInlinerHelper::thread): Likewise. + (SharkInlinerHelper::do_inline): Updated. + (SharkInliner::attempt_inline): Updated. + + * ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp + (SharkIntrinsics): Made a subclass of SharkTargetInvariants. + (SharkIntrinsics::inline_intrinsic): Updated arguments. + (SharkIntrinsics::SharkIntrinsics): New method. + (SharkIntrinsics::_state): New field. + (SharkIntrinsics::state): New method. + (SharkIntrinsics::do_intrinsic): Likewise. + (SharkIntrinsics::do_Math_minmax): Updated arguments. + (SharkIntrinsics::do_Math_1to1): Likewise. + (SharkIntrinsics::do_Math_2to1): Likewise. + (SharkIntrinsics::do_Object_getClass): Likewise. + (SharkIntrinsics::do_System_currentTimeMillis): Likewise. + (SharkIntrinsics::do_Thread_currentThread): Likewise. + (SharkIntrinsics::do_Unsafe_compareAndSwapInt): Likewise. + * ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp + (SharkIntrinsics::inline_intrinsic): Updated. + (SharkIntrinsics::do_intrinsic): New method. + (SharkIntrinsics::do_Math_minmax): Updated. + (SharkIntrinsics::do_Math_1to1): Likewise. + (SharkIntrinsics::do_Math_2to1): Likewise. + (SharkIntrinsics::do_Object_getClass): Likewise. + (SharkIntrinsics::do_System_currentTimeMillis): Likewise. + (SharkIntrinsics::do_Thread_currentThread): Likewise. + (SharkIntrinsics::do_Unsafe_compareAndSwapInt): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::SharkTopLevelBlock): Updated constructor. + (SharkTopLevelBlock::decache_for_Java_call): Moved from SharkState. + (SharkTopLevelBlock::cache_after_Java_call): Likewise. + (SharkTopLevelBlock::decache_for_VM_call): Likewise. + (SharkTopLevelBlock::cache_after_VM_call): Likewise. + (SharkTopLevelBlock::decache_for_trap): Likewise. + (SharkTopLevelBlock::call_vm): Updated. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::decache_for_Java_call): Moved from SharkState. + (SharkTopLevelBlock::cache_after_Java_call): Likewise. + (SharkTopLevelBlock::decache_for_VM_call): Likewise. + (SharkTopLevelBlock::cache_after_VM_call): Likewise. + (SharkTopLevelBlock::decache_for_trap): Likewise. + (SharkTopLevelBlock::do_trap): Updated. + (SharkTopLevelBlock::improve_virtual_call): Likewise. + (SharkTopLevelBlock::do_call): Likewise. + (SharkTopLevelBlock::acquire_lock): Likewise. + + * ports/hotspot/src/share/vm/includeDB_shark: Updated. + 2009-06-18 Mark Wielaard * rt/net/sourceforge/jnlp/services/XExtendedService.java diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/includeDB_shark --- a/ports/hotspot/src/share/vm/includeDB_shark Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/includeDB_shark Thu Jun 18 12:00:59 2009 -0400 @@ -50,8 +50,6 @@ compileBroker.cpp sharkCompiler.hpp -disassembler_.cpp sharkEntry.hpp - globals.hpp shark_globals_.hpp globals.cpp shark_globals.hpp @@ -75,7 +73,7 @@ sharkBlock.cpp sharkBuilder.hpp sharkBlock.cpp sharkConstant.hpp sharkBlock.cpp sharkRuntime.hpp -sharkBlock.cpp sharkState.inline.hpp +sharkBlock.cpp sharkState.hpp sharkBlock.cpp sharkValue.hpp sharkBlock.hpp allocation.hpp @@ -85,6 +83,7 @@ sharkBlock.hpp llvmHeaders.hpp sharkBlock.hpp sharkBuilder.hpp sharkBlock.hpp sharkConstant.hpp +sharkBlock.hpp sharkInvariants.hpp sharkBlock.hpp sharkState.hpp sharkBlock.hpp sharkValue.hpp @@ -121,7 +120,7 @@ sharkCacheDecache.cpp sharkBuilder.hpp sharkCacheDecache.cpp sharkCacheDecache.hpp sharkCacheDecache.cpp sharkFunction.hpp -sharkCacheDecache.cpp sharkState.inline.hpp +sharkCacheDecache.cpp sharkState.hpp sharkCacheDecache.hpp ciMethod.hpp sharkCacheDecache.hpp debugInfoRec.hpp @@ -181,7 +180,7 @@ sharkFunction.cpp sharkBuilder.hpp sharkFunction.cpp sharkEntry.hpp sharkFunction.cpp sharkFunction.hpp -sharkFunction.cpp sharkState.inline.hpp +sharkFunction.cpp sharkState.hpp sharkFunction.cpp sharkTopLevelBlock.hpp sharkFunction.hpp allocation.hpp @@ -191,6 +190,7 @@ sharkFunction.hpp llvmHeaders.hpp sharkFunction.hpp llvmValue.hpp sharkFunction.hpp sharkBuilder.hpp +sharkFunction.hpp sharkInvariants.hpp sharkInliner.cpp allocation.hpp sharkInliner.cpp bytecodes.hpp @@ -198,29 +198,44 @@ sharkInliner.cpp ciMethod.hpp sharkInliner.cpp ciStreams.hpp sharkInliner.cpp shark_globals.hpp +sharkInliner.cpp sharkBlock.hpp sharkInliner.cpp sharkConstant.hpp sharkInliner.cpp sharkInliner.hpp sharkInliner.cpp sharkIntrinsics.hpp -sharkInliner.cpp sharkState.inline.hpp +sharkInliner.cpp sharkState.hpp sharkInliner.cpp sharkValue.hpp sharkInliner.hpp allocation.hpp sharkInliner.hpp ciMethod.hpp sharkInliner.hpp llvmHeaders.hpp -sharkInliner.hpp sharkState.inline.hpp +sharkInliner.hpp sharkState.hpp sharkIntrinsics.cpp ciMethod.hpp sharkIntrinsics.cpp llvmHeaders.hpp sharkIntrinsics.cpp shark_globals.hpp sharkIntrinsics.cpp sharkIntrinsics.hpp sharkIntrinsics.cpp sharkRuntime.hpp -sharkIntrinsics.cpp sharkState.inline.hpp +sharkIntrinsics.cpp sharkState.hpp sharkIntrinsics.cpp sharkValue.hpp sharkIntrinsics.hpp allocation.hpp sharkIntrinsics.hpp ciMethod.hpp sharkIntrinsics.hpp llvmHeaders.hpp sharkIntrinsics.hpp sharkState.hpp + +sharkInvariants.cpp sharkInvariants.hpp + +sharkInvariants.hpp allocation.hpp +sharkInvariants.hpp ciEnv.hpp +sharkInvariants.hpp ciMethod.hpp +sharkInvariants.hpp ciInstanceKlass.hpp +sharkInvariants.hpp ciTypeFlow.hpp +sharkInvariants.hpp debugInfoRec.hpp +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 @@ -249,7 +264,7 @@ sharkState.cpp ciTypeFlow.hpp sharkState.cpp sharkBuilder.hpp sharkState.cpp sharkCacheDecache.hpp -sharkState.cpp sharkState.inline.hpp +sharkState.cpp sharkState.hpp sharkState.cpp sharkTopLevelBlock.hpp sharkState.cpp sharkType.hpp sharkState.cpp sharkValue.hpp @@ -258,19 +273,16 @@ sharkState.hpp ciMethod.hpp sharkState.hpp llvmHeaders.hpp sharkState.hpp sharkBuilder.hpp +sharkState.hpp sharkInvariants.hpp sharkState.hpp sharkValue.hpp -sharkState.inline.hpp sharkBlock.hpp -sharkState.inline.hpp sharkBuilder.hpp -sharkState.inline.hpp sharkFunction.hpp -sharkState.inline.hpp sharkState.hpp - -sharkStateScanner.cpp sharkState.inline.hpp +sharkStateScanner.cpp sharkState.hpp sharkStateScanner.cpp sharkStateScanner.hpp sharkStateScanner.hpp allocation.hpp sharkStateScanner.hpp llvmHeaders.hpp sharkStateScanner.hpp sharkFunction.hpp +sharkStateScanner.hpp sharkInvariants.hpp sharkTopLevelBlock.cpp allocation.hpp sharkTopLevelBlock.cpp bytecodes.hpp @@ -283,12 +295,13 @@ sharkTopLevelBlock.cpp llvmHeaders.hpp sharkTopLevelBlock.cpp llvmValue.hpp sharkTopLevelBlock.cpp shark_globals.hpp +sharkTopLevelBlock.cpp sharkCacheDecache.hpp sharkTopLevelBlock.cpp sharkTopLevelBlock.hpp sharkTopLevelBlock.cpp sharkBuilder.hpp sharkTopLevelBlock.cpp sharkConstant.hpp sharkTopLevelBlock.cpp sharkInliner.hpp sharkTopLevelBlock.cpp sharkRuntime.hpp -sharkTopLevelBlock.cpp sharkState.inline.hpp +sharkTopLevelBlock.cpp sharkState.hpp sharkTopLevelBlock.cpp sharkValue.hpp sharkTopLevelBlock.hpp allocation.hpp @@ -300,7 +313,7 @@ sharkTopLevelBlock.hpp sharkBlock.hpp sharkTopLevelBlock.hpp sharkBuilder.hpp sharkTopLevelBlock.hpp sharkFunction.hpp -sharkTopLevelBlock.hpp sharkState.inline.hpp +sharkTopLevelBlock.hpp sharkState.hpp sharkTopLevelBlock.hpp sharkValue.hpp sharkType.cpp arrayOop.hpp diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp Thu Jun 18 12:00:59 2009 -0400 @@ -888,7 +888,7 @@ SharkState* SharkBlock::initial_current_state() { - return new SharkState(this, entry_state()); + return entry_state()->copy(); } int SharkBlock::switch_default_dest() diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Thu Jun 18 12:00:59 2009 -0400 @@ -25,61 +25,32 @@ class SharkState; -class SharkBlock : public ResourceObj { - public: - SharkBlock(SharkBuilder* builder, - ciMethod* target, - ciBytecodeStream* iter, - llvm::Value* thread) - : _builder(builder), - _target(target), - _iter(iter), - _current_state(NULL), - _thread(thread) {} +class SharkBlock : public SharkTargetInvariants { + protected: + SharkBlock(const SharkTargetInvariants* parent) + : SharkTargetInvariants(parent), + _iter(target()), + _current_state(NULL) {} + + SharkBlock(const SharkCompileInvariants* parent, ciMethod* target) + : SharkTargetInvariants(parent, target), + _iter(target), + _current_state(NULL) {} private: - SharkBuilder* _builder; - ciMethod* _target; - ciBytecodeStream* _iter; - SharkState* _current_state; - llvm::Value* _thread; + ciBytecodeStream _iter; + SharkState* _current_state; public: - SharkBuilder* builder() const + ciBytecodeStream* iter() { - return _builder; + return &_iter; } - ciMethod* target() const - { - return _target; - } - ciBytecodeStream* iter() const - { - return _iter; - } - llvm::Value* thread() const - { - return _thread; - } - - // Target properties - public: - int max_locals() const - { - return target()->max_locals(); - } - int max_stack() const - { - return target()->max_stack(); - } - - // Bytecode stream - public: - Bytecodes::Code bc() const + Bytecodes::Code bc() { return iter()->cur_bc(); } - int bci() const + int bci() { return iter()->cur_bci(); } diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Thu Jun 18 12:00:59 2009 -0400 @@ -34,20 +34,20 @@ _pc_offset = builder()->code_buffer()->create_unique_offset(); _oopmap = new OopMap( oopmap_slot_munge(function()->oopmap_frame_size()), - oopmap_slot_munge(function()->arg_size())); + oopmap_slot_munge(arg_size())); debug_info()->add_safepoint(pc_offset(), oopmap()); } -void SharkDecacher::start_stack(int num_slots, int max_slots) +void SharkDecacher::start_stack(int stack_depth) { // Create the array we'll record our stack slots in - _exparray = new GrowableArray(num_slots); + _exparray = new GrowableArray(stack_depth); // Set the stack pointer function()->CreateStoreZeroStackPointer( builder()->CreatePtrToInt( function()->CreateAddressOfFrameEntry( - function()->stack_slots_offset() + max_slots - num_slots), + function()->stack_slots_offset() + max_stack() - stack_depth), SharkType::intptr_type())); } @@ -123,10 +123,10 @@ function()->CreateAddressOfFrameEntry(offset)); } -void SharkDecacher::start_locals(int num_locals) +void SharkDecacher::start_locals() { // Create the array we'll record our local variables in - _locarray = new GrowableArray(num_locals);} + _locarray = new GrowableArray(max_locals());} void SharkDecacher::process_local_slot(int index, SharkValue** addr, @@ -158,7 +158,7 @@ // Record the scope debug_info()->describe_scope( pc_offset(), - function()->target(), + target(), bci(), debug_info()->create_scope_values(locarray()), debug_info()->create_scope_values(exparray()), diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp --- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp Thu Jun 18 12:00:59 2009 -0400 @@ -40,12 +40,6 @@ SharkCacherDecacher(SharkFunction* function) : SharkStateScanner(function) {} - protected: - SharkBuilder* builder() const - { - return function()->builder(); - } - // Helper protected: static int adjusted_offset(SharkValue* value, int offset) @@ -68,12 +62,6 @@ int bci() const { return _bci; - } - - private: - DebugInformationRecorder* debug_info() const - { - return function()->debug_info(); } private: @@ -109,7 +97,7 @@ protected: void start_frame(); - void start_stack(int num_slots, int max_slots); + void start_stack(int stack_depth); void process_stack_slot(int index, SharkValue** value, int offset); void start_monitors(int num_monitors); @@ -119,7 +107,7 @@ void process_method_slot(llvm::Value** value, int offset); void process_pc_slot(int offset); - void start_locals(int num_locals); + void start_locals(); void process_local_slot(int index, SharkValue** value, int offset); void end_frame(); diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkCompiler.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Thu Jun 18 12:00:59 2009 -0400 @@ -120,8 +120,7 @@ builder()->set_code_buffer(&cb); // Compile the method - ciBytecodeStream iter(target); - SharkFunction function(this, name, flow, &iter); + SharkFunction function(this, env, flow, name); // Unhook the code buffer builder()->set_code_buffer(NULL); diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkFunction.cpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Thu Jun 18 12:00:59 2009 -0400 @@ -39,7 +39,7 @@ // Create the function _function = builder()->CreateFunction(name()); entry->set_llvm_function(function()); - compiler()->memory_manager()->set_entry_for_function(function(), entry); + memory_manager()->set_entry_for_function(function(), entry); // Get our arguments Function::arg_iterator ai = function()->arg_begin(); @@ -48,12 +48,13 @@ Argument *base_pc = ai++; base_pc->setName("base_pc"); builder()->code_buffer()->set_base_pc(base_pc); - _thread = ai++; - _thread->setName("thread"); + Argument *thread = ai++; + thread->setName("thread"); + set_thread(thread); // Create the list of blocks set_block_insertion_point(NULL); - _blocks = NEW_RESOURCE_ARRAY(SharkTopLevelBlock*, flow()->block_count()); + _blocks = NEW_RESOURCE_ARRAY(SharkTopLevelBlock*, block_count()); for (int i = 0; i < block_count(); i++) { ciTypeFlow::Block *b = flow()->pre_order_at(i); @@ -76,14 +77,6 @@ block(i)->initialize(); } - // Initialize the monitors - _max_monitors = 0; - if (target()->is_synchronized() || target()->uses_monitors()) { - for (int i = 0; i < block_count(); i++) - _max_monitors = MAX2( - _max_monitors, block(i)->ciblock()->monitor_count()); - } - // Create the method preamble set_block_insertion_point(&function()->front()); builder()->SetInsertPoint(CreateBlock()); @@ -98,7 +91,7 @@ // Lock if necessary SharkState *entry_state = new SharkEntryState(start_block, method); - if (target()->is_synchronized()) { + if (is_synchronized()) { SharkTopLevelBlock *locker = new SharkTopLevelBlock(this, start_block->ciblock()); locker->add_incoming(entry_state); @@ -291,10 +284,11 @@ return result; } -class DeferredZeroCheck : public ResourceObj { +class DeferredZeroCheck : public SharkTargetInvariants { public: DeferredZeroCheck(SharkTopLevelBlock* block, SharkValue* value) - : _block(block), + : SharkTargetInvariants(block), + _block(block), _value(value), _bci(block->bci()), _state(block->current_state()->copy()), @@ -339,10 +333,6 @@ } public: - SharkBuilder* builder() const - { - return block()->builder(); - } SharkFunction* function() const { return block()->function(); diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkFunction.hpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Thu Jun 18 12:00:59 2009 -0400 @@ -24,105 +24,46 @@ */ class SharkTopLevelBlock; - class DeferredZeroCheck; -class SharkFunction : public StackObj { +class SharkFunction : public SharkTargetInvariants { public: - SharkFunction(SharkCompiler* compiler, - const char* name, - ciTypeFlow* flow, - ciBytecodeStream* iter) - : _compiler(compiler), - _name(name), - _flow(flow), - _iter(iter) - { initialize(); } + SharkFunction(SharkCompiler* compiler, + ciEnv* env, + ciTypeFlow* flow, + const char* name) + : SharkTargetInvariants(compiler, env, flow), _name(name) { initialize(); } private: void initialize(); private: - SharkCompiler* _compiler; const char* _name; - ciTypeFlow* _flow; - ciBytecodeStream* _iter; llvm::Function* _function; SharkTopLevelBlock** _blocks; - llvm::Value* _thread; - int _max_monitors; GrowableArray _deferred_zero_checks; - public: - SharkCompiler* compiler() const - { - return _compiler; - } + public: const char* name() const { return _name; - } - ciTypeFlow* flow() const - { - return _flow; - } - ciBytecodeStream* iter() const - { - return _iter; - } + } llvm::Function* function() const { return _function; - } - SharkTopLevelBlock* block(int i) const - { - return _blocks[i]; - } - llvm::Value* thread() const - { - return _thread; - } - int max_monitors() const - { - return _max_monitors; - } - GrowableArray* deferred_zero_checks() - { - return &_deferred_zero_checks; - } - - public: - SharkBuilder* builder() const - { - return compiler()->builder(); - } - int arg_size() const - { - return target()->arg_size(); } int block_count() const { return flow()->block_count(); } - DebugInformationRecorder *debug_info() const + SharkTopLevelBlock* block(int i) const { - return env()->debug_info(); + assert(i < block_count(), "should be"); + return _blocks[i]; } - ciEnv* env() const + GrowableArray* deferred_zero_checks() { - return flow()->env(); - } - int max_locals() const - { - return flow()->max_locals(); - } - int max_stack() const - { - return flow()->max_stack(); - } - ciMethod* target() const - { - return flow()->method(); + return &_deferred_zero_checks; } // Block management diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkInliner.cpp --- a/ports/hotspot/src/share/vm/shark/sharkInliner.cpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkInliner.cpp Thu Jun 18 12:00:59 2009 -0400 @@ -30,11 +30,8 @@ class SharkInlineBlock : public SharkBlock { public: - SharkInlineBlock(ciMethod* target, - SharkState* state, - ciBytecodeStream* iter, - Value* thread) - : SharkBlock(state->builder(), target, iter, thread), + SharkInlineBlock(ciMethod* target, SharkState* state) + : SharkBlock(state, target), _outer_state(state), _entry_state(new SharkState(this)) { @@ -80,17 +77,15 @@ class SharkInlinerHelper : public StackObj { public: - SharkInlinerHelper(ciMethod* target, SharkState* entry_state, Value* thread) + SharkInlinerHelper(ciMethod* target, SharkState* entry_state) : _target(target), _entry_state(entry_state), - _iter(target), - _thread(thread) {} + _iter(target) {} private: ciBytecodeStream _iter; SharkState* _entry_state; ciMethod* _target; - Value* _thread; public: ciBytecodeStream* iter() @@ -104,10 +99,6 @@ ciMethod* target() const { return _target; - } - Value* thread() const - { - return _thread; } public: @@ -207,8 +198,7 @@ public: void do_inline() { - (new SharkInlineBlock( - target(), entry_state(), iter(), thread()))->emit_IR(); + (new SharkInlineBlock(target(), entry_state()))->emit_IR(); } }; @@ -770,17 +760,15 @@ return true; } -bool SharkInliner::attempt_inline(ciMethod* target, - SharkState* state, - Value* thread) +bool SharkInliner::attempt_inline(ciMethod *target, SharkState *state) { if (SharkIntrinsics::is_intrinsic(target)) { - SharkIntrinsics::inline_intrinsic(target, state, thread); + SharkIntrinsics::inline_intrinsic(target, state); return true; } if (may_be_inlinable(target)) { - SharkInlinerHelper inliner(target, state, thread); + SharkInlinerHelper inliner(target, state); if (inliner.is_inlinable()) { inliner.do_inline(); return true; diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkInliner.hpp --- a/ports/hotspot/src/share/vm/shark/sharkInliner.hpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkInliner.hpp Thu Jun 18 12:00:59 2009 -0400 @@ -25,9 +25,7 @@ class SharkInliner : public AllStatic { public: - static bool attempt_inline(ciMethod* target, - SharkState* state, - llvm::Value* thread); + static bool attempt_inline(ciMethod* target, SharkState* state); private: static bool may_be_inlinable(ciMethod* target); diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp --- a/ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp Thu Jun 18 12:00:59 2009 -0400 @@ -75,67 +75,71 @@ return false; } -void SharkIntrinsics::inline_intrinsic(ciMethod* target, - SharkState* state, - Value* thread) +void SharkIntrinsics::inline_intrinsic(ciMethod *target, SharkState *state) { - switch (target->intrinsic_id()) { + SharkIntrinsics intrinsic(state, target); + intrinsic.do_intrinsic(); +} + +void SharkIntrinsics::do_intrinsic() +{ + switch (target()->intrinsic_id()) { // java.lang.Math case vmIntrinsics::_min: - do_Math_minmax(state, llvm::ICmpInst::ICMP_SLE); + do_Math_minmax(llvm::ICmpInst::ICMP_SLE); break; case vmIntrinsics::_max: - do_Math_minmax(state, llvm::ICmpInst::ICMP_SGE); + do_Math_minmax(llvm::ICmpInst::ICMP_SGE); break; case vmIntrinsics::_dabs: - do_Math_1to1(state, SharkRuntime::fabs()); + do_Math_1to1(SharkRuntime::fabs()); break; case vmIntrinsics::_dsin: - do_Math_1to1(state, state->builder()->llvm_sin_fn()); + do_Math_1to1(builder()->llvm_sin_fn()); break; case vmIntrinsics::_dcos: - do_Math_1to1(state, state->builder()->llvm_cos_fn()); + do_Math_1to1(builder()->llvm_cos_fn()); break; case vmIntrinsics::_dtan: - do_Math_1to1(state, SharkRuntime::tan()); + do_Math_1to1(SharkRuntime::tan()); break; case vmIntrinsics::_datan2: - do_Math_2to1(state, SharkRuntime::atan2()); + do_Math_2to1(SharkRuntime::atan2()); break; case vmIntrinsics::_dsqrt: - do_Math_1to1(state, state->builder()->llvm_sqrt_fn()); + do_Math_1to1(builder()->llvm_sqrt_fn()); break; case vmIntrinsics::_dlog: - do_Math_1to1(state, state->builder()->llvm_log_fn()); + do_Math_1to1(builder()->llvm_log_fn()); break; case vmIntrinsics::_dlog10: - do_Math_1to1(state, state->builder()->llvm_log10_fn()); + do_Math_1to1(builder()->llvm_log10_fn()); break; case vmIntrinsics::_dpow: - do_Math_2to1(state, state->builder()->llvm_pow_fn()); + do_Math_2to1(builder()->llvm_pow_fn()); break; case vmIntrinsics::_dexp: - do_Math_1to1(state, state->builder()->llvm_exp_fn()); + do_Math_1to1(builder()->llvm_exp_fn()); break; // java.lang.Object case vmIntrinsics::_getClass: - do_Object_getClass(state); + do_Object_getClass(); break; // java.lang.System case vmIntrinsics::_currentTimeMillis: - do_System_currentTimeMillis(state); + do_System_currentTimeMillis(); break; // java.lang.Thread case vmIntrinsics::_currentThread: - do_Thread_currentThread(state, thread); + do_Thread_currentThread(); break; // sun.misc.Unsafe case vmIntrinsics::_compareAndSwapInt: - do_Unsafe_compareAndSwapInt(state); + do_Unsafe_compareAndSwapInt(); break; default: @@ -143,85 +147,83 @@ } } -void SharkIntrinsics::do_Math_minmax(SharkState *state, ICmpInst::Predicate p) +void SharkIntrinsics::do_Math_minmax(ICmpInst::Predicate p) { - SharkBuilder *builder = state->builder(); - // Pop the arguments - SharkValue *sb = state->pop(); - SharkValue *sa = state->pop(); + SharkValue *sb = state()->pop(); + SharkValue *sa = state()->pop(); Value *a = sa->jint_value(); Value *b = sb->jint_value(); // Perform the test - BasicBlock *ip = builder->GetBlockInsertionPoint(); - BasicBlock *return_a = builder->CreateBlock(ip, "return_a"); - BasicBlock *return_b = builder->CreateBlock(ip, "return_b"); - BasicBlock *done = builder->CreateBlock(ip, "done"); + BasicBlock *ip = builder()->GetBlockInsertionPoint(); + BasicBlock *return_a = builder()->CreateBlock(ip, "return_a"); + BasicBlock *return_b = builder()->CreateBlock(ip, "return_b"); + BasicBlock *done = builder()->CreateBlock(ip, "done"); - builder->CreateCondBr(builder->CreateICmp(p, a, b), return_a, return_b); + builder()->CreateCondBr(builder()->CreateICmp(p, a, b), return_a, return_b); - builder->SetInsertPoint(return_a); - builder->CreateBr(done); + builder()->SetInsertPoint(return_a); + builder()->CreateBr(done); - builder->SetInsertPoint(return_b); - builder->CreateBr(done); + builder()->SetInsertPoint(return_b); + builder()->CreateBr(done); - builder->SetInsertPoint(done); - PHINode *phi = builder->CreatePHI(a->getType(), "result"); + builder()->SetInsertPoint(done); + PHINode *phi = builder()->CreatePHI(a->getType(), "result"); phi->addIncoming(a, return_a); phi->addIncoming(b, return_b); // Push the result - state->push( + state()->push( SharkValue::create_jint( phi, sa->zero_checked() && sb->zero_checked())); } -void SharkIntrinsics::do_Math_1to1(SharkState *state, Constant *function) +void SharkIntrinsics::do_Math_1to1(Constant *function) { - SharkValue *empty = state->pop(); + SharkValue *empty = state()->pop(); assert(empty == NULL, "should be"); - state->push( + state()->push( SharkValue::create_jdouble( - state->builder()->CreateCall(function, state->pop()->jdouble_value()))); - state->push(NULL); + builder()->CreateCall( + function, state()->pop()->jdouble_value()))); + state()->push(NULL); } -void SharkIntrinsics::do_Math_2to1(SharkState *state, Constant *function) +void SharkIntrinsics::do_Math_2to1(Constant *function) { - SharkValue *empty = state->pop(); + SharkValue *empty = state()->pop(); assert(empty == NULL, "should be"); - Value *y = state->pop()->jdouble_value(); - empty = state->pop(); + Value *y = state()->pop()->jdouble_value(); + empty = state()->pop(); assert(empty == NULL, "should be"); - Value *x = state->pop()->jdouble_value(); + Value *x = state()->pop()->jdouble_value(); - state->push( - SharkValue::create_jdouble(state->builder()->CreateCall2(function, x, y))); - state->push(NULL); + state()->push( + SharkValue::create_jdouble( + builder()->CreateCall2(function, x, y))); + state()->push(NULL); } -void SharkIntrinsics::do_Object_getClass(SharkState *state) +void SharkIntrinsics::do_Object_getClass() { - SharkBuilder *builder = state->builder(); - - Value *klass = builder->CreateValueOfStructEntry( - state->pop()->jobject_value(), + Value *klass = builder()->CreateValueOfStructEntry( + state()->pop()->jobject_value(), in_ByteSize(oopDesc::klass_offset_in_bytes()), SharkType::jobject_type(), "klass"); - Value *klass_part = builder->CreateAddressOfStructEntry( + Value *klass_part = builder()->CreateAddressOfStructEntry( klass, in_ByteSize(klassOopDesc::klass_part_offset_in_bytes()), SharkType::klass_type(), "klass_part"); - state->push( + state()->push( SharkValue::create_jobject( - builder->CreateValueOfStructEntry( + builder()->CreateValueOfStructEntry( klass_part, in_ByteSize(Klass::java_mirror_offset_in_bytes()), SharkType::oop_type(), @@ -229,59 +231,57 @@ true)); } -void SharkIntrinsics::do_System_currentTimeMillis(SharkState *state) +void SharkIntrinsics::do_System_currentTimeMillis() { - state->push( + state()->push( SharkValue::create_jlong( - state->builder()->CreateCall(SharkRuntime::current_time_millis()), + builder()->CreateCall(SharkRuntime::current_time_millis()), false)); - state->push(NULL); + state()->push(NULL); } -void SharkIntrinsics::do_Thread_currentThread(SharkState *state, Value *thread) +void SharkIntrinsics::do_Thread_currentThread() { - state->push( + state()->push( SharkValue::create_jobject( - state->builder()->CreateValueOfStructEntry( - thread, JavaThread::threadObj_offset(), + builder()->CreateValueOfStructEntry( + thread(), JavaThread::threadObj_offset(), SharkType::jobject_type(), "threadObj"), true)); } -void SharkIntrinsics::do_Unsafe_compareAndSwapInt(SharkState *state) +void SharkIntrinsics::do_Unsafe_compareAndSwapInt() { - SharkBuilder *builder = state->builder(); - // Pop the arguments - Value *x = state->pop()->jint_value(); - Value *e = state->pop()->jint_value(); - SharkValue *empty = state->pop(); + Value *x = state()->pop()->jint_value(); + Value *e = state()->pop()->jint_value(); + SharkValue *empty = state()->pop(); assert(empty == NULL, "should be"); - Value *offset = state->pop()->jlong_value(); - Value *object = state->pop()->jobject_value(); - Value *unsafe = state->pop()->jobject_value(); + Value *offset = state()->pop()->jlong_value(); + Value *object = state()->pop()->jobject_value(); + Value *unsafe = state()->pop()->jobject_value(); // Convert the offset - offset = builder->CreateCall( + offset = builder()->CreateCall( SharkRuntime::unsafe_field_offset_to_byte_offset(), offset); // Locate the field - Value *addr = builder->CreateIntToPtr( - builder->CreateAdd( - builder->CreatePtrToInt(object, SharkType::intptr_type()), - builder->CreateIntCast(offset, SharkType::intptr_type(), true)), + Value *addr = builder()->CreateIntToPtr( + builder()->CreateAdd( + builder()->CreatePtrToInt(object, SharkType::intptr_type()), + builder()->CreateIntCast(offset, SharkType::intptr_type(), true)), PointerType::getUnqual(SharkType::jint_type()), "addr"); // Perform the operation - Value *result = builder->CreateCmpxchgInt(x, addr, e); + Value *result = builder()->CreateCmpxchgInt(x, addr, e); // Push the result - state->push( + state()->push( SharkValue::create_jint( - builder->CreateIntCast( - builder->CreateICmpEQ(result, e), SharkType::jint_type(), true), + builder()->CreateIntCast( + builder()->CreateICmpEQ(result, e), SharkType::jint_type(), true), false)); } diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp --- a/ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp Thu Jun 18 12:00:59 2009 -0400 @@ -23,19 +23,33 @@ * */ -class SharkIntrinsics : public AllStatic { +class SharkIntrinsics : public SharkTargetInvariants { public: static bool is_intrinsic(ciMethod* target); - static void inline_intrinsic(ciMethod* target, - SharkState* state, - llvm::Value* thread); + static void inline_intrinsic(ciMethod* target, SharkState* state); private: - static void do_Math_minmax(SharkState* state, llvm::ICmpInst::Predicate p); - static void do_Math_1to1(SharkState* state, llvm::Constant* function); - static void do_Math_2to1(SharkState* state, llvm::Constant* function); - static void do_Object_getClass(SharkState* state); - static void do_System_currentTimeMillis(SharkState* state); - static void do_Thread_currentThread(SharkState* state, llvm::Value* thread); - static void do_Unsafe_compareAndSwapInt(SharkState* state); + SharkIntrinsics(SharkState* state, ciMethod* target) + : SharkTargetInvariants(state, target), _state(state) {} + + private: + SharkState* _state; + + private: + SharkState* state() const + { + return _state; + } + + private: + void do_intrinsic(); + + private: + void do_Math_minmax(llvm::ICmpInst::Predicate p); + void do_Math_1to1(llvm::Constant* function); + void do_Math_2to1(llvm::Constant* function); + void do_Object_getClass(); + void do_System_currentTimeMillis(); + void do_Thread_currentThread(); + void do_Unsafe_compareAndSwapInt(); }; diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkInvariants.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkInvariants.cpp Thu Jun 18 12:00:59 2009 -0400 @@ -0,0 +1,38 @@ +/* + * 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/_sharkInvariants.cpp.incl" + +int SharkTargetInvariants::count_monitors() +{ + int result = 0; + if (is_synchronized() || target()->has_monitor_bytecodes()) { + for (int i = 0; i < flow()->block_count(); i++) { + result = MAX2(result, flow()->pre_order_at(i)->monitor_count()); + } + } + return result; +} diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkInvariants.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkInvariants.hpp Thu Jun 18 12:00:59 2009 -0400 @@ -0,0 +1,186 @@ +/* + * 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. + * + */ + +// Base classes used to track various values through the compilation. +// SharkCompileInvariants is used to track values which remain the +// same for the top-level method and any inlined methods it may have +// (ie for the whole compilation). SharkTargetInvariants is used to +// track values which differ between methods. + +class SharkCompileInvariants : public ResourceObj { + protected: + SharkCompileInvariants(SharkCompiler* compiler, ciEnv* env) + : _compiler(compiler), + _env(env), + _thread(NULL) {} + + SharkCompileInvariants(const SharkCompileInvariants* parent) + : _compiler(parent->_compiler), + _env(parent->_env), + _thread(parent->_thread) {} + + private: + SharkCompiler* _compiler; + ciEnv* _env; + llvm::Value* _thread; + + // The SharkCompiler that is compiling this method. Holds the + // classes that form the interface with LLVM (the builder, the + // module, the memory manager, etc) and provides the compile() + // method to convert LLVM functions to native code. + protected: + SharkCompiler* compiler() const + { + return _compiler; + } + + // Top-level broker for HotSpot's Compiler Interface. + // + // Its main purpose is to allow the various CI classes to access + // oops in the VM without having to worry about safepointing. In + // addition to this it acts as a holder for various recorders and + // memory allocators. + // + // Accessing this directly is kind of ugly, so it's private. Add + // new accessors below if you need something from it. + private: + ciEnv* env() const + { + return _env; + } + + // Pointer to this thread's JavaThread object. This is not + // available until a short way into SharkFunction creation + // so a setter is required. Assertions are used to enforce + // invariance. + protected: + llvm::Value* thread() const + { + assert(_thread != NULL, "thread not available"); + return _thread; + } + void set_thread(llvm::Value* thread) + { + assert(_thread == NULL, "thread already set"); + _thread = thread; + } + + // Objects that handle various aspects of the compilation. + protected: + SharkBuilder* builder() const + { + return compiler()->builder(); + } + SharkMemoryManager* memory_manager() const + { + return compiler()->memory_manager(); + } + DebugInformationRecorder* debug_info() const + { + return env()->debug_info(); + } + Dependencies* dependencies() const + { + return env()->dependencies(); + } + + // That well-known class... + protected: + ciInstanceKlass* java_lang_Object_klass() const + { + return env()->Object_klass(); + } +}; + +class SharkTargetInvariants : public SharkCompileInvariants { + protected: + SharkTargetInvariants(SharkCompiler* compiler, ciEnv* env, ciTypeFlow* flow) + : SharkCompileInvariants(compiler, env), + _target(flow->method()), + _flow(flow), + _max_monitors(count_monitors()) {} + + SharkTargetInvariants(const SharkCompileInvariants* parent, ciMethod* target) + : SharkCompileInvariants(parent), + _target(target), + _flow(NULL), + _max_monitors(count_monitors()) {} + + SharkTargetInvariants(const SharkTargetInvariants* parent) + : SharkCompileInvariants(parent), + _target(parent->_target), + _flow(parent->_flow), + _max_monitors(parent->_max_monitors) {} + + private: + int count_monitors(); + + private: + ciMethod* _target; + ciTypeFlow* _flow; + int _max_monitors; + + // The method being compiled. + protected: + ciMethod* target() const + { + return _target; + } + + // Typeflow analysis of the method being compiled. + protected: + ciTypeFlow* flow() const + { + assert(_flow != NULL, "typeflow not available"); + return _flow; + } + + // Properties of the method. + protected: + int max_locals() const + { + return target()->max_locals(); + } + int max_stack() const + { + return target()->max_stack(); + } + int max_monitors() const + { + return _max_monitors; + } + int arg_size() const + { + return target()->arg_size(); + } + bool is_static() const + { + return target()->is_static(); + } + bool is_synchronized() const + { + return target()->is_synchronized(); + } +}; diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkState.cpp --- a/ports/hotspot/src/share/vm/shark/sharkState.cpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkState.cpp Thu Jun 18 12:00:59 2009 -0400 @@ -27,26 +27,6 @@ #include "incls/_sharkState.cpp.incl" using namespace llvm; - -SharkState::SharkState(SharkBlock* block, SharkFunction* function) - : _block(block), - _function(function), - _method(NULL), - _oop_tmp(NULL), - _has_safepointed(false) -{ - initialize(NULL); -} - -SharkState::SharkState(SharkBlock* block, const SharkState* state) - : _block(block), - _function(state->function()), - _method(state->method()), - _oop_tmp(state->oop_tmp()), - _has_safepointed(state->has_safepointed()) -{ - initialize(state); -} void SharkState::initialize(const SharkState *state) { @@ -78,10 +58,7 @@ bool SharkState::equal_to(SharkState *other) { - if (block() != other->block()) - return false; - - if (function() != other->function()) + if (target() != other->target()) return false; if (method() != other->method()) @@ -216,57 +193,8 @@ } } -void SharkState::decache_for_Java_call(ciMethod* callee) -{ - assert(function() && method(), "you cannot decache here"); - SharkJavaCallDecacher(function(), block()->bci(), callee).scan(this); - pop(callee->arg_size()); -} - -void SharkState::cache_after_Java_call(ciMethod* callee) -{ - assert(function() && method(), "you cannot cache here"); - if (callee->return_type()->size()) { - ciType *type; - switch (callee->return_type()->basic_type()) { - case T_BOOLEAN: - case T_BYTE: - case T_CHAR: - case T_SHORT: - type = ciType::make(T_INT); - break; - - default: - type = callee->return_type(); - } - - push(SharkValue::create_generic(type, NULL, false)); - if (type->is_two_word()) - push(NULL); - } - SharkJavaCallCacher(function(), callee).scan(this); -} - -void SharkState::decache_for_VM_call() -{ - assert(function() && method(), "you cannot decache here"); - SharkVMCallDecacher(function(), block()->bci()).scan(this); -} - -void SharkState::cache_after_VM_call() -{ - assert(function() && method(), "you cannot cache here"); - SharkVMCallCacher(function()).scan(this); -} - -void SharkState::decache_for_trap() -{ - assert(function() && method(), "you cannot decache here"); - SharkTrapDecacher(function(), block()->bci()).scan(this); -} - SharkEntryState::SharkEntryState(SharkTopLevelBlock* block, Value* method) - : SharkState(block, block->function()) + : SharkState(block) { assert(!block->stack_depth_at_entry(), "entry block shouldn't have stack"); @@ -282,11 +210,10 @@ case T_DOUBLE: case T_OBJECT: case T_ARRAY: - if (i >= function()->arg_size()) { + if (i >= arg_size()) { ShouldNotReachHere(); } - value = SharkValue::create_generic( - type, NULL, i == 0 && !function()->target()->is_static()); + value = SharkValue::create_generic(type, NULL, i == 0 && !is_static()); break; case ciTypeFlow::StateVector::T_BOTTOM: @@ -301,11 +228,11 @@ } set_local(i, value); } - SharkFunctionEntryCacher(function(), method).scan(this); + SharkFunctionEntryCacher(block->function(), method).scan(this); } SharkPHIState::SharkPHIState(SharkTopLevelBlock* block) - : SharkState(block, block->function()) + : SharkState(block), _block(block) { BasicBlock *saved_insert_point = builder()->GetInsertBlock(); builder()->SetInsertPoint(block->entry_block()); @@ -407,7 +334,7 @@ } // Expression stack - int stack_depth = ((SharkTopLevelBlock *) block())->stack_depth_at_entry(); + int stack_depth = block()->stack_depth_at_entry(); assert(stack_depth == incoming_state->stack_depth(), "should be"); for (int i = 0; i < stack_depth; i++) { assert((stack(i) == NULL) == (incoming_state->stack(i) == NULL), "oops"); diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkState.hpp --- a/ports/hotspot/src/share/vm/shark/sharkState.hpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkState.hpp Thu Jun 18 12:00:59 2009 -0400 @@ -23,44 +23,31 @@ * */ -class SharkBlock; -class SharkFunction; -class SharkTopLevelBlock; +class SharkState : public SharkTargetInvariants { + public: + SharkState(const SharkTargetInvariants* parent) + : SharkTargetInvariants(parent), + _method(NULL), + _oop_tmp(NULL), + _has_safepointed(false) { initialize(NULL); } -class SharkState : public ResourceObj { - public: - SharkState(SharkBlock* block, SharkFunction* function = NULL); - SharkState(SharkBlock* block, const SharkState* state); + SharkState(const SharkState* state) + : SharkTargetInvariants(state), + _method(state->_method), + _oop_tmp(state->_oop_tmp), + _has_safepointed(state->_has_safepointed) { initialize(state); } private: void initialize(const SharkState* state); private: - SharkBlock* _block; - SharkFunction* _function; - llvm::Value* _method; - SharkValue** _locals; - SharkValue** _stack; - SharkValue** _sp; - int _num_monitors; - llvm::Value* _oop_tmp; - bool _has_safepointed; - - public: - SharkBlock *block() const - { - return _block; - } - SharkFunction *function() const - { - return _function; - } - - public: - inline SharkBuilder* builder() const; - inline int max_locals() const; - inline int max_stack() const; - inline int max_monitors() const; + llvm::Value* _method; + SharkValue** _locals; + SharkValue** _stack; + SharkValue** _sp; + int _num_monitors; + llvm::Value* _oop_tmp; + bool _has_safepointed; // Method public: @@ -125,11 +112,6 @@ assert(stack_depth() > 0, "stack underrun"); return *(--_sp); } - void pop(int slots) - { - assert(stack_depth() >= slots, "stack underrun"); - _sp -= slots; - } // Monitors public: @@ -176,7 +158,7 @@ public: SharkState* copy() const { - return new SharkState(block(), this); + return new SharkState(this); } void merge(SharkState* other, llvm::BasicBlock* other_block, @@ -185,15 +167,9 @@ // Value replacement public: void replace_all(SharkValue* old_value, SharkValue* new_value); +}; - // Cache and decache - public: - void decache_for_Java_call(ciMethod* callee); - void cache_after_Java_call(ciMethod* callee); - void decache_for_VM_call(); - void cache_after_VM_call(); - void decache_for_trap(); -}; +class SharkTopLevelBlock; // SharkEntryState objects are used to manage the state // that the method will be entered with. @@ -209,6 +185,15 @@ public: SharkPHIState(SharkTopLevelBlock* block); + private: + SharkTopLevelBlock* _block; + + private: + SharkTopLevelBlock* block() const + { + return _block; + } + public: void add_incoming(SharkState* incoming_state); }; diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkState.inline.hpp --- a/ports/hotspot/src/share/vm/shark/sharkState.inline.hpp Thu Jun 18 10:58:02 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * 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. - * - */ - -inline SharkBuilder* SharkState::builder() const -{ - return block()->builder(); -} - -inline int SharkState::max_locals() const -{ - return block()->max_locals(); -} - -inline int SharkState::max_stack() const -{ - return block()->max_stack(); -} - -inline int SharkState::max_monitors() const -{ - return function()->max_monitors(); -} diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp --- a/ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp Thu Jun 18 12:00:59 2009 -0400 @@ -34,13 +34,13 @@ // Expression stack stack_integrity_checks(state); - start_stack(state->stack_depth(), state->max_stack()); + start_stack(state->stack_depth()); for (int i = state->stack_depth() - 1; i >= 0; i--) { process_stack_slot( i, state->stack_addr(i), function()->stack_slots_offset() + - i + state->max_stack() - state->stack_depth()); + i + max_stack() - state->stack_depth()); } end_stack(); @@ -64,12 +64,12 @@ // Local variables locals_integrity_checks(state); - start_locals(state->max_locals()); - for (int i = 0; i < state->max_locals(); i++) { + start_locals(); + for (int i = 0; i < max_locals(); i++) { process_local_slot( i, state->local_addr(i), - function()->locals_slots_offset() + state->max_locals() - 1 - i); + function()->locals_slots_offset() + max_locals() - 1 - i); } end_locals(); @@ -92,7 +92,7 @@ void SharkStateScanner::locals_integrity_checks(SharkState* state) { - for (int i = 0; i < state->max_locals(); i++) { + for (int i = 0; i < max_locals(); i++) { if (state->local(i)) { if (state->local(i)->is_two_word()) assert(state->local(i + 1) == NULL, "should be"); diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp --- a/ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp Thu Jun 18 12:00:59 2009 -0400 @@ -25,10 +25,10 @@ class SharkState; -class SharkStateScanner : public StackObj { +class SharkStateScanner : public SharkTargetInvariants { protected: SharkStateScanner(SharkFunction* function) - : _function(function) {} + : SharkTargetInvariants(function), _function(function) {} private: SharkFunction* _function; @@ -49,7 +49,7 @@ protected: virtual void start_frame() {} - virtual void start_stack(int num_slots, int max_slots) {} + virtual void start_stack(int stack_depth) {} virtual void process_stack_slot(int index, SharkValue** value, int offset) {} virtual void end_stack() {} @@ -63,7 +63,7 @@ virtual void process_pc_slot(int offset) {} virtual void end_frame_header() {} - virtual void start_locals(int num_locals) {} + virtual void start_locals() {} virtual void process_local_slot(int index, SharkValue** value, int offset) {} virtual void end_locals() {} @@ -71,6 +71,6 @@ // Integrity checks private: - static void stack_integrity_checks(SharkState* state) PRODUCT_RETURN; - static void locals_integrity_checks(SharkState* state) PRODUCT_RETURN; + void stack_integrity_checks(SharkState* state) PRODUCT_RETURN; + void locals_integrity_checks(SharkState* state) PRODUCT_RETURN; }; diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Thu Jun 18 12:00:59 2009 -0400 @@ -189,6 +189,49 @@ "bci_%d%s", start(), is_backedge_copy() ? "_backedge_copy" : ""); _entry_block = function()->CreateBlock(name); +} + +void SharkTopLevelBlock::decache_for_Java_call(ciMethod *callee) +{ + SharkJavaCallDecacher(function(), bci(), callee).scan(current_state()); + for (int i = 0; i < callee->arg_size(); i++) + xpop(); +} + +void SharkTopLevelBlock::cache_after_Java_call(ciMethod *callee) +{ + if (callee->return_type()->size()) { + ciType *type; + switch (callee->return_type()->basic_type()) { + case T_BOOLEAN: + case T_BYTE: + case T_CHAR: + case T_SHORT: + type = ciType::make(T_INT); + break; + + default: + type = callee->return_type(); + } + + push(SharkValue::create_generic(type, NULL, false)); + } + SharkJavaCallCacher(function(), callee).scan(current_state()); +} + +void SharkTopLevelBlock::decache_for_VM_call() +{ + SharkVMCallDecacher(function(), bci()).scan(current_state()); +} + +void SharkTopLevelBlock::cache_after_VM_call() +{ + SharkVMCallCacher(function()).scan(current_state()); +} + +void SharkTopLevelBlock::decache_for_trap() +{ + SharkTrapDecacher(function(), bci()).scan(current_state()); } void SharkTopLevelBlock::emit_IR() @@ -508,7 +551,7 @@ void SharkTopLevelBlock::do_trap(int trap_request) { - current_state()->decache_for_trap(); + decache_for_trap(); builder()->CreateCall2( SharkRuntime::uncommon_trap(), thread(), @@ -828,7 +871,7 @@ // Array methods are all inherited from Object and are monomorphic if (receiver_type->is_array_klass() && - dest_method->holder() == function()->env()->Object_klass()) + dest_method->holder() == java_lang_Object_klass()) return dest_method; // All other interesting cases are instance classes @@ -876,7 +919,7 @@ // us dependent on that target method not getting overridden // by dynamic class loading. if (monomorphic_target != NULL) { - function()->env()->dependencies()->assert_unique_concrete_method( + dependencies()->assert_unique_concrete_method( actual_receiver, monomorphic_target); return monomorphic_target; } @@ -1077,7 +1120,7 @@ // Try to inline the call if (!call_is_virtual) { - if (SharkInliner::attempt_inline(call_method, current_state(), thread())) + if (SharkInliner::attempt_inline(call_method, current_state())) return; } @@ -1116,9 +1159,9 @@ "entry_point"); // Make the call - current_state()->decache_for_Java_call(call_method); + decache_for_Java_call(call_method); builder()->CreateCall3(entry_point, callee, base_pc, thread()); - current_state()->cache_after_Java_call(call_method); + cache_after_Java_call(call_method); // Check for pending exceptions check_pending_exception(EX_CHECK_FULL); @@ -1133,7 +1176,7 @@ // If the class we're checking against is java.lang.Object // then this is a no brainer. Apparently this can happen // in reflective code... - if (check_klass == function()->env()->Object_klass()) + if (check_klass == java_lang_Object_klass()) return true; // Perform a subtype check. NB in opto's code for this @@ -1690,13 +1733,13 @@ // NB we use the entire stack, but JavaThread::is_lock_owned() // uses a more limited range. I don't think it hurts though... Value *stack_limit = builder()->CreateValueOfStructEntry( - function()->thread(), Thread::stack_base_offset(), + thread(), Thread::stack_base_offset(), SharkType::intptr_type(), "stack_limit"); assert(sizeof(size_t) == sizeof(intptr_t), "should be"); Value *stack_size = builder()->CreateValueOfStructEntry( - function()->thread(), Thread::stack_size_offset(), + thread(), Thread::stack_size_offset(), SharkType::intptr_type(), "stack_size"); diff -r e86b8e1d9de6 -r 4e8a6af384a1 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Thu Jun 18 10:58:02 2009 +0200 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Thu Jun 18 12:00:59 2009 -0400 @@ -26,10 +26,7 @@ class SharkTopLevelBlock : public SharkBlock { public: SharkTopLevelBlock(SharkFunction* function, ciTypeFlow::Block* ciblock) - : SharkBlock(function->builder(), - function->target(), - function->iter(), - function->thread()), + : SharkBlock(function), _function(function), _ciblock(ciblock), _entered(false), @@ -205,6 +202,14 @@ return value; } + // Cache and decache + private: + void decache_for_Java_call(ciMethod* callee); + void cache_after_Java_call(ciMethod* callee); + void decache_for_VM_call(); + void cache_after_VM_call(); + void decache_for_trap(); + // Monitors private: int num_monitors() @@ -256,11 +261,11 @@ llvm::Value** args_end, int exception_action) { - current_state()->decache_for_VM_call(); + decache_for_VM_call(); function()->set_last_Java_frame(); llvm::CallInst *res = builder()->CreateCall(callee, args_start, args_end); function()->reset_last_Java_frame(); - current_state()->cache_after_VM_call(); + cache_after_VM_call(); if (exception_action & EAM_CHECK) { check_pending_exception(exception_action); current_state()->set_has_safepointed(true); From gbenson at redhat.com Thu Jun 18 09:20:12 2009 From: gbenson at redhat.com (Gary Benson) Date: Thu, 18 Jun 2009 17:20:12 +0100 Subject: Shark tweak Message-ID: <20090618162012.GC3159@redhat.com> Hi all, This commit tweaks when a warning is printed. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 4e8a6af384a1 -r 025782d51e5c ChangeLog --- a/ChangeLog Thu Jun 18 12:00:59 2009 -0400 +++ b/ChangeLog Thu Jun 18 12:14:25 2009 -0400 @@ -1,3 +1,9 @@ +2009-06-18 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::improve_virtual_call): Only print cast + warnings when run with -XX:+SharkPerformanceWarnings. + 2009-06-18 Gary Benson * ports/hotspot/src/share/vm/shark/sharkInvariants.hpp: New file. diff -r 4e8a6af384a1 -r 025782d51e5c ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Thu Jun 18 12:00:59 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Thu Jun 18 12:14:25 2009 -0400 @@ -902,15 +902,15 @@ // types, but I can't even tell which direction it // doesn't like. For now I'm going to block *any* cast. if (monomorphic_target != dest_method) { -#ifndef PRODUCT - tty->print_cr("found monomorphic target, but inhibited cast:"); - tty->print(" dest_method = "); - dest_method->print_short_name(tty); - tty->cr(); - tty->print(" monomorphic_target = "); - monomorphic_target->print_short_name(tty); - tty->cr(); -#endif // !PRODUCT + if (SharkPerformanceWarnings) { + warning("found monomorphic target, but inhibited cast:"); + tty->print(" dest_method = "); + dest_method->print_short_name(tty); + tty->cr(); + tty->print(" monomorphic_target = "); + monomorphic_target->print_short_name(tty); + tty->cr(); + } monomorphic_target = NULL; } } From gbenson at redhat.com Fri Jun 19 03:10:59 2009 From: gbenson at redhat.com (Gary Benson) Date: Fri, 19 Jun 2009 11:10:59 +0100 Subject: SharkFunction tidying Message-ID: <20090619101059.GA3218@redhat.com> Hi all, This commit moves all code not relating to building the LLVM IR for the method being compiled from SharkFunction::initialize() to SharkCompiler::compile_method(). SharkFunction is now solely concerned with emitting IR. Whilst I was doing this, I updated all debug code that takes a method name from a -XX option to use fnmatch. Some of them did already, but some were using strcmp. Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 94d99ead66a4 ChangeLog --- a/ChangeLog Fri Jun 19 03:59:26 2009 -0400 +++ b/ChangeLog Fri Jun 19 06:02:49 2009 -0400 @@ -1,3 +1,33 @@ +2009-06-19 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkCompiler.hpp + (SharkCompiler::compile): Removed. + * ports/hotspot/src/share/vm/shark/sharkCompiler.cpp + (SharkCompiler::compile_method): Moved all non-IR-emission + code from SharkFunction::initialize, and the IR-to-native + code from SharkCompiler::compile, here. Also changed all + debug options that take a method name to use fnmatch. + (SharkCompiler::compile): Removed. + + * ports/hotspot/src/share/vm/shark/sharkFunction.hpp + (SharkFunction::_name): Removed. + (SharkFunction::_name): Likewise. + (SharkFunction::initialize): Receive name in argument. + (SharkFunction::SharkFunction): Updated. + (SharkFunction::build): New method. + * ports/hotspot/src/share/vm/shark/sharkFunction.cpp + (SharkFunction::initialize): Receive name in argument, + and moved all code not relating to emitting the function's + IR to SharkCompiler::compile_method. + + * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp + (SharkBuilder::CreateFunction): Removed. + * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp + (SharkBuilder::CreateFunction): Likewise. + + * ports/hotspot/src/share/vm/shark/sharkInvariants.hpp + (SharkCompileInvariants::memory_manager): Removed. + 2009-06-19 Gary Benson * ports/hotspot/src/share/vm/shark/sharkEntry.hpp diff -r 94d99ead66a4 ports/hotspot/src/share/vm/shark/sharkBuilder.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Fri Jun 19 03:59:26 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Fri Jun 19 06:02:49 2009 -0400 @@ -176,16 +176,6 @@ set_llvm_pow_fn(module()->getOrInsertFunction("llvm.pow.f64", type)); } -Function *SharkBuilder::CreateFunction(const char *name) -{ - Function *function = Function::Create( - SharkType::entry_point_type(), - GlobalVariable::InternalLinkage, - name); - module()->getFunctionList().push_back(function); - return function; -} - CallInst* SharkBuilder::CreateDump(llvm::Value* value) { Constant *const_name; diff -r 94d99ead66a4 ports/hotspot/src/share/vm/shark/sharkBuilder.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Fri Jun 19 03:59:26 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Fri Jun 19 06:02:49 2009 -0400 @@ -45,10 +45,6 @@ { return compiler()->execution_engine(); } - - // Function creation - public: - llvm::Function *CreateFunction(const char *name = "func"); // Helpers for creating basic blocks // NB don't use unless SharkFunction::CreateBlock is unavailable diff -r 94d99ead66a4 ports/hotspot/src/share/vm/shark/sharkCompiler.cpp --- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Fri Jun 19 03:59:26 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Fri Jun 19 06:02:49 2009 -0400 @@ -91,7 +91,7 @@ #endif // !PRODUCT if (SharkOnlyCompile != NULL) { - if (strcmp(SharkOnlyCompile, name)) { + if (fnmatch(SharkOnlyCompile, name, 0)) { env->record_method_not_compilable("does not match SharkOnlyCompile"); return; } @@ -102,8 +102,7 @@ if (env->failing()) return; if (SharkPrintTypeflowOf != NULL) { - if (!strcmp(SharkPrintTypeflowOf, name) || - !strcmp(SharkPrintTypeflowOf, "*")) + if (!fnmatch(SharkPrintTypeflowOf, name, 0)) flow->print_on(tty); } @@ -119,12 +118,46 @@ SharkCodeBuffer cb(env->oop_recorder()); builder()->set_code_buffer(&cb); - // Compile the method - SharkFunction function(this, env, flow, name); + // Emit the entry point + SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry)); + + // Build the LLVM IR for the method + Function *function = SharkFunction::build(this, env, flow, name); + if (SharkPrintBitcodeOf != NULL) { + if (!fnmatch(SharkPrintBitcodeOf, name, 0)) + function->dump(); + } // Unhook the code buffer builder()->set_code_buffer(NULL); + // Compile to native code +#ifndef PRODUCT +#ifdef X86 + if (SharkPrintAsmOf != NULL) { + 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 // X86 +#endif // !PRODUCT + memory_manager()->set_entry_for_function(function, entry); + module()->getFunctionList().push_back(function); + entry->set_entry_point( + (ZeroEntry::method_entry_t) + execution_engine()->getPointerToFunction(function)); + + // Register generated code for profiling, etc + if (JvmtiExport::should_post_dynamic_code_generated()) { + JvmtiExport::post_dynamic_code_generated( + name, entry->code_start(), entry->code_limit()); + } + // Install the method into the VM CodeOffsets offsets; offsets.set_value(CodeOffsets::Deopt, 0); @@ -148,31 +181,10 @@ env->comp_level(), false, false); -} - -ZeroEntry::method_entry_t SharkCompiler::compile(const char* name, - Function* function) -{ - // Dump the generated code, if requested -#ifndef PRODUCT -#ifdef X86 - if (SharkPrintAsmOf != NULL) { - 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 // X86 -#endif // !PRODUCT - - // Compile to native code - return (ZeroEntry::method_entry_t) - execution_engine()->getPointerToFunction(function); + // Print statistics, if requested + if (SharkTraceInstalls) + entry->print_statistics(name); } const char* SharkCompiler::methodname(const ciMethod* target) diff -r 94d99ead66a4 ports/hotspot/src/share/vm/shark/sharkCompiler.hpp --- a/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp Fri Jun 19 03:59:26 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp Fri Jun 19 06:02:49 2009 -0400 @@ -72,9 +72,6 @@ return _execution_engine; } - public: - ZeroEntry::method_entry_t compile(const char* name, llvm::Function* func); - // Helper private: static const char* methodname(const ciMethod* target); diff -r 94d99ead66a4 ports/hotspot/src/share/vm/shark/sharkFunction.cpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Fri Jun 19 03:59:26 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Fri Jun 19 06:02:49 2009 -0400 @@ -26,19 +26,15 @@ #include "incls/_precompiled.incl" #include "incls/_sharkFunction.cpp.incl" -#include - using namespace llvm; -void SharkFunction::initialize() +void SharkFunction::initialize(const char *name) { - // Emit the entry point - SharkEntry *entry = - (SharkEntry *) builder()->code_buffer()->malloc(sizeof(SharkEntry)); - // Create the function - _function = builder()->CreateFunction(name()); - memory_manager()->set_entry_for_function(function(), entry); + _function = Function::Create( + SharkType::entry_point_type(), + GlobalVariable::InternalLinkage, + name); // Get our arguments Function::arg_iterator ai = function()->arg_begin(); @@ -118,25 +114,6 @@ block(i)->emit_IR(); } do_deferred_zero_checks(); - - // Dump the bitcode, if requested - if (SharkPrintBitcodeOf != NULL) { - if (!fnmatch(SharkPrintBitcodeOf, name(), 0)) - function()->dump(); - } - - // Compile to native code - entry->set_entry_point(compiler()->compile(name(), function())); - - // Register generated code for profiling, etc - if (JvmtiExport::should_post_dynamic_code_generated()) { - JvmtiExport::post_dynamic_code_generated( - name(), entry->code_start(), entry->code_limit()); - } - - // Print statistics, if requested - if (SharkTraceInstalls) - entry->print_statistics(name()); } void SharkFunction::CreateInitZeroStack() diff -r 94d99ead66a4 ports/hotspot/src/share/vm/shark/sharkFunction.hpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Fri Jun 19 03:59:26 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Fri Jun 19 06:02:49 2009 -0400 @@ -28,26 +28,31 @@ class SharkFunction : public SharkTargetInvariants { public: + static llvm::Function* build(SharkCompiler* compiler, + ciEnv* env, + ciTypeFlow* flow, + const char* name) + { + SharkFunction function(compiler, env, flow, name); + return function.function(); + } + + private: SharkFunction(SharkCompiler* compiler, ciEnv* env, ciTypeFlow* flow, const char* name) - : SharkTargetInvariants(compiler, env, flow), _name(name) { initialize(); } + : SharkTargetInvariants(compiler, env, flow) { initialize(name); } private: - void initialize(); + void initialize(const char* name); private: - const char* _name; llvm::Function* _function; SharkTopLevelBlock** _blocks; GrowableArray _deferred_zero_checks; public: - const char* name() const - { - return _name; - } llvm::Function* function() const { return _function; diff -r 94d99ead66a4 ports/hotspot/src/share/vm/shark/sharkInvariants.hpp --- a/ports/hotspot/src/share/vm/shark/sharkInvariants.hpp Fri Jun 19 03:59:26 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkInvariants.hpp Fri Jun 19 06:02:49 2009 -0400 @@ -93,10 +93,6 @@ { return compiler()->builder(); } - SharkMemoryManager* memory_manager() const - { - return compiler()->memory_manager(); - } DebugInformationRecorder* debug_info() const { return env()->debug_info(); From gbenson at redhat.com Fri Jun 19 06:00:41 2009 From: gbenson at redhat.com (Gary Benson) Date: Fri, 19 Jun 2009 14:00:41 +0100 Subject: Improve static type information to ldc and ldc_w in Shark Message-ID: <20090619130041.GB3218@redhat.com> Hi all, This commit sets the static type of objects constants loaded by ldc and ldc_w to either java.lang.String or java.lang.Class. Previously the type was set to java.lang.Object. This should improve the scope for the various static type optimizations (checkcast/instanceof elimination, virtual-direct call improvement, etc). Cheers, Gary -- http://gbenson.net/ -------------- next part -------------- diff -r 2bd8742661b3 -r 2861671c8434 ChangeLog --- a/ChangeLog Fri Jun 19 06:03:31 2009 -0400 +++ b/ChangeLog Fri Jun 19 08:48:56 2009 -0400 @@ -1,3 +1,9 @@ +2009-06-19 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkConstant.cpp + (SharkConstant::for_ldc): Set type for object constants. + (SharkConstant::SharkConstant): Updated. + 2009-06-19 Gary Benson * ports/hotspot/src/share/vm/shark/sharkCompiler.hpp diff -r 2bd8742661b3 -r 2861671c8434 ports/hotspot/src/share/vm/shark/sharkConstant.cpp --- a/ports/hotspot/src/share/vm/shark/sharkConstant.cpp Fri Jun 19 06:03:31 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkConstant.cpp Fri Jun 19 08:48:56 2009 -0400 @@ -30,7 +30,16 @@ SharkConstant* SharkConstant::for_ldc(ciBytecodeStream *iter) { - return new SharkConstant(iter->get_constant(), NULL); + ciConstant constant = iter->get_constant(); + 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(); + } + return new SharkConstant(constant, type); } SharkConstant* SharkConstant::for_field(ciBytecodeStream *iter) @@ -97,6 +106,7 @@ // have yet to be created. We need to spot the unloaded // 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. @@ -114,7 +124,7 @@ _value = NULL; _object = object; - _type = type ? type : ciType::make(T_OBJECT); + _type = type; _is_loaded = true; _is_nonzero = true; _is_two_word = false;