Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/shark/sharkFunction.cpp
32285 views
/*1* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.2* Copyright 2008, 2009 Red Hat, Inc.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include "precompiled.hpp"26#include "ci/ciTypeFlow.hpp"27#include "memory/allocation.hpp"28#include "shark/llvmHeaders.hpp"29#include "shark/llvmValue.hpp"30#include "shark/sharkBuilder.hpp"31#include "shark/sharkEntry.hpp"32#include "shark/sharkFunction.hpp"33#include "shark/sharkState.hpp"34#include "shark/sharkTopLevelBlock.hpp"35#include "shark/shark_globals.hpp"36#include "utilities/debug.hpp"3738using namespace llvm;3940void SharkFunction::initialize(const char *name) {41// Create the function42_function = Function::Create(43entry_point_type(),44GlobalVariable::InternalLinkage,45name);4647// Get our arguments48Function::arg_iterator ai = function()->arg_begin();49Argument *method = ai++;50method->setName("method");51Argument *osr_buf = NULL;52if (is_osr()) {53osr_buf = ai++;54osr_buf->setName("osr_buf");55}56Argument *base_pc = ai++;57base_pc->setName("base_pc");58code_buffer()->set_base_pc(base_pc);59Argument *thread = ai++;60thread->setName("thread");61set_thread(thread);6263// Create the list of blocks64set_block_insertion_point(NULL);65_blocks = NEW_RESOURCE_ARRAY(SharkTopLevelBlock*, block_count());66for (int i = 0; i < block_count(); i++) {67ciTypeFlow::Block *b = flow()->pre_order_at(i);6869// Work around a bug in pre_order_at() that does not return70// the correct pre-ordering. If pre_order_at() were correct71// this line could simply be:72// _blocks[i] = new SharkTopLevelBlock(this, b);73_blocks[b->pre_order()] = new SharkTopLevelBlock(this, b);74}7576// Walk the tree from the start block to determine which77// blocks are entered and which blocks require phis78SharkTopLevelBlock *start_block = block(flow()->start_block_num());79if (is_osr() && start_block->stack_depth_at_entry() != 0) {80env()->record_method_not_compilable("can't compile OSR block with incoming stack-depth > 0");81return;82}83assert(start_block->start() == flow()->start_bci(), "blocks out of order");84start_block->enter();8586// Initialize all entered blocks87for (int i = 0; i < block_count(); i++) {88if (block(i)->entered())89block(i)->initialize();90}9192// Create and push our stack frame93set_block_insertion_point(&function()->front());94builder()->SetInsertPoint(CreateBlock());95_stack = SharkStack::CreateBuildAndPushFrame(this, method);9697// Create the entry state98SharkState *entry_state;99if (is_osr()) {100entry_state = new SharkOSREntryState(start_block, method, osr_buf);101102// Free the OSR buffer103builder()->CreateCall(builder()->osr_migration_end(), osr_buf);104}105else {106entry_state = new SharkNormalEntryState(start_block, method);107108// Lock if necessary109if (is_synchronized()) {110SharkTopLevelBlock *locker =111new SharkTopLevelBlock(this, start_block->ciblock());112locker->add_incoming(entry_state);113114set_block_insertion_point(start_block->entry_block());115locker->acquire_method_lock();116117entry_state = locker->current_state();118}119}120121// Transition into the method proper122start_block->add_incoming(entry_state);123builder()->CreateBr(start_block->entry_block());124125// Parse the blocks126for (int i = 0; i < block_count(); i++) {127if (!block(i)->entered())128continue;129130if (i + 1 < block_count())131set_block_insertion_point(block(i + 1)->entry_block());132else133set_block_insertion_point(NULL);134135block(i)->emit_IR();136}137do_deferred_zero_checks();138}139140class DeferredZeroCheck : public SharkTargetInvariants {141public:142DeferredZeroCheck(SharkTopLevelBlock* block, SharkValue* value)143: SharkTargetInvariants(block),144_block(block),145_value(value),146_bci(block->bci()),147_state(block->current_state()->copy()),148_check_block(builder()->GetInsertBlock()),149_continue_block(function()->CreateBlock("not_zero")) {150builder()->SetInsertPoint(continue_block());151}152153private:154SharkTopLevelBlock* _block;155SharkValue* _value;156int _bci;157SharkState* _state;158BasicBlock* _check_block;159BasicBlock* _continue_block;160161public:162SharkTopLevelBlock* block() const {163return _block;164}165SharkValue* value() const {166return _value;167}168int bci() const {169return _bci;170}171SharkState* state() const {172return _state;173}174BasicBlock* check_block() const {175return _check_block;176}177BasicBlock* continue_block() const {178return _continue_block;179}180181public:182SharkFunction* function() const {183return block()->function();184}185186public:187void process() const {188builder()->SetInsertPoint(check_block());189block()->do_deferred_zero_check(value(), bci(), state(), continue_block());190}191};192193void SharkFunction::add_deferred_zero_check(SharkTopLevelBlock* block,194SharkValue* value) {195deferred_zero_checks()->append(new DeferredZeroCheck(block, value));196}197198void SharkFunction::do_deferred_zero_checks() {199for (int i = 0; i < deferred_zero_checks()->length(); i++)200deferred_zero_checks()->at(i)->process();201}202203204