src/share/vm/shark/sharkStack.cpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/shark/sharkStack.cpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,267 @@
     1.4 +/*
     1.5 + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright 2008, 2009, 2010 Red Hat, Inc.
     1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8 + *
     1.9 + * This code is free software; you can redistribute it and/or modify it
    1.10 + * under the terms of the GNU General Public License version 2 only, as
    1.11 + * published by the Free Software Foundation.
    1.12 + *
    1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.16 + * version 2 for more details (a copy is included in the LICENSE file that
    1.17 + * accompanied this code).
    1.18 + *
    1.19 + * You should have received a copy of the GNU General Public License version
    1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.22 + *
    1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.24 + * or visit www.oracle.com if you need additional information or have any
    1.25 + * questions.
    1.26 + *
    1.27 + */
    1.28 +
    1.29 +#include "precompiled.hpp"
    1.30 +#include "shark/llvmHeaders.hpp"
    1.31 +#include "shark/sharkFunction.hpp"
    1.32 +#include "shark/sharkNativeWrapper.hpp"
    1.33 +#include "shark/sharkStack.hpp"
    1.34 +#include "shark/sharkType.hpp"
    1.35 +
    1.36 +using namespace llvm;
    1.37 +
    1.38 +void SharkStack::initialize(Value* method) {
    1.39 +  bool setup_sp_and_method = (method != NULL);
    1.40 +
    1.41 +  int locals_words  = max_locals();
    1.42 +  int extra_locals  = locals_words - arg_size();
    1.43 +  int header_words  = SharkFrame::header_words;
    1.44 +  int monitor_words = max_monitors()*frame::interpreter_frame_monitor_size();
    1.45 +  int stack_words   = max_stack();
    1.46 +  int frame_words   = header_words + monitor_words + stack_words;
    1.47 +
    1.48 +  _extended_frame_size = frame_words + locals_words;
    1.49 +
    1.50 +  // Update the stack pointer
    1.51 +  Value *stack_pointer = builder()->CreateSub(
    1.52 +    CreateLoadStackPointer(),
    1.53 +    LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize));
    1.54 +  CreateStackOverflowCheck(stack_pointer);
    1.55 +  if (setup_sp_and_method)
    1.56 +    CreateStoreStackPointer(stack_pointer);
    1.57 +
    1.58 +  // Create the frame
    1.59 +  _frame = builder()->CreateIntToPtr(
    1.60 +    stack_pointer,
    1.61 +    PointerType::getUnqual(
    1.62 +      ArrayType::get(SharkType::intptr_type(), extended_frame_size())),
    1.63 +    "frame");
    1.64 +  int offset = 0;
    1.65 +
    1.66 +  // Expression stack
    1.67 +  _stack_slots_offset = offset;
    1.68 +  offset += stack_words;
    1.69 +
    1.70 +  // Monitors
    1.71 +  _monitors_slots_offset = offset;
    1.72 +  offset += monitor_words;
    1.73 +
    1.74 +  // Temporary oop slot
    1.75 +  _oop_tmp_slot_offset = offset++;
    1.76 +
    1.77 +  // Method pointer
    1.78 +  _method_slot_offset = offset++;
    1.79 +  if (setup_sp_and_method) {
    1.80 +    builder()->CreateStore(
    1.81 +      method, slot_addr(method_slot_offset(), SharkType::Method_type()));
    1.82 +  }
    1.83 +
    1.84 +  // Unextended SP
    1.85 +  builder()->CreateStore(stack_pointer, slot_addr(offset++));
    1.86 +
    1.87 +  // PC
    1.88 +  _pc_slot_offset = offset++;
    1.89 +
    1.90 +  // Frame header
    1.91 +  builder()->CreateStore(
    1.92 +    LLVMValue::intptr_constant(ZeroFrame::SHARK_FRAME), slot_addr(offset++));
    1.93 +  Value *fp = slot_addr(offset++);
    1.94 +
    1.95 +  // Local variables
    1.96 +  _locals_slots_offset = offset;
    1.97 +  offset += locals_words;
    1.98 +
    1.99 +  // Push the frame
   1.100 +  assert(offset == extended_frame_size(), "should do");
   1.101 +  builder()->CreateStore(CreateLoadFramePointer(), fp);
   1.102 +  CreateStoreFramePointer(
   1.103 +    builder()->CreatePtrToInt(fp, SharkType::intptr_type()));
   1.104 +}
   1.105 +
   1.106 +// This function should match ZeroStack::overflow_check
   1.107 +void SharkStack::CreateStackOverflowCheck(Value* sp) {
   1.108 +  BasicBlock *zero_ok  = CreateBlock("zero_stack_ok");
   1.109 +  BasicBlock *overflow = CreateBlock("stack_overflow");
   1.110 +  BasicBlock *abi_ok   = CreateBlock("abi_stack_ok");
   1.111 +
   1.112 +  // Check the Zero stack
   1.113 +  builder()->CreateCondBr(
   1.114 +    builder()->CreateICmpULT(sp, stack_base()),
   1.115 +    overflow, zero_ok);
   1.116 +
   1.117 +  // Check the ABI stack
   1.118 +  builder()->SetInsertPoint(zero_ok);
   1.119 +  Value *stack_top = builder()->CreateSub(
   1.120 +    builder()->CreateValueOfStructEntry(
   1.121 +      thread(),
   1.122 +      Thread::stack_base_offset(),
   1.123 +      SharkType::intptr_type(),
   1.124 +      "abi_base"),
   1.125 +    builder()->CreateValueOfStructEntry(
   1.126 +      thread(),
   1.127 +      Thread::stack_size_offset(),
   1.128 +      SharkType::intptr_type(),
   1.129 +      "abi_size"));
   1.130 +  Value *free_stack = builder()->CreateSub(
   1.131 +    builder()->CreatePtrToInt(
   1.132 +      builder()->CreateGetFrameAddress(),
   1.133 +      SharkType::intptr_type(),
   1.134 +      "abi_sp"),
   1.135 +    stack_top);
   1.136 +  builder()->CreateCondBr(
   1.137 +    builder()->CreateICmpULT(
   1.138 +      free_stack,
   1.139 +      LLVMValue::intptr_constant(StackShadowPages * os::vm_page_size())),
   1.140 +    overflow, abi_ok);
   1.141 +
   1.142 +  // Handle overflows
   1.143 +  builder()->SetInsertPoint(overflow);
   1.144 +  builder()->CreateCall(builder()->throw_StackOverflowError(), thread());
   1.145 +  builder()->CreateRet(LLVMValue::jint_constant(0));
   1.146 +
   1.147 +  builder()->SetInsertPoint(abi_ok);
   1.148 +}
   1.149 +
   1.150 +Value* SharkStack::CreatePopFrame(int result_slots) {
   1.151 +  assert(result_slots >= 0 && result_slots <= 2, "should be");
   1.152 +  int locals_to_pop = max_locals() - result_slots;
   1.153 +
   1.154 +  Value *fp = CreateLoadFramePointer();
   1.155 +  Value *sp = builder()->CreateAdd(
   1.156 +    fp,
   1.157 +    LLVMValue::intptr_constant((1 + locals_to_pop) * wordSize));
   1.158 +
   1.159 +  CreateStoreStackPointer(sp);
   1.160 +  CreateStoreFramePointer(
   1.161 +    builder()->CreateLoad(
   1.162 +      builder()->CreateIntToPtr(
   1.163 +        fp, PointerType::getUnqual(SharkType::intptr_type()))));
   1.164 +
   1.165 +  return sp;
   1.166 +}
   1.167 +
   1.168 +Value* SharkStack::slot_addr(int         offset,
   1.169 +                             Type* type,
   1.170 +                             const char* name) const {
   1.171 +  bool needs_cast = type && type != SharkType::intptr_type();
   1.172 +
   1.173 +  Value* result = builder()->CreateStructGEP(
   1.174 +    _frame, offset, needs_cast ? "" : name);
   1.175 +
   1.176 +  if (needs_cast) {
   1.177 +    result = builder()->CreateBitCast(
   1.178 +      result, PointerType::getUnqual(type), name);
   1.179 +  }
   1.180 +  return result;
   1.181 +}
   1.182 +
   1.183 +// The bits that differentiate stacks with normal and native frames on top
   1.184 +
   1.185 +SharkStack* SharkStack::CreateBuildAndPushFrame(SharkFunction* function,
   1.186 +                                                Value*         method) {
   1.187 +  return new SharkStackWithNormalFrame(function, method);
   1.188 +}
   1.189 +SharkStack* SharkStack::CreateBuildAndPushFrame(SharkNativeWrapper* wrapper,
   1.190 +                                                Value*              method) {
   1.191 +  return new SharkStackWithNativeFrame(wrapper, method);
   1.192 +}
   1.193 +
   1.194 +SharkStackWithNormalFrame::SharkStackWithNormalFrame(SharkFunction* function,
   1.195 +                                                     Value*         method)
   1.196 +  : SharkStack(function), _function(function) {
   1.197 +  // For normal frames, the stack pointer and the method slot will
   1.198 +  // be set during each decache, so it is not necessary to do them
   1.199 +  // at the time the frame is created.  However, we set them for
   1.200 +  // non-PRODUCT builds to make crash dumps easier to understand.
   1.201 +  initialize(PRODUCT_ONLY(NULL) NOT_PRODUCT(method));
   1.202 +}
   1.203 +SharkStackWithNativeFrame::SharkStackWithNativeFrame(SharkNativeWrapper* wrp,
   1.204 +                                                     Value*              method)
   1.205 +  : SharkStack(wrp), _wrapper(wrp) {
   1.206 +  initialize(method);
   1.207 +}
   1.208 +
   1.209 +int SharkStackWithNormalFrame::arg_size() const {
   1.210 +  return function()->arg_size();
   1.211 +}
   1.212 +int SharkStackWithNativeFrame::arg_size() const {
   1.213 +  return wrapper()->arg_size();
   1.214 +}
   1.215 +
   1.216 +int SharkStackWithNormalFrame::max_locals() const {
   1.217 +  return function()->max_locals();
   1.218 +}
   1.219 +int SharkStackWithNativeFrame::max_locals() const {
   1.220 +  return wrapper()->arg_size();
   1.221 +}
   1.222 +
   1.223 +int SharkStackWithNormalFrame::max_stack() const {
   1.224 +  return function()->max_stack();
   1.225 +}
   1.226 +int SharkStackWithNativeFrame::max_stack() const {
   1.227 +  return 0;
   1.228 +}
   1.229 +
   1.230 +int SharkStackWithNormalFrame::max_monitors() const {
   1.231 +  return function()->max_monitors();
   1.232 +}
   1.233 +int SharkStackWithNativeFrame::max_monitors() const {
   1.234 +  return wrapper()->is_synchronized() ? 1 : 0;
   1.235 +}
   1.236 +
   1.237 +BasicBlock* SharkStackWithNormalFrame::CreateBlock(const char* name) const {
   1.238 +  return function()->CreateBlock(name);
   1.239 +}
   1.240 +BasicBlock* SharkStackWithNativeFrame::CreateBlock(const char* name) const {
   1.241 +  return wrapper()->CreateBlock(name);
   1.242 +}
   1.243 +
   1.244 +address SharkStackWithNormalFrame::interpreter_entry_point() const {
   1.245 +  return (address) CppInterpreter::normal_entry;
   1.246 +}
   1.247 +address SharkStackWithNativeFrame::interpreter_entry_point() const {
   1.248 +  return (address) CppInterpreter::native_entry;
   1.249 +}
   1.250 +
   1.251 +#ifndef PRODUCT
   1.252 +void SharkStack::CreateAssertLastJavaSPIsNull() const {
   1.253 +#ifdef ASSERT
   1.254 +  BasicBlock *fail = CreateBlock("assert_failed");
   1.255 +  BasicBlock *pass = CreateBlock("assert_ok");
   1.256 +
   1.257 +  builder()->CreateCondBr(
   1.258 +    builder()->CreateICmpEQ(
   1.259 +      builder()->CreateLoad(last_Java_sp_addr()),
   1.260 +      LLVMValue::intptr_constant(0)),
   1.261 +    pass, fail);
   1.262 +
   1.263 +  builder()->SetInsertPoint(fail);
   1.264 +  builder()->CreateShouldNotReachHere(__FILE__, __LINE__);
   1.265 +  builder()->CreateUnreachable();
   1.266 +
   1.267 +  builder()->SetInsertPoint(pass);
   1.268 +#endif // ASSERT
   1.269 +}
   1.270 +#endif // !PRODUCT

mercurial