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>

     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  */
    26 class SharkFunction;
    27 class SharkNativeWrapper;
    28 class SharkStackWithNormalFrame;
    29 class SharkStackWithNativeFrame;
    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);
    38  protected:
    39   SharkStack(const SharkCompileInvariants* parent)
    40     : SharkCompileInvariants(parent) {}
    42  protected:
    43   void initialize(llvm::Value* method);
    45  protected:
    46   void CreateStackOverflowCheck(llvm::Value* sp);
    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;
    55   // BasicBlock creation
    56  protected:
    57   virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0;
    59   // Interpreter entry point for bailouts
    60  protected:
    61   virtual address interpreter_entry_point() const = 0;
    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   }
    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);
   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   }
   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   }
   141  private:
   142   void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN;
   144   // Our method's frame
   145  private:
   146   llvm::Value* _frame;
   147   int          _extended_frame_size;
   148   int          _stack_slots_offset;
   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   }
   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;
   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   }
   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;
   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   }
   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 };
   232 class SharkStackWithNormalFrame : public SharkStack {
   233   friend class SharkStack;
   235  protected:
   236   SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method);
   238  private:
   239   SharkFunction* _function;
   241  private:
   242   SharkFunction* function() const {
   243     return _function;
   244   }
   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;
   253   // BasicBlock creation
   254  private:
   255   llvm::BasicBlock* CreateBlock(const char* name = "") const;
   257   // Interpreter entry point for bailouts
   258  private:
   259   address interpreter_entry_point() const;
   260 };
   262 class SharkStackWithNativeFrame : public SharkStack {
   263   friend class SharkStack;
   265  protected:
   266   SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method);
   268  private:
   269   SharkNativeWrapper* _wrapper;
   271  private:
   272   SharkNativeWrapper* wrapper() const {
   273     return _wrapper;
   274   }
   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;
   283   // BasicBlock creation
   284  private:
   285   llvm::BasicBlock* CreateBlock(const char* name = "") const;
   287   // Interpreter entry point for bailouts
   288  private:
   289   address interpreter_entry_point() const;
   290 };

mercurial