Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp
32285 views
/*1* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.2* Copyright 2008, 2009, 2010 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#ifndef SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP26#define SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP2728#include "ci/ciStreams.hpp"29#include "ci/ciType.hpp"30#include "ci/ciTypeFlow.hpp"31#include "interpreter/bytecodes.hpp"32#include "memory/allocation.hpp"33#include "shark/llvmHeaders.hpp"34#include "shark/sharkBlock.hpp"35#include "shark/sharkBuilder.hpp"36#include "shark/sharkFunction.hpp"37#include "shark/sharkState.hpp"38#include "shark/sharkValue.hpp"3940class SharkTopLevelBlock : public SharkBlock {41public:42SharkTopLevelBlock(SharkFunction* function, ciTypeFlow::Block* ciblock)43: SharkBlock(function),44_function(function),45_ciblock(ciblock),46_entered(false),47_has_trap(false),48_needs_phis(false),49_entry_state(NULL),50_entry_block(NULL) {}5152private:53SharkFunction* _function;54ciTypeFlow::Block* _ciblock;5556public:57SharkFunction* function() const {58return _function;59}60ciTypeFlow::Block* ciblock() const {61return _ciblock;62}6364// Function properties65public:66SharkStack* stack() const {67return function()->stack();68}6970// Typeflow properties71public:72int index() const {73return ciblock()->pre_order();74}75bool is_backedge_copy() const {76return ciblock()->is_backedge_copy();77}78int stack_depth_at_entry() const {79return ciblock()->stack_size();80}81ciType* local_type_at_entry(int index) const {82return ciblock()->local_type_at(index);83}84ciType* stack_type_at_entry(int slot) const {85return ciblock()->stack_type_at(slot);86}87int start() const {88return ciblock()->start();89}90int limit() const {91return ciblock()->limit();92}93bool falls_through() const {94return ciblock()->control() == ciBlock::fall_through_bci;95}96int num_successors() const {97return ciblock()->successors()->length();98}99SharkTopLevelBlock* successor(int index) const {100return function()->block(ciblock()->successors()->at(index)->pre_order());101}102SharkTopLevelBlock* bci_successor(int bci) const;103104// Exceptions105private:106GrowableArray<ciExceptionHandler*>* _exc_handlers;107GrowableArray<SharkTopLevelBlock*>* _exceptions;108109private:110void compute_exceptions();111112private:113int num_exceptions() const {114return _exc_handlers->length();115}116ciExceptionHandler* exc_handler(int index) const {117return _exc_handlers->at(index);118}119SharkTopLevelBlock* exception(int index) const {120return _exceptions->at(index);121}122123// Traps124private:125bool _has_trap;126int _trap_request;127int _trap_bci;128129void set_trap(int trap_request, int trap_bci) {130assert(!has_trap(), "shouldn't have");131_has_trap = true;132_trap_request = trap_request;133_trap_bci = trap_bci;134}135136private:137bool has_trap() {138return _has_trap;139}140int trap_request() {141assert(has_trap(), "should have");142return _trap_request;143}144int trap_bci() {145assert(has_trap(), "should have");146return _trap_bci;147}148149private:150void scan_for_traps();151152private:153bool static_field_ok_in_clinit(ciField* field);154155// Entry state156private:157bool _entered;158bool _needs_phis;159160public:161bool entered() const {162return _entered;163}164bool needs_phis() const {165return _needs_phis;166}167168private:169void enter(SharkTopLevelBlock* predecessor, bool is_exception);170171public:172void enter() {173enter(NULL, false);174}175176private:177SharkState* _entry_state;178179private:180SharkState* entry_state();181182private:183llvm::BasicBlock* _entry_block;184185public:186llvm::BasicBlock* entry_block() const {187return _entry_block;188}189190public:191void initialize();192193public:194void add_incoming(SharkState* incoming_state);195196// Method197public:198llvm::Value* method() {199return current_state()->method();200}201202// Temporary oop storage203public:204void set_oop_tmp(llvm::Value* value) {205assert(value, "value must be non-NULL (will be reset by get_oop_tmp)");206assert(!current_state()->oop_tmp(), "oop_tmp gets and sets must match");207current_state()->set_oop_tmp(value);208}209llvm::Value* get_oop_tmp() {210llvm::Value* value = current_state()->oop_tmp();211assert(value, "oop_tmp gets and sets must match");212current_state()->set_oop_tmp(NULL);213return value;214}215216// Cache and decache217private:218void decache_for_Java_call(ciMethod* callee);219void cache_after_Java_call(ciMethod* callee);220void decache_for_VM_call();221void cache_after_VM_call();222void decache_for_trap();223224// Monitors225private:226int num_monitors() {227return current_state()->num_monitors();228}229int set_num_monitors(int num_monitors) {230current_state()->set_num_monitors(num_monitors);231}232233// Code generation234public:235void emit_IR();236237// Branch helpers238private:239void do_branch(int successor_index);240241// Zero checks242private:243void do_zero_check(SharkValue* value);244void zero_check_value(SharkValue* value, llvm::BasicBlock* continue_block);245246public:247void do_deferred_zero_check(SharkValue* value,248int bci,249SharkState* saved_state,250llvm::BasicBlock* continue_block);251// Exceptions252private:253llvm::Value* pending_exception_address() const {254return builder()->CreateAddressOfStructEntry(255thread(), Thread::pending_exception_offset(),256llvm::PointerType::getUnqual(SharkType::oop_type()),257"pending_exception_addr");258}259llvm::LoadInst* get_pending_exception() const {260return builder()->CreateLoad(261pending_exception_address(), "pending_exception");262}263void clear_pending_exception() const {264builder()->CreateStore(LLVMValue::null(), pending_exception_address());265}266public:267enum ExceptionActionMask {268// The actual bitmasks that things test against269EAM_CHECK = 1, // whether to check for pending exceptions270EAM_HANDLE = 2, // whether to attempt to handle pending exceptions271EAM_MONITOR_FUDGE = 4, // whether the monitor count needs adjusting272273// More convenient values for passing274EX_CHECK_NONE = 0,275EX_CHECK_NO_CATCH = EAM_CHECK,276EX_CHECK_FULL = EAM_CHECK | EAM_HANDLE277};278void check_pending_exception(int action);279void handle_exception(llvm::Value* exception, int action);280void marshal_exception_fast(int num_options);281void marshal_exception_slow(int num_options);282llvm::BasicBlock* handler_for_exception(int index);283284// VM calls285private:286llvm::CallInst* call_vm(llvm::Value* callee,287llvm::Value** args_start,288llvm::Value** args_end,289int exception_action) {290decache_for_VM_call();291stack()->CreateSetLastJavaFrame();292llvm::CallInst *res = builder()->CreateCall(callee, llvm::makeArrayRef(args_start, args_end));293stack()->CreateResetLastJavaFrame();294cache_after_VM_call();295if (exception_action & EAM_CHECK) {296check_pending_exception(exception_action);297current_state()->set_has_safepointed(true);298}299return res;300}301302public:303llvm::CallInst* call_vm(llvm::Value* callee,304int exception_action) {305llvm::Value *args[] = {thread()};306return call_vm(callee, args, args + 1, exception_action);307}308llvm::CallInst* call_vm(llvm::Value* callee,309llvm::Value* arg1,310int exception_action) {311llvm::Value *args[] = {thread(), arg1};312return call_vm(callee, args, args + 2, exception_action);313}314llvm::CallInst* call_vm(llvm::Value* callee,315llvm::Value* arg1,316llvm::Value* arg2,317int exception_action) {318llvm::Value *args[] = {thread(), arg1, arg2};319return call_vm(callee, args, args + 3, exception_action);320}321llvm::CallInst* call_vm(llvm::Value* callee,322llvm::Value* arg1,323llvm::Value* arg2,324llvm::Value* arg3,325int exception_action) {326llvm::Value *args[] = {thread(), arg1, arg2, arg3};327return call_vm(callee, args, args + 4, exception_action);328}329330// VM call oop return handling331private:332llvm::LoadInst* get_vm_result() const {333llvm::Value *addr = builder()->CreateAddressOfStructEntry(334thread(), JavaThread::vm_result_offset(),335llvm::PointerType::getUnqual(SharkType::oop_type()),336"vm_result_addr");337llvm::LoadInst *result = builder()->CreateLoad(addr, "vm_result");338builder()->CreateStore(LLVMValue::null(), addr);339return result;340}341342// Synchronization343private:344void acquire_lock(llvm::Value* lockee, int exception_action);345void release_lock(int exception_action);346347public:348void acquire_method_lock();349350// Bounds checks351private:352void check_bounds(SharkValue* array, SharkValue* index);353354// Safepoints355private:356void maybe_add_safepoint();357void maybe_add_backedge_safepoint();358359// Loop safepoint removal360private:361bool _can_reach_visited;362363bool can_reach(SharkTopLevelBlock* other);364bool can_reach_helper(SharkTopLevelBlock* other);365366// Traps367private:368llvm::BasicBlock* make_trap(int trap_bci, int trap_request);369void do_trap(int trap_request);370371// Returns372private:373void call_register_finalizer(llvm::Value* receiver);374void handle_return(BasicType type, llvm::Value* exception);375376// arraylength377private:378void do_arraylength();379380// *aload and *astore381private:382void do_aload(BasicType basic_type);383void do_astore(BasicType basic_type);384385// *return and athrow386private:387void do_return(BasicType type);388void do_athrow();389390// goto*391private:392void do_goto();393394// jsr* and ret395private:396void do_jsr();397void do_ret();398399// if*400private:401void do_if_helper(llvm::ICmpInst::Predicate p,402llvm::Value* b,403llvm::Value* a,404SharkState* if_taken_state,405SharkState* not_taken_state);406void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a);407408// tableswitch and lookupswitch409private:410void do_switch();411412// invoke*413private:414ciMethod* improve_virtual_call(ciMethod* caller,415ciInstanceKlass* klass,416ciMethod* dest_method,417ciType* receiver_type);418llvm::Value* get_direct_callee(ciMethod* method);419llvm::Value* get_virtual_callee(SharkValue* receiver, int vtable_index);420llvm::Value* get_interface_callee(SharkValue* receiver, ciMethod* method);421422void do_call();423424// checkcast and instanceof425private:426bool static_subtype_check(ciKlass* check_klass, ciKlass* object_klass);427void do_full_instance_check(ciKlass* klass);428void do_trapping_instance_check(ciKlass* klass);429430void do_instance_check();431bool maybe_do_instanceof_if();432433// new and *newarray434private:435void do_new();436void do_newarray();437void do_anewarray();438void do_multianewarray();439440// monitorenter and monitorexit441private:442void do_monitorenter();443void do_monitorexit();444};445446#endif // SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP447448449