Mercurial > hg > release > icedtea-1.9
view ports/hotspot/src/share/vm/shark/sharkFunction.cpp @ 1754:8ad9d28381c5
2009-03-13 Gary Benson <gbenson@redhat.com>
* ports/hotspot/src/share/vm/shark/sharkState.hpp
(SharkEntryState): Moved from sharkFunction.cpp.
(SharkPHIState): Moved from sharkTopLevelBlock.cpp.
* ports/hotspot/src/share/vm/shark/sharkState.hpp
(SharkEntryState::SharkEntryState): Moved from sharkFunction.cpp.
(SharkPHIState::SharkPHIState): Moved from sharkTopLevelBlock.cpp.
(SharkPHIState::add_incoming): Likewise.
* ports/hotspot/src/share/vm/shark/sharkFunction.cpp
(SharkEntryState): Removed.
* ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
(SharkPHIState): Likewise.
author | Gary Benson <gbenson@redhat.com> |
---|---|
date | Fri, 13 Mar 2009 05:43:37 -0400 |
parents | 1eeb14582f5a |
children |
line wrap: on
line source
/* * 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/_sharkFunction.cpp.incl" #include <fnmatch.h> using namespace llvm; void SharkFunction::initialize() { // Emit the entry point SharkEntry *entry = (SharkEntry *) masm()->pc(); masm()->advance(sizeof(SharkEntry)); // Create the function _function = builder()->CreateFunction(name()); entry->set_llvm_function(function()); compiler()->memory_manager()->set_entry_for_function(function(), entry); // Get our arguments Function::arg_iterator ai = function()->arg_begin(); Argument *method = ai++; method->setName("method"); _base_pc = ai++; _base_pc->setName("base_pc"); _thread = ai++; _thread->setName("thread"); // Create the list of blocks set_block_insertion_point(NULL); _blocks = NEW_RESOURCE_ARRAY(SharkTopLevelBlock*, flow()->block_count()); for (int i = 0; i < block_count(); i++) { ciTypeFlow::Block *b = flow()->pre_order_at(i); // Work around a bug in pre_order_at() that does not return the // correct pre-ordering. If pre_order_at() were correct this // line could simply be: // _blocks[i] = new SharkTopLevelBlock(this, b); _blocks[b->pre_order()] = new SharkTopLevelBlock(this, b); } // Walk the tree from the start block to determine which // blocks are entered and which blocks require phis SharkTopLevelBlock *start_block = block(0); assert(start_block->start() == 0, "blocks out of order"); start_block->enter(); // Initialize all entered blocks for (int i = 0; i < block_count(); i++) { if (block(i)->entered()) block(i)->initialize(); } // Initialize the monitors _monitor_count = 0; if (target()->is_synchronized() || target()->uses_monitors()) { for (int i = 0; i < block_count(); i++) _monitor_count = MAX2( _monitor_count, block(i)->ciblock()->monitor_count()); } // Create the method preamble set_block_insertion_point(&function()->front()); builder()->SetInsertPoint(CreateBlock()); CreateInitZeroStack(); CreatePushFrame(CreateBuildFrame()); NOT_PRODUCT(builder()->CreateStore( method, CreateAddressOfFrameEntry( method_slot_offset(), SharkType::methodOop_type(), "method_slot"))); // Lock if necessary SharkState *entry_state = new SharkEntryState(start_block, method); if (target()->is_synchronized()) { SharkTopLevelBlock *locker = new SharkTopLevelBlock(this, start_block->ciblock()); locker->add_incoming(entry_state); set_block_insertion_point(start_block->entry_block()); locker->acquire_method_lock(); entry_state = locker->current_state(); } // Transition into the method proper start_block->add_incoming(entry_state); builder()->CreateBr(start_block->entry_block()); // Parse the blocks for (int i = 0; i < block_count(); i++) { if (!block(i)->entered()) continue; if (i + 1 < block_count()) set_block_insertion_point(block(i + 1)->entry_block()); else set_block_insertion_point(NULL); block(i)->emit_IR(); } // 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() { Value *zero_stack = builder()->CreateAddressOfStructEntry( thread(), JavaThread::zero_stack_offset(), SharkType::zeroStack_type(), "zero_stack"); _zero_stack_base = builder()->CreateValueOfStructEntry( zero_stack, ZeroStack::base_offset(), SharkType::intptr_type(), "zero_stack_base"); _zero_stack_pointer_addr = builder()->CreateAddressOfStructEntry( zero_stack, ZeroStack::sp_offset(), PointerType::getUnqual(SharkType::intptr_type()), "zero_stack_pointer_addr"); _zero_frame_pointer_addr = builder()->CreateAddressOfStructEntry( thread(), JavaThread::top_zero_frame_offset(), PointerType::getUnqual(SharkType::intptr_type()), "zero_frame_pointer_addr"); } void SharkFunction::CreateStackOverflowCheck(Value *sp) { BasicBlock *overflow = CreateBlock("stack_overflow"); BasicBlock *no_overflow = CreateBlock("no_overflow"); builder()->CreateCondBr( builder()->CreateICmpULT(sp, zero_stack_base()), overflow, no_overflow); builder()->SetInsertPoint(overflow); builder()->CreateUnimplemented(__FILE__, __LINE__); builder()->CreateUnreachable(); builder()->SetInsertPoint(no_overflow); } void SharkFunction::CreatePushFrame(Value *fp) { builder()->CreateStore(CreateLoadZeroFramePointer(), fp); CreateStoreZeroFramePointer( builder()->CreatePtrToInt(fp, SharkType::intptr_type())); } Value* SharkFunction::CreatePopFrame(int result_slots) { assert(result_slots >= 0 && result_slots <= 2, "should be"); int locals_to_pop = max_locals() - result_slots; Value *fp = CreateLoadZeroFramePointer(); Value *sp = builder()->CreateAdd( fp, LLVMValue::intptr_constant((1 + locals_to_pop) * wordSize)); CreateStoreZeroStackPointer(sp); CreateStoreZeroFramePointer( builder()->CreateLoad( builder()->CreateIntToPtr( fp, PointerType::getUnqual(SharkType::intptr_type())))); return sp; } Value* SharkFunction::CreateBuildFrame() { int locals_words = max_locals(); int extra_locals = locals_words - arg_size(); int header_words = SharkFrame::header_words; int monitor_words = monitor_count()*frame::interpreter_frame_monitor_size(); int stack_words = max_stack(); int frame_words = header_words + monitor_words + stack_words; _oopmap_frame_size = frame_words + extra_locals; // Update the stack pointer Value *zero_stack_pointer = builder()->CreateSub( CreateLoadZeroStackPointer(), LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize)); CreateStackOverflowCheck(zero_stack_pointer); NOT_PRODUCT(CreateStoreZeroStackPointer(zero_stack_pointer)); // Create the frame _frame = builder()->CreateIntToPtr( zero_stack_pointer, PointerType::getUnqual( ArrayType::get(SharkType::intptr_type(), frame_words + locals_words)), "frame"); int offset = 0; // Expression stack _stack_slots_offset = offset; offset += stack_words; // Monitors if (monitor_count()) { _monitors_slots_offset = offset; for (int i = 0; i < monitor_count(); i++) { if (i != 0 || !target()->is_synchronized()) monitor(i)->mark_free(); } } offset += monitor_words; // Exception pointer _exception_slot_offset = offset++; builder()->CreateStore(LLVMValue::null(), exception_slot()); // Method pointer _method_slot_offset = offset++; // Unextended SP builder()->CreateStore( zero_stack_pointer, CreateAddressOfFrameEntry(offset++)); // PC _pc_slot_offset = offset++; // Frame header builder()->CreateStore( LLVMValue::intptr_constant(ZeroFrame::SHARK_FRAME), CreateAddressOfFrameEntry(offset++)); Value *fp = CreateAddressOfFrameEntry(offset++); // Local variables _locals_slots_offset = offset; offset += locals_words; assert(offset == frame_words + locals_words, "should do"); return fp; } Value* SharkFunction::CreateAddressOfFrameEntry(int offset, const llvm::Type* type, const char* name) const { bool needs_cast = type && type != SharkType::intptr_type(); Value* result = builder()->CreateStructGEP( _frame, offset, needs_cast ? "" : name); if (needs_cast) { result = builder()->CreateBitCast( result, PointerType::getUnqual(type), name); } return result; } SharkMonitor* SharkFunction::monitor(Value *index) const { Value *indexes[] = { LLVMValue::jint_constant(0), builder()->CreateSub( LLVMValue::jint_constant(monitor_count() - 1), index), }; return new SharkMonitor( this, builder()->CreateGEP(monitors_slots(), indexes, indexes + 2)); }