Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/shark/sharkStack.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_SHARKSTACK_HPP26#define SHARE_VM_SHARK_SHARKSTACK_HPP2728#include "shark/llvmHeaders.hpp"29#include "shark/sharkInvariants.hpp"30#include "shark/sharkType.hpp"3132class SharkFunction;33class SharkNativeWrapper;34class SharkStackWithNormalFrame;35class SharkStackWithNativeFrame;3637class SharkStack : public SharkCompileInvariants {38public:39static SharkStack* CreateBuildAndPushFrame(40SharkFunction* function, llvm::Value* method);41static SharkStack* CreateBuildAndPushFrame(42SharkNativeWrapper* wrapper, llvm::Value* method);4344protected:45SharkStack(const SharkCompileInvariants* parent)46: SharkCompileInvariants(parent) {}4748protected:49void initialize(llvm::Value* method);5051protected:52void CreateStackOverflowCheck(llvm::Value* sp);5354// Properties of the method being compiled55protected:56virtual int arg_size() const = 0;57virtual int max_locals() const = 0;58virtual int max_stack() const = 0;59virtual int max_monitors() const = 0;6061// BasicBlock creation62protected:63virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0;6465// Interpreter entry point for bailouts66protected:67virtual address interpreter_entry_point() const = 0;6869// Interface with the Zero stack70private:71llvm::Value* zero_stack() const {72return builder()->CreateAddressOfStructEntry(73thread(),74JavaThread::zero_stack_offset(),75SharkType::zeroStack_type(),76"zero_stack");77}78llvm::Value* stack_base() const {79return builder()->CreateValueOfStructEntry(80zero_stack(),81ZeroStack::base_offset(),82SharkType::intptr_type(),83"stack_base");84}85llvm::Value* stack_pointer_addr() const {86return builder()->CreateAddressOfStructEntry(87zero_stack(),88ZeroStack::sp_offset(),89llvm::PointerType::getUnqual(SharkType::intptr_type()),90"stack_pointer_addr");91}92llvm::Value* frame_pointer_addr() const {93return builder()->CreateAddressOfStructEntry(94thread(),95JavaThread::top_zero_frame_offset(),96llvm::PointerType::getUnqual(SharkType::intptr_type()),97"frame_pointer_addr");98}99100public:101llvm::LoadInst* CreateLoadStackPointer(const char *name = "") {102return builder()->CreateLoad(stack_pointer_addr(), name);103}104llvm::StoreInst* CreateStoreStackPointer(llvm::Value* value) {105return builder()->CreateStore(value, stack_pointer_addr());106}107llvm::LoadInst* CreateLoadFramePointer(const char *name = "") {108return builder()->CreateLoad(frame_pointer_addr(), name);109}110llvm::StoreInst* CreateStoreFramePointer(llvm::Value* value) {111return builder()->CreateStore(value, frame_pointer_addr());112}113llvm::Value* CreatePopFrame(int result_slots);114115// Interface with the frame anchor116private:117llvm::Value* last_Java_sp_addr() const {118return builder()->CreateAddressOfStructEntry(119thread(),120JavaThread::last_Java_sp_offset(),121llvm::PointerType::getUnqual(SharkType::intptr_type()),122"last_Java_sp_addr");123}124llvm::Value* last_Java_fp_addr() const {125return builder()->CreateAddressOfStructEntry(126thread(),127JavaThread::last_Java_fp_offset(),128llvm::PointerType::getUnqual(SharkType::intptr_type()),129"last_Java_fp_addr");130}131132public:133void CreateSetLastJavaFrame() {134// Note that whenever _last_Java_sp != NULL other anchor fields135// must be valid. The profiler apparently depends on this.136NOT_PRODUCT(CreateAssertLastJavaSPIsNull());137builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr());138// XXX There's last_Java_pc as well, but I don't think anything uses it139// Also XXX: should we fence here? Zero doesn't...140builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr());141// Also also XXX: we could probably cache the sp (and the fp we know??)142}143void CreateResetLastJavaFrame() {144builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr());145}146147private:148void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN;149150// Our method's frame151private:152llvm::Value* _frame;153int _extended_frame_size;154int _stack_slots_offset;155156public:157int extended_frame_size() const {158return _extended_frame_size;159}160int oopmap_frame_size() const {161return extended_frame_size() - arg_size();162}163164// Offsets of things in the frame165private:166int _monitors_slots_offset;167int _oop_tmp_slot_offset;168int _method_slot_offset;169int _pc_slot_offset;170int _locals_slots_offset;171172public:173int stack_slots_offset() const {174return _stack_slots_offset;175}176int oop_tmp_slot_offset() const {177return _oop_tmp_slot_offset;178}179int method_slot_offset() const {180return _method_slot_offset;181}182int pc_slot_offset() const {183return _pc_slot_offset;184}185int locals_slots_offset() const {186return _locals_slots_offset;187}188int monitor_offset(int index) const {189assert(index >= 0 && index < max_monitors(), "invalid monitor index");190return _monitors_slots_offset +191(max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size();192}193int monitor_object_offset(int index) const {194return monitor_offset(index) +195(BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord);196}197int monitor_header_offset(int index) const {198return monitor_offset(index) +199((BasicObjectLock::lock_offset_in_bytes() +200BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord);201}202203// Addresses of things in the frame204public:205llvm::Value* slot_addr(int offset,206llvm::Type* type = NULL,207const char* name = "") const;208209llvm::Value* monitor_addr(int index) const {210return slot_addr(211monitor_offset(index),212SharkType::monitor_type(),213"monitor");214}215llvm::Value* monitor_object_addr(int index) const {216return slot_addr(217monitor_object_offset(index),218SharkType::oop_type(),219"object_addr");220}221llvm::Value* monitor_header_addr(int index) const {222return slot_addr(223monitor_header_offset(index),224SharkType::intptr_type(),225"displaced_header_addr");226}227228// oopmap helpers229public:230static int oopmap_slot_munge(int offset) {231return offset << (LogBytesPerWord - LogBytesPerInt);232}233static VMReg slot2reg(int offset) {234return VMRegImpl::stack2reg(oopmap_slot_munge(offset));235}236};237238class SharkStackWithNormalFrame : public SharkStack {239friend class SharkStack;240241protected:242SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method);243244private:245SharkFunction* _function;246247private:248SharkFunction* function() const {249return _function;250}251252// Properties of the method being compiled253private:254int arg_size() const;255int max_locals() const;256int max_stack() const;257int max_monitors() const;258259// BasicBlock creation260private:261llvm::BasicBlock* CreateBlock(const char* name = "") const;262263// Interpreter entry point for bailouts264private:265address interpreter_entry_point() const;266};267268class SharkStackWithNativeFrame : public SharkStack {269friend class SharkStack;270271protected:272SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method);273274private:275SharkNativeWrapper* _wrapper;276277private:278SharkNativeWrapper* wrapper() const {279return _wrapper;280}281282// Properties of the method being compiled283private:284int arg_size() const;285int max_locals() const;286int max_stack() const;287int max_monitors() const;288289// BasicBlock creation290private:291llvm::BasicBlock* CreateBlock(const char* name = "") const;292293// Interpreter entry point for bailouts294private:295address interpreter_entry_point() const;296};297298#endif // SHARE_VM_SHARK_SHARKSTACK_HPP299300301