Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/shark/sharkStack.cpp
32285 views
/*1* Copyright (c) 1999, 2012, 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#include "precompiled.hpp"26#include "shark/llvmHeaders.hpp"27#include "shark/sharkFunction.hpp"28#include "shark/sharkNativeWrapper.hpp"29#include "shark/sharkStack.hpp"30#include "shark/sharkType.hpp"3132using namespace llvm;3334void SharkStack::initialize(Value* method) {35bool setup_sp_and_method = (method != NULL);3637int locals_words = max_locals();38int extra_locals = locals_words - arg_size();39int header_words = SharkFrame::header_words;40int monitor_words = max_monitors()*frame::interpreter_frame_monitor_size();41int stack_words = max_stack();42int frame_words = header_words + monitor_words + stack_words;4344_extended_frame_size = frame_words + locals_words;4546// Update the stack pointer47Value *stack_pointer = builder()->CreateSub(48CreateLoadStackPointer(),49LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize));50CreateStackOverflowCheck(stack_pointer);51if (setup_sp_and_method)52CreateStoreStackPointer(stack_pointer);5354// Create the frame55_frame = builder()->CreateIntToPtr(56stack_pointer,57PointerType::getUnqual(58ArrayType::get(SharkType::intptr_type(), extended_frame_size())),59"frame");60int offset = 0;6162// Expression stack63_stack_slots_offset = offset;64offset += stack_words;6566// Monitors67_monitors_slots_offset = offset;68offset += monitor_words;6970// Temporary oop slot71_oop_tmp_slot_offset = offset++;7273// Method pointer74_method_slot_offset = offset++;75if (setup_sp_and_method) {76builder()->CreateStore(77method, slot_addr(method_slot_offset(), SharkType::Method_type()));78}7980// Unextended SP81builder()->CreateStore(stack_pointer, slot_addr(offset++));8283// PC84_pc_slot_offset = offset++;8586// Frame header87builder()->CreateStore(88LLVMValue::intptr_constant(ZeroFrame::SHARK_FRAME), slot_addr(offset++));89Value *fp = slot_addr(offset++);9091// Local variables92_locals_slots_offset = offset;93offset += locals_words;9495// Push the frame96assert(offset == extended_frame_size(), "should do");97builder()->CreateStore(CreateLoadFramePointer(), fp);98CreateStoreFramePointer(99builder()->CreatePtrToInt(fp, SharkType::intptr_type()));100}101102// This function should match ZeroStack::overflow_check103void SharkStack::CreateStackOverflowCheck(Value* sp) {104BasicBlock *zero_ok = CreateBlock("zero_stack_ok");105BasicBlock *overflow = CreateBlock("stack_overflow");106BasicBlock *abi_ok = CreateBlock("abi_stack_ok");107108// Check the Zero stack109builder()->CreateCondBr(110builder()->CreateICmpULT(sp, stack_base()),111overflow, zero_ok);112113// Check the ABI stack114builder()->SetInsertPoint(zero_ok);115Value *stack_top = builder()->CreateSub(116builder()->CreateValueOfStructEntry(117thread(),118Thread::stack_base_offset(),119SharkType::intptr_type(),120"abi_base"),121builder()->CreateValueOfStructEntry(122thread(),123Thread::stack_size_offset(),124SharkType::intptr_type(),125"abi_size"));126Value *free_stack = builder()->CreateSub(127builder()->CreatePtrToInt(128builder()->CreateGetFrameAddress(),129SharkType::intptr_type(),130"abi_sp"),131stack_top);132builder()->CreateCondBr(133builder()->CreateICmpULT(134free_stack,135LLVMValue::intptr_constant(StackShadowPages * os::vm_page_size())),136overflow, abi_ok);137138// Handle overflows139builder()->SetInsertPoint(overflow);140builder()->CreateCall(builder()->throw_StackOverflowError(), thread());141builder()->CreateRet(LLVMValue::jint_constant(0));142143builder()->SetInsertPoint(abi_ok);144}145146Value* SharkStack::CreatePopFrame(int result_slots) {147assert(result_slots >= 0 && result_slots <= 2, "should be");148int locals_to_pop = max_locals() - result_slots;149150Value *fp = CreateLoadFramePointer();151Value *sp = builder()->CreateAdd(152fp,153LLVMValue::intptr_constant((1 + locals_to_pop) * wordSize));154155CreateStoreStackPointer(sp);156CreateStoreFramePointer(157builder()->CreateLoad(158builder()->CreateIntToPtr(159fp, PointerType::getUnqual(SharkType::intptr_type()))));160161return sp;162}163164Value* SharkStack::slot_addr(int offset,165Type* type,166const char* name) const {167bool needs_cast = type && type != SharkType::intptr_type();168169Value* result = builder()->CreateStructGEP(170_frame, offset, needs_cast ? "" : name);171172if (needs_cast) {173result = builder()->CreateBitCast(174result, PointerType::getUnqual(type), name);175}176return result;177}178179// The bits that differentiate stacks with normal and native frames on top180181SharkStack* SharkStack::CreateBuildAndPushFrame(SharkFunction* function,182Value* method) {183return new SharkStackWithNormalFrame(function, method);184}185SharkStack* SharkStack::CreateBuildAndPushFrame(SharkNativeWrapper* wrapper,186Value* method) {187return new SharkStackWithNativeFrame(wrapper, method);188}189190SharkStackWithNormalFrame::SharkStackWithNormalFrame(SharkFunction* function,191Value* method)192: SharkStack(function), _function(function) {193// For normal frames, the stack pointer and the method slot will194// be set during each decache, so it is not necessary to do them195// at the time the frame is created. However, we set them for196// non-PRODUCT builds to make crash dumps easier to understand.197initialize(PRODUCT_ONLY(NULL) NOT_PRODUCT(method));198}199SharkStackWithNativeFrame::SharkStackWithNativeFrame(SharkNativeWrapper* wrp,200Value* method)201: SharkStack(wrp), _wrapper(wrp) {202initialize(method);203}204205int SharkStackWithNormalFrame::arg_size() const {206return function()->arg_size();207}208int SharkStackWithNativeFrame::arg_size() const {209return wrapper()->arg_size();210}211212int SharkStackWithNormalFrame::max_locals() const {213return function()->max_locals();214}215int SharkStackWithNativeFrame::max_locals() const {216return wrapper()->arg_size();217}218219int SharkStackWithNormalFrame::max_stack() const {220return function()->max_stack();221}222int SharkStackWithNativeFrame::max_stack() const {223return 0;224}225226int SharkStackWithNormalFrame::max_monitors() const {227return function()->max_monitors();228}229int SharkStackWithNativeFrame::max_monitors() const {230return wrapper()->is_synchronized() ? 1 : 0;231}232233BasicBlock* SharkStackWithNormalFrame::CreateBlock(const char* name) const {234return function()->CreateBlock(name);235}236BasicBlock* SharkStackWithNativeFrame::CreateBlock(const char* name) const {237return wrapper()->CreateBlock(name);238}239240address SharkStackWithNormalFrame::interpreter_entry_point() const {241return (address) CppInterpreter::normal_entry;242}243address SharkStackWithNativeFrame::interpreter_entry_point() const {244return (address) CppInterpreter::native_entry;245}246247#ifndef PRODUCT248void SharkStack::CreateAssertLastJavaSPIsNull() const {249#ifdef ASSERT250BasicBlock *fail = CreateBlock("assert_failed");251BasicBlock *pass = CreateBlock("assert_ok");252253builder()->CreateCondBr(254builder()->CreateICmpEQ(255builder()->CreateLoad(last_Java_sp_addr()),256LLVMValue::intptr_constant(0)),257pass, fail);258259builder()->SetInsertPoint(fail);260builder()->CreateShouldNotReachHere(__FILE__, __LINE__);261builder()->CreateUnreachable();262263builder()->SetInsertPoint(pass);264#endif // ASSERT265}266#endif // !PRODUCT267268269