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 };