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