1 /* 2 * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. 3 * Copyright 2008, 2009, 2010 Red Hat, Inc. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 class SharkFunction; 27 class SharkNativeWrapper; 28 class SharkStackWithNormalFrame; 29 class SharkStackWithNativeFrame; 30 31 class SharkStack : public SharkCompileInvariants { 32 public: 33 static SharkStack* CreateBuildAndPushFrame( 34 SharkFunction* function, llvm::Value* method); 35 static SharkStack* CreateBuildAndPushFrame( 36 SharkNativeWrapper* wrapper, llvm::Value* method); 37 38 protected: 39 SharkStack(const SharkCompileInvariants* parent) 40 : SharkCompileInvariants(parent) {} 41 42 protected: 43 void initialize(llvm::Value* method); 44 45 protected: 46 void CreateStackOverflowCheck(llvm::Value* sp); 47 48 // Properties of the method being compiled 49 protected: 50 virtual int arg_size() const = 0; 51 virtual int max_locals() const = 0; 52 virtual int max_stack() const = 0; 53 virtual int max_monitors() const = 0; 54 55 // BasicBlock creation 56 protected: 57 virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0; 58 59 // Interpreter entry point for bailouts 60 protected: 61 virtual address interpreter_entry_point() const = 0; 62 63 // Interface with the Zero stack 64 private: 65 llvm::Value* zero_stack() const { 66 return builder()->CreateAddressOfStructEntry( 67 thread(), 68 JavaThread::zero_stack_offset(), 69 SharkType::zeroStack_type(), 70 "zero_stack"); 71 } 72 llvm::Value* stack_base() const { 73 return builder()->CreateValueOfStructEntry( 74 zero_stack(), 75 ZeroStack::base_offset(), 76 SharkType::intptr_type(), 77 "stack_base"); 78 } 79 llvm::Value* stack_pointer_addr() const { 80 return builder()->CreateAddressOfStructEntry( 81 zero_stack(), 82 ZeroStack::sp_offset(), 83 llvm::PointerType::getUnqual(SharkType::intptr_type()), 84 "stack_pointer_addr"); 85 } 86 llvm::Value* frame_pointer_addr() const { 87 return builder()->CreateAddressOfStructEntry( 88 thread(), 89 JavaThread::top_zero_frame_offset(), 90 llvm::PointerType::getUnqual(SharkType::intptr_type()), 91 "frame_pointer_addr"); 92 } 93 94 public: 95 llvm::LoadInst* CreateLoadStackPointer(const char *name = "") { 96 return builder()->CreateLoad(stack_pointer_addr(), name); 97 } 98 llvm::StoreInst* CreateStoreStackPointer(llvm::Value* value) { 99 return builder()->CreateStore(value, stack_pointer_addr()); 100 } 101 llvm::LoadInst* CreateLoadFramePointer(const char *name = "") { 102 return builder()->CreateLoad(frame_pointer_addr(), name); 103 } 104 llvm::StoreInst* CreateStoreFramePointer(llvm::Value* value) { 105 return builder()->CreateStore(value, frame_pointer_addr()); 106 } 107 llvm::Value* CreatePopFrame(int result_slots); 108 109 // Interface with the frame anchor 110 private: 111 llvm::Value* last_Java_sp_addr() const { 112 return builder()->CreateAddressOfStructEntry( 113 thread(), 114 JavaThread::last_Java_sp_offset(), 115 llvm::PointerType::getUnqual(SharkType::intptr_type()), 116 "last_Java_sp_addr"); 117 } 118 llvm::Value* last_Java_fp_addr() const { 119 return builder()->CreateAddressOfStructEntry( 120 thread(), 121 JavaThread::last_Java_fp_offset(), 122 llvm::PointerType::getUnqual(SharkType::intptr_type()), 123 "last_Java_fp_addr"); 124 } 125 126 public: 127 void CreateSetLastJavaFrame() { 128 // Note that whenever _last_Java_sp != NULL other anchor fields 129 // must be valid. The profiler apparently depends on this. 130 NOT_PRODUCT(CreateAssertLastJavaSPIsNull()); 131 builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr()); 132 // XXX There's last_Java_pc as well, but I don't think anything uses it 133 // Also XXX: should we fence here? Zero doesn't... 134 builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr()); 135 // Also also XXX: we could probably cache the sp (and the fp we know??) 136 } 137 void CreateResetLastJavaFrame() { 138 builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr()); 139 } 140 141 private: 142 void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN; 143 144 // Our method's frame 145 private: 146 llvm::Value* _frame; 147 int _extended_frame_size; 148 int _stack_slots_offset; 149 150 public: 151 int extended_frame_size() const { 152 return _extended_frame_size; 153 } 154 int oopmap_frame_size() const { 155 return extended_frame_size() - arg_size(); 156 } 157 158 // Offsets of things in the frame 159 private: 160 int _monitors_slots_offset; 161 int _oop_tmp_slot_offset; 162 int _method_slot_offset; 163 int _pc_slot_offset; 164 int _locals_slots_offset; 165 166 public: 167 int stack_slots_offset() const { 168 return _stack_slots_offset; 169 } 170 int oop_tmp_slot_offset() const { 171 return _oop_tmp_slot_offset; 172 } 173 int method_slot_offset() const { 174 return _method_slot_offset; 175 } 176 int pc_slot_offset() const { 177 return _pc_slot_offset; 178 } 179 int locals_slots_offset() const { 180 return _locals_slots_offset; 181 } 182 int monitor_offset(int index) const { 183 assert(index >= 0 && index < max_monitors(), "invalid monitor index"); 184 return _monitors_slots_offset + 185 (max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size(); 186 } 187 int monitor_object_offset(int index) const { 188 return monitor_offset(index) + 189 (BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord); 190 } 191 int monitor_header_offset(int index) const { 192 return monitor_offset(index) + 193 ((BasicObjectLock::lock_offset_in_bytes() + 194 BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord); 195 } 196 197 // Addresses of things in the frame 198 public: 199 llvm::Value* slot_addr(int offset, 200 const llvm::Type* type = NULL, 201 const char* name = "") const; 202 203 llvm::Value* monitor_addr(int index) const { 204 return slot_addr( 205 monitor_offset(index), 206 SharkType::monitor_type(), 207 "monitor"); 208 } 209 llvm::Value* monitor_object_addr(int index) const { 210 return slot_addr( 211 monitor_object_offset(index), 212 SharkType::oop_type(), 213 "object_addr"); 214 } 215 llvm::Value* monitor_header_addr(int index) const { 216 return slot_addr( 217 monitor_header_offset(index), 218 SharkType::intptr_type(), 219 "displaced_header_addr"); 220 } 221 222 // oopmap helpers 223 public: 224 static int oopmap_slot_munge(int offset) { 225 return offset << (LogBytesPerWord - LogBytesPerInt); 226 } 227 static VMReg slot2reg(int offset) { 228 return VMRegImpl::stack2reg(oopmap_slot_munge(offset)); 229 } 230 }; 231 232 class SharkStackWithNormalFrame : public SharkStack { 233 friend class SharkStack; 234 235 protected: 236 SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method); 237 238 private: 239 SharkFunction* _function; 240 241 private: 242 SharkFunction* function() const { 243 return _function; 244 } 245 246 // Properties of the method being compiled 247 private: 248 int arg_size() const; 249 int max_locals() const; 250 int max_stack() const; 251 int max_monitors() const; 252 253 // BasicBlock creation 254 private: 255 llvm::BasicBlock* CreateBlock(const char* name = "") const; 256 257 // Interpreter entry point for bailouts 258 private: 259 address interpreter_entry_point() const; 260 }; 261 262 class SharkStackWithNativeFrame : public SharkStack { 263 friend class SharkStack; 264 265 protected: 266 SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method); 267 268 private: 269 SharkNativeWrapper* _wrapper; 270 271 private: 272 SharkNativeWrapper* wrapper() const { 273 return _wrapper; 274 } 275 276 // Properties of the method being compiled 277 private: 278 int arg_size() const; 279 int max_locals() const; 280 int max_stack() const; 281 int max_monitors() const; 282 283 // BasicBlock creation 284 private: 285 llvm::BasicBlock* CreateBlock(const char* name = "") const; 286 287 // Interpreter entry point for bailouts 288 private: 289 address interpreter_entry_point() const; 290 };