1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/shark/sharkStack.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,299 @@ 1.4 +/* 1.5 + * Copyright (c) 1999, 2010, 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 +#ifndef SHARE_VM_SHARK_SHARKSTACK_HPP 1.30 +#define SHARE_VM_SHARK_SHARKSTACK_HPP 1.31 + 1.32 +#include "shark/llvmHeaders.hpp" 1.33 +#include "shark/sharkInvariants.hpp" 1.34 +#include "shark/sharkType.hpp" 1.35 + 1.36 +class SharkFunction; 1.37 +class SharkNativeWrapper; 1.38 +class SharkStackWithNormalFrame; 1.39 +class SharkStackWithNativeFrame; 1.40 + 1.41 +class SharkStack : public SharkCompileInvariants { 1.42 + public: 1.43 + static SharkStack* CreateBuildAndPushFrame( 1.44 + SharkFunction* function, llvm::Value* method); 1.45 + static SharkStack* CreateBuildAndPushFrame( 1.46 + SharkNativeWrapper* wrapper, llvm::Value* method); 1.47 + 1.48 + protected: 1.49 + SharkStack(const SharkCompileInvariants* parent) 1.50 + : SharkCompileInvariants(parent) {} 1.51 + 1.52 + protected: 1.53 + void initialize(llvm::Value* method); 1.54 + 1.55 + protected: 1.56 + void CreateStackOverflowCheck(llvm::Value* sp); 1.57 + 1.58 + // Properties of the method being compiled 1.59 + protected: 1.60 + virtual int arg_size() const = 0; 1.61 + virtual int max_locals() const = 0; 1.62 + virtual int max_stack() const = 0; 1.63 + virtual int max_monitors() const = 0; 1.64 + 1.65 + // BasicBlock creation 1.66 + protected: 1.67 + virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0; 1.68 + 1.69 + // Interpreter entry point for bailouts 1.70 + protected: 1.71 + virtual address interpreter_entry_point() const = 0; 1.72 + 1.73 + // Interface with the Zero stack 1.74 + private: 1.75 + llvm::Value* zero_stack() const { 1.76 + return builder()->CreateAddressOfStructEntry( 1.77 + thread(), 1.78 + JavaThread::zero_stack_offset(), 1.79 + SharkType::zeroStack_type(), 1.80 + "zero_stack"); 1.81 + } 1.82 + llvm::Value* stack_base() const { 1.83 + return builder()->CreateValueOfStructEntry( 1.84 + zero_stack(), 1.85 + ZeroStack::base_offset(), 1.86 + SharkType::intptr_type(), 1.87 + "stack_base"); 1.88 + } 1.89 + llvm::Value* stack_pointer_addr() const { 1.90 + return builder()->CreateAddressOfStructEntry( 1.91 + zero_stack(), 1.92 + ZeroStack::sp_offset(), 1.93 + llvm::PointerType::getUnqual(SharkType::intptr_type()), 1.94 + "stack_pointer_addr"); 1.95 + } 1.96 + llvm::Value* frame_pointer_addr() const { 1.97 + return builder()->CreateAddressOfStructEntry( 1.98 + thread(), 1.99 + JavaThread::top_zero_frame_offset(), 1.100 + llvm::PointerType::getUnqual(SharkType::intptr_type()), 1.101 + "frame_pointer_addr"); 1.102 + } 1.103 + 1.104 + public: 1.105 + llvm::LoadInst* CreateLoadStackPointer(const char *name = "") { 1.106 + return builder()->CreateLoad(stack_pointer_addr(), name); 1.107 + } 1.108 + llvm::StoreInst* CreateStoreStackPointer(llvm::Value* value) { 1.109 + return builder()->CreateStore(value, stack_pointer_addr()); 1.110 + } 1.111 + llvm::LoadInst* CreateLoadFramePointer(const char *name = "") { 1.112 + return builder()->CreateLoad(frame_pointer_addr(), name); 1.113 + } 1.114 + llvm::StoreInst* CreateStoreFramePointer(llvm::Value* value) { 1.115 + return builder()->CreateStore(value, frame_pointer_addr()); 1.116 + } 1.117 + llvm::Value* CreatePopFrame(int result_slots); 1.118 + 1.119 + // Interface with the frame anchor 1.120 + private: 1.121 + llvm::Value* last_Java_sp_addr() const { 1.122 + return builder()->CreateAddressOfStructEntry( 1.123 + thread(), 1.124 + JavaThread::last_Java_sp_offset(), 1.125 + llvm::PointerType::getUnqual(SharkType::intptr_type()), 1.126 + "last_Java_sp_addr"); 1.127 + } 1.128 + llvm::Value* last_Java_fp_addr() const { 1.129 + return builder()->CreateAddressOfStructEntry( 1.130 + thread(), 1.131 + JavaThread::last_Java_fp_offset(), 1.132 + llvm::PointerType::getUnqual(SharkType::intptr_type()), 1.133 + "last_Java_fp_addr"); 1.134 + } 1.135 + 1.136 + public: 1.137 + void CreateSetLastJavaFrame() { 1.138 + // Note that whenever _last_Java_sp != NULL other anchor fields 1.139 + // must be valid. The profiler apparently depends on this. 1.140 + NOT_PRODUCT(CreateAssertLastJavaSPIsNull()); 1.141 + builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr()); 1.142 + // XXX There's last_Java_pc as well, but I don't think anything uses it 1.143 + // Also XXX: should we fence here? Zero doesn't... 1.144 + builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr()); 1.145 + // Also also XXX: we could probably cache the sp (and the fp we know??) 1.146 + } 1.147 + void CreateResetLastJavaFrame() { 1.148 + builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr()); 1.149 + } 1.150 + 1.151 + private: 1.152 + void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN; 1.153 + 1.154 + // Our method's frame 1.155 + private: 1.156 + llvm::Value* _frame; 1.157 + int _extended_frame_size; 1.158 + int _stack_slots_offset; 1.159 + 1.160 + public: 1.161 + int extended_frame_size() const { 1.162 + return _extended_frame_size; 1.163 + } 1.164 + int oopmap_frame_size() const { 1.165 + return extended_frame_size() - arg_size(); 1.166 + } 1.167 + 1.168 + // Offsets of things in the frame 1.169 + private: 1.170 + int _monitors_slots_offset; 1.171 + int _oop_tmp_slot_offset; 1.172 + int _method_slot_offset; 1.173 + int _pc_slot_offset; 1.174 + int _locals_slots_offset; 1.175 + 1.176 + public: 1.177 + int stack_slots_offset() const { 1.178 + return _stack_slots_offset; 1.179 + } 1.180 + int oop_tmp_slot_offset() const { 1.181 + return _oop_tmp_slot_offset; 1.182 + } 1.183 + int method_slot_offset() const { 1.184 + return _method_slot_offset; 1.185 + } 1.186 + int pc_slot_offset() const { 1.187 + return _pc_slot_offset; 1.188 + } 1.189 + int locals_slots_offset() const { 1.190 + return _locals_slots_offset; 1.191 + } 1.192 + int monitor_offset(int index) const { 1.193 + assert(index >= 0 && index < max_monitors(), "invalid monitor index"); 1.194 + return _monitors_slots_offset + 1.195 + (max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size(); 1.196 + } 1.197 + int monitor_object_offset(int index) const { 1.198 + return monitor_offset(index) + 1.199 + (BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord); 1.200 + } 1.201 + int monitor_header_offset(int index) const { 1.202 + return monitor_offset(index) + 1.203 + ((BasicObjectLock::lock_offset_in_bytes() + 1.204 + BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord); 1.205 + } 1.206 + 1.207 + // Addresses of things in the frame 1.208 + public: 1.209 + llvm::Value* slot_addr(int offset, 1.210 + llvm::Type* type = NULL, 1.211 + const char* name = "") const; 1.212 + 1.213 + llvm::Value* monitor_addr(int index) const { 1.214 + return slot_addr( 1.215 + monitor_offset(index), 1.216 + SharkType::monitor_type(), 1.217 + "monitor"); 1.218 + } 1.219 + llvm::Value* monitor_object_addr(int index) const { 1.220 + return slot_addr( 1.221 + monitor_object_offset(index), 1.222 + SharkType::oop_type(), 1.223 + "object_addr"); 1.224 + } 1.225 + llvm::Value* monitor_header_addr(int index) const { 1.226 + return slot_addr( 1.227 + monitor_header_offset(index), 1.228 + SharkType::intptr_type(), 1.229 + "displaced_header_addr"); 1.230 + } 1.231 + 1.232 + // oopmap helpers 1.233 + public: 1.234 + static int oopmap_slot_munge(int offset) { 1.235 + return offset << (LogBytesPerWord - LogBytesPerInt); 1.236 + } 1.237 + static VMReg slot2reg(int offset) { 1.238 + return VMRegImpl::stack2reg(oopmap_slot_munge(offset)); 1.239 + } 1.240 +}; 1.241 + 1.242 +class SharkStackWithNormalFrame : public SharkStack { 1.243 + friend class SharkStack; 1.244 + 1.245 + protected: 1.246 + SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method); 1.247 + 1.248 + private: 1.249 + SharkFunction* _function; 1.250 + 1.251 + private: 1.252 + SharkFunction* function() const { 1.253 + return _function; 1.254 + } 1.255 + 1.256 + // Properties of the method being compiled 1.257 + private: 1.258 + int arg_size() const; 1.259 + int max_locals() const; 1.260 + int max_stack() const; 1.261 + int max_monitors() const; 1.262 + 1.263 + // BasicBlock creation 1.264 + private: 1.265 + llvm::BasicBlock* CreateBlock(const char* name = "") const; 1.266 + 1.267 + // Interpreter entry point for bailouts 1.268 + private: 1.269 + address interpreter_entry_point() const; 1.270 +}; 1.271 + 1.272 +class SharkStackWithNativeFrame : public SharkStack { 1.273 + friend class SharkStack; 1.274 + 1.275 + protected: 1.276 + SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method); 1.277 + 1.278 + private: 1.279 + SharkNativeWrapper* _wrapper; 1.280 + 1.281 + private: 1.282 + SharkNativeWrapper* wrapper() const { 1.283 + return _wrapper; 1.284 + } 1.285 + 1.286 + // Properties of the method being compiled 1.287 + private: 1.288 + int arg_size() const; 1.289 + int max_locals() const; 1.290 + int max_stack() const; 1.291 + int max_monitors() const; 1.292 + 1.293 + // BasicBlock creation 1.294 + private: 1.295 + llvm::BasicBlock* CreateBlock(const char* name = "") const; 1.296 + 1.297 + // Interpreter entry point for bailouts 1.298 + private: 1.299 + address interpreter_entry_point() const; 1.300 +}; 1.301 + 1.302 +#endif // SHARE_VM_SHARK_SHARKSTACK_HPP