src/share/vm/shark/sharkStack.hpp

Tue, 18 Jun 2013 12:31:07 -0700

author
johnc
date
Tue, 18 Jun 2013 12:31:07 -0700
changeset 5277
01522ca68fc7
parent 4314
2cd5e15048e6
child 6876
710a3c8b516e
permissions
-rw-r--r--

8015237: Parallelize string table scanning during strong root processing
Summary: Parallelize the scanning of the intern string table by having each GC worker claim a given number of buckets. Changes were also reviewed by Per Liden <per.liden@oracle.com>.
Reviewed-by: tschatzl, stefank, twisti

     1 /*
     2  * Copyright (c) 1999, 2010, 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 #ifndef SHARE_VM_SHARK_SHARKSTACK_HPP
    27 #define SHARE_VM_SHARK_SHARKSTACK_HPP
    29 #include "shark/llvmHeaders.hpp"
    30 #include "shark/sharkInvariants.hpp"
    31 #include "shark/sharkType.hpp"
    33 class SharkFunction;
    34 class SharkNativeWrapper;
    35 class SharkStackWithNormalFrame;
    36 class SharkStackWithNativeFrame;
    38 class SharkStack : public SharkCompileInvariants {
    39  public:
    40   static SharkStack* CreateBuildAndPushFrame(
    41     SharkFunction* function, llvm::Value* method);
    42   static SharkStack* CreateBuildAndPushFrame(
    43     SharkNativeWrapper* wrapper, llvm::Value* method);
    45  protected:
    46   SharkStack(const SharkCompileInvariants* parent)
    47     : SharkCompileInvariants(parent) {}
    49  protected:
    50   void initialize(llvm::Value* method);
    52  protected:
    53   void CreateStackOverflowCheck(llvm::Value* sp);
    55   // Properties of the method being compiled
    56  protected:
    57   virtual int arg_size() const = 0;
    58   virtual int max_locals() const = 0;
    59   virtual int max_stack() const = 0;
    60   virtual int max_monitors() const = 0;
    62   // BasicBlock creation
    63  protected:
    64   virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0;
    66   // Interpreter entry point for bailouts
    67  protected:
    68   virtual address interpreter_entry_point() const = 0;
    70   // Interface with the Zero stack
    71  private:
    72   llvm::Value* zero_stack() const {
    73     return builder()->CreateAddressOfStructEntry(
    74       thread(),
    75       JavaThread::zero_stack_offset(),
    76       SharkType::zeroStack_type(),
    77       "zero_stack");
    78   }
    79   llvm::Value* stack_base() const {
    80     return builder()->CreateValueOfStructEntry(
    81       zero_stack(),
    82       ZeroStack::base_offset(),
    83       SharkType::intptr_type(),
    84       "stack_base");
    85   }
    86   llvm::Value* stack_pointer_addr() const {
    87     return builder()->CreateAddressOfStructEntry(
    88       zero_stack(),
    89       ZeroStack::sp_offset(),
    90       llvm::PointerType::getUnqual(SharkType::intptr_type()),
    91       "stack_pointer_addr");
    92   }
    93   llvm::Value* frame_pointer_addr() const {
    94     return builder()->CreateAddressOfStructEntry(
    95       thread(),
    96       JavaThread::top_zero_frame_offset(),
    97       llvm::PointerType::getUnqual(SharkType::intptr_type()),
    98       "frame_pointer_addr");
    99   }
   101  public:
   102   llvm::LoadInst* CreateLoadStackPointer(const char *name = "") {
   103     return builder()->CreateLoad(stack_pointer_addr(), name);
   104   }
   105   llvm::StoreInst* CreateStoreStackPointer(llvm::Value* value) {
   106     return builder()->CreateStore(value, stack_pointer_addr());
   107   }
   108   llvm::LoadInst* CreateLoadFramePointer(const char *name = "") {
   109     return builder()->CreateLoad(frame_pointer_addr(), name);
   110   }
   111   llvm::StoreInst* CreateStoreFramePointer(llvm::Value* value) {
   112     return builder()->CreateStore(value, frame_pointer_addr());
   113   }
   114   llvm::Value* CreatePopFrame(int result_slots);
   116   // Interface with the frame anchor
   117  private:
   118   llvm::Value* last_Java_sp_addr() const {
   119     return builder()->CreateAddressOfStructEntry(
   120       thread(),
   121       JavaThread::last_Java_sp_offset(),
   122       llvm::PointerType::getUnqual(SharkType::intptr_type()),
   123       "last_Java_sp_addr");
   124   }
   125   llvm::Value* last_Java_fp_addr() const {
   126     return builder()->CreateAddressOfStructEntry(
   127       thread(),
   128       JavaThread::last_Java_fp_offset(),
   129       llvm::PointerType::getUnqual(SharkType::intptr_type()),
   130       "last_Java_fp_addr");
   131   }
   133  public:
   134   void CreateSetLastJavaFrame() {
   135     // Note that whenever _last_Java_sp != NULL other anchor fields
   136     // must be valid.  The profiler apparently depends on this.
   137     NOT_PRODUCT(CreateAssertLastJavaSPIsNull());
   138     builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr());
   139     // XXX There's last_Java_pc as well, but I don't think anything uses it
   140     // Also XXX: should we fence here?  Zero doesn't...
   141     builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr());
   142     // Also also XXX: we could probably cache the sp (and the fp we know??)
   143   }
   144   void CreateResetLastJavaFrame() {
   145     builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr());
   146   }
   148  private:
   149   void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN;
   151   // Our method's frame
   152  private:
   153   llvm::Value* _frame;
   154   int          _extended_frame_size;
   155   int          _stack_slots_offset;
   157  public:
   158   int extended_frame_size() const {
   159     return _extended_frame_size;
   160   }
   161   int oopmap_frame_size() const {
   162     return extended_frame_size() - arg_size();
   163   }
   165   // Offsets of things in the frame
   166  private:
   167   int _monitors_slots_offset;
   168   int _oop_tmp_slot_offset;
   169   int _method_slot_offset;
   170   int _pc_slot_offset;
   171   int _locals_slots_offset;
   173  public:
   174   int stack_slots_offset() const {
   175     return _stack_slots_offset;
   176   }
   177   int oop_tmp_slot_offset() const {
   178     return _oop_tmp_slot_offset;
   179   }
   180   int method_slot_offset() const {
   181     return _method_slot_offset;
   182   }
   183   int pc_slot_offset() const {
   184     return _pc_slot_offset;
   185   }
   186   int locals_slots_offset() const {
   187     return _locals_slots_offset;
   188   }
   189   int monitor_offset(int index) const {
   190     assert(index >= 0 && index < max_monitors(), "invalid monitor index");
   191     return _monitors_slots_offset +
   192       (max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size();
   193   }
   194   int monitor_object_offset(int index) const {
   195     return monitor_offset(index) +
   196       (BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord);
   197   }
   198   int monitor_header_offset(int index) const {
   199     return monitor_offset(index) +
   200       ((BasicObjectLock::lock_offset_in_bytes() +
   201         BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord);
   202   }
   204   // Addresses of things in the frame
   205  public:
   206   llvm::Value* slot_addr(int               offset,
   207                          llvm::Type* type = NULL,
   208                          const char*       name = "") const;
   210   llvm::Value* monitor_addr(int index) const {
   211     return slot_addr(
   212       monitor_offset(index),
   213       SharkType::monitor_type(),
   214       "monitor");
   215   }
   216   llvm::Value* monitor_object_addr(int index) const {
   217     return slot_addr(
   218       monitor_object_offset(index),
   219       SharkType::oop_type(),
   220       "object_addr");
   221   }
   222   llvm::Value* monitor_header_addr(int index) const {
   223     return slot_addr(
   224       monitor_header_offset(index),
   225       SharkType::intptr_type(),
   226       "displaced_header_addr");
   227   }
   229   // oopmap helpers
   230  public:
   231   static int oopmap_slot_munge(int offset) {
   232     return offset << (LogBytesPerWord - LogBytesPerInt);
   233   }
   234   static VMReg slot2reg(int offset) {
   235     return VMRegImpl::stack2reg(oopmap_slot_munge(offset));
   236   }
   237 };
   239 class SharkStackWithNormalFrame : public SharkStack {
   240   friend class SharkStack;
   242  protected:
   243   SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method);
   245  private:
   246   SharkFunction* _function;
   248  private:
   249   SharkFunction* function() const {
   250     return _function;
   251   }
   253   // Properties of the method being compiled
   254  private:
   255   int arg_size() const;
   256   int max_locals() const;
   257   int max_stack() const;
   258   int max_monitors() const;
   260   // BasicBlock creation
   261  private:
   262   llvm::BasicBlock* CreateBlock(const char* name = "") const;
   264   // Interpreter entry point for bailouts
   265  private:
   266   address interpreter_entry_point() const;
   267 };
   269 class SharkStackWithNativeFrame : public SharkStack {
   270   friend class SharkStack;
   272  protected:
   273   SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method);
   275  private:
   276   SharkNativeWrapper* _wrapper;
   278  private:
   279   SharkNativeWrapper* wrapper() const {
   280     return _wrapper;
   281   }
   283   // Properties of the method being compiled
   284  private:
   285   int arg_size() const;
   286   int max_locals() const;
   287   int max_stack() const;
   288   int max_monitors() const;
   290   // BasicBlock creation
   291  private:
   292   llvm::BasicBlock* CreateBlock(const char* name = "") const;
   294   // Interpreter entry point for bailouts
   295  private:
   296   address interpreter_entry_point() const;
   297 };
   299 #endif // SHARE_VM_SHARK_SHARKSTACK_HPP

mercurial