src/share/vm/shark/sharkStack.hpp

Wed, 11 Aug 2010 05:51:21 -0700

author
twisti
date
Wed, 11 Aug 2010 05:51:21 -0700
changeset 2047
d2ede61b7a12
child 2314
f95d63e2154a
permissions
-rw-r--r--

6976186: integrate Shark HotSpot changes
Summary: Shark is a JIT compiler for Zero that uses the LLVM compiler infrastructure.
Reviewed-by: kvn, twisti
Contributed-by: Gary Benson <gbenson@redhat.com>

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

mercurial