src/share/vm/shark/sharkCacheDecache.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 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_SHARKCACHEDECACHE_HPP
    27 #define SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP
    29 #include "ci/ciMethod.hpp"
    30 #include "code/debugInfoRec.hpp"
    31 #include "shark/sharkBuilder.hpp"
    32 #include "shark/sharkFunction.hpp"
    33 #include "shark/sharkStateScanner.hpp"
    35 // Class hierarchy:
    36 // - SharkStateScanner
    37 //   - SharkCacherDecacher
    38 //     - SharkDecacher
    39 //       - SharkJavaCallDecacher
    40 //       - SharkVMCallDecacher
    41 //       - SharkTrapDecacher
    42 //     - SharkCacher
    43 //       - SharkJavaCallCacher
    44 //       - SharkVMCallCacher
    45 //       - SharkFunctionEntryCacher
    46 //         - SharkNormalEntryCacher
    47 //         - SharkOSREntryCacher
    49 class SharkCacherDecacher : public SharkStateScanner {
    50  protected:
    51   SharkCacherDecacher(SharkFunction* function)
    52     : SharkStateScanner(function) {}
    54   // Helper
    55  protected:
    56   static int adjusted_offset(SharkValue* value, int offset) {
    57     if (value->is_two_word())
    58       offset--;
    59     return offset;
    60   }
    61 };
    63 class SharkDecacher : public SharkCacherDecacher {
    64  protected:
    65   SharkDecacher(SharkFunction* function, int bci)
    66     : SharkCacherDecacher(function), _bci(bci) {}
    68  private:
    69   int _bci;
    71  protected:
    72   int bci() const {
    73     return _bci;
    74   }
    76  private:
    77   int                           _pc_offset;
    78   OopMap*                       _oopmap;
    79   GrowableArray<ScopeValue*>*   _exparray;
    80   GrowableArray<MonitorValue*>* _monarray;
    81   GrowableArray<ScopeValue*>*   _locarray;
    83  private:
    84   int pc_offset() const {
    85     return _pc_offset;
    86   }
    87   OopMap* oopmap() const {
    88     return _oopmap;
    89   }
    90   GrowableArray<ScopeValue*>* exparray() const {
    91     return _exparray;
    92   }
    93   GrowableArray<MonitorValue*>* monarray() const {
    94     return _monarray;
    95   }
    96   GrowableArray<ScopeValue*>* locarray() const {
    97     return _locarray;
    98   }
   100   // Callbacks
   101  protected:
   102   void start_frame();
   104   void start_stack(int stack_depth);
   105   void process_stack_slot(int index, SharkValue** value, int offset);
   107   void start_monitors(int num_monitors);
   108   void process_monitor(int index, int box_offset, int obj_offset);
   110   void process_oop_tmp_slot(llvm::Value** value, int offset);
   111   void process_method_slot(llvm::Value** value, int offset);
   112   void process_pc_slot(int offset);
   114   void start_locals();
   115   void process_local_slot(int index, SharkValue** value, int offset);
   117   void end_frame();
   119   // oopmap and debuginfo helpers
   120  private:
   121   static int oopmap_slot_munge(int offset) {
   122     return SharkStack::oopmap_slot_munge(offset);
   123   }
   124   static VMReg slot2reg(int offset) {
   125     return SharkStack::slot2reg(offset);
   126   }
   127   static Location slot2loc(int offset, Location::Type type) {
   128     return Location::new_stk_loc(type, offset * wordSize);
   129   }
   130   static LocationValue* slot2lv(int offset, Location::Type type) {
   131     return new LocationValue(slot2loc(offset, type));
   132   }
   133   static Location::Type location_type(SharkValue** addr, bool maybe_two_word) {
   134     // low addresses this end
   135     //                           Type       32-bit    64-bit
   136     //   ----------------------------------------------------
   137     //   stack[0]    local[3]    jobject    oop       oop
   138     //   stack[1]    local[2]    NULL       normal    lng
   139     //   stack[2]    local[1]    jlong      normal    invalid
   140     //   stack[3]    local[0]    jint       normal    normal
   141     //
   142     // high addresses this end
   144     SharkValue *value = *addr;
   145     if (value) {
   146       if (value->is_jobject())
   147         return Location::oop;
   148 #ifdef _LP64
   149       if (value->is_two_word())
   150         return Location::invalid;
   151 #endif // _LP64
   152       return Location::normal;
   153     }
   154     else {
   155       if (maybe_two_word) {
   156         value = *(addr - 1);
   157         if (value && value->is_two_word()) {
   158 #ifdef _LP64
   159           if (value->is_jlong())
   160             return Location::lng;
   161           if (value->is_jdouble())
   162             return Location::dbl;
   163           ShouldNotReachHere();
   164 #else
   165           return Location::normal;
   166 #endif // _LP64
   167         }
   168       }
   169       return Location::invalid;
   170     }
   171   }
   173   // Stack slot helpers
   174  protected:
   175   virtual bool stack_slot_needs_write(int index, SharkValue* value) = 0;
   176   virtual bool stack_slot_needs_oopmap(int index, SharkValue* value) = 0;
   177   virtual bool stack_slot_needs_debuginfo(int index, SharkValue* value) = 0;
   179   static Location::Type stack_location_type(int index, SharkValue** addr) {
   180     return location_type(addr, *addr == NULL);
   181   }
   183   // Local slot helpers
   184  protected:
   185   virtual bool local_slot_needs_write(int index, SharkValue* value) = 0;
   186   virtual bool local_slot_needs_oopmap(int index, SharkValue* value) = 0;
   187   virtual bool local_slot_needs_debuginfo(int index, SharkValue* value) = 0;
   189   static Location::Type local_location_type(int index, SharkValue** addr) {
   190     return location_type(addr, index > 0);
   191   }
   193   // Writer helper
   194  protected:
   195   void write_value_to_frame(llvm::Type* type,
   196                             llvm::Value*      value,
   197                             int               offset);
   198 };
   200 class SharkJavaCallDecacher : public SharkDecacher {
   201  public:
   202   SharkJavaCallDecacher(SharkFunction* function, int bci, ciMethod* callee)
   203     : SharkDecacher(function, bci), _callee(callee) {}
   205  private:
   206   ciMethod* _callee;
   208  protected:
   209   ciMethod* callee() const {
   210     return _callee;
   211   }
   213   // Stack slot helpers
   214  protected:
   215   bool stack_slot_needs_write(int index, SharkValue* value) {
   216     return value && (index < callee()->arg_size() || value->is_jobject());
   217   }
   218   bool stack_slot_needs_oopmap(int index, SharkValue* value) {
   219     return value && value->is_jobject() && index >= callee()->arg_size();
   220   }
   221   bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
   222     return index >= callee()->arg_size();
   223   }
   225   // Local slot helpers
   226  protected:
   227   bool local_slot_needs_write(int index, SharkValue* value) {
   228     return value && value->is_jobject();
   229   }
   230   bool local_slot_needs_oopmap(int index, SharkValue* value) {
   231     return value && value->is_jobject();
   232   }
   233   bool local_slot_needs_debuginfo(int index, SharkValue* value) {
   234     return true;
   235   }
   236 };
   238 class SharkVMCallDecacher : public SharkDecacher {
   239  public:
   240   SharkVMCallDecacher(SharkFunction* function, int bci)
   241     : SharkDecacher(function, bci) {}
   243   // Stack slot helpers
   244  protected:
   245   bool stack_slot_needs_write(int index, SharkValue* value) {
   246     return value && value->is_jobject();
   247   }
   248   bool stack_slot_needs_oopmap(int index, SharkValue* value) {
   249     return value && value->is_jobject();
   250   }
   251   bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
   252     return true;
   253   }
   255   // Local slot helpers
   256  protected:
   257   bool local_slot_needs_write(int index, SharkValue* value) {
   258     return value && value->is_jobject();
   259   }
   260   bool local_slot_needs_oopmap(int index, SharkValue* value) {
   261     return value && value->is_jobject();
   262   }
   263   bool local_slot_needs_debuginfo(int index, SharkValue* value) {
   264     return true;
   265   }
   266 };
   268 class SharkTrapDecacher : public SharkDecacher {
   269  public:
   270   SharkTrapDecacher(SharkFunction* function, int bci)
   271     : SharkDecacher(function, bci) {}
   273   // Stack slot helpers
   274  protected:
   275   bool stack_slot_needs_write(int index, SharkValue* value) {
   276     return value != NULL;
   277   }
   278   bool stack_slot_needs_oopmap(int index, SharkValue* value) {
   279     return value && value->is_jobject();
   280   }
   281   bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
   282     return true;
   283   }
   285   // Local slot helpers
   286  protected:
   287   bool local_slot_needs_write(int index, SharkValue* value) {
   288     return value != NULL;
   289   }
   290   bool local_slot_needs_oopmap(int index, SharkValue* value) {
   291     return value && value->is_jobject();
   292   }
   293   bool local_slot_needs_debuginfo(int index, SharkValue* value) {
   294     return true;
   295   }
   296 };
   298 class SharkCacher : public SharkCacherDecacher {
   299  protected:
   300   SharkCacher(SharkFunction* function)
   301     : SharkCacherDecacher(function) {}
   303   // Callbacks
   304  protected:
   305   void process_stack_slot(int index, SharkValue** value, int offset);
   307   void process_oop_tmp_slot(llvm::Value** value, int offset);
   308   virtual void process_method_slot(llvm::Value** value, int offset);
   310   virtual void process_local_slot(int index, SharkValue** value, int offset);
   312   // Stack slot helper
   313  protected:
   314   virtual bool stack_slot_needs_read(int index, SharkValue* value) = 0;
   316   // Local slot helper
   317  protected:
   318   virtual bool local_slot_needs_read(int index, SharkValue* value) {
   319     return value && value->is_jobject();
   320   }
   322   // Writer helper
   323  protected:
   324   llvm::Value* read_value_from_frame(llvm::Type* type, int offset);
   325 };
   327 class SharkJavaCallCacher : public SharkCacher {
   328  public:
   329   SharkJavaCallCacher(SharkFunction* function, ciMethod* callee)
   330     : SharkCacher(function), _callee(callee) {}
   332  private:
   333   ciMethod* _callee;
   335  protected:
   336   ciMethod* callee() const {
   337     return _callee;
   338   }
   340   // Stack slot helper
   341  protected:
   342   bool stack_slot_needs_read(int index, SharkValue* value) {
   343     return value && (index < callee()->return_type()->size() ||
   344                      value->is_jobject());
   345   }
   346 };
   348 class SharkVMCallCacher : public SharkCacher {
   349  public:
   350   SharkVMCallCacher(SharkFunction* function)
   351     : SharkCacher(function) {}
   353   // Stack slot helper
   354  protected:
   355   bool stack_slot_needs_read(int index, SharkValue* value) {
   356     return value && value->is_jobject();
   357   }
   358 };
   360 class SharkFunctionEntryCacher : public SharkCacher {
   361  public:
   362   SharkFunctionEntryCacher(SharkFunction* function, llvm::Value* method)
   363     : SharkCacher(function), _method(method) {}
   365  private:
   366   llvm::Value* _method;
   368  private:
   369   llvm::Value* method() const {
   370     return _method;
   371   }
   373   // Method slot callback
   374  protected:
   375   void process_method_slot(llvm::Value** value, int offset);
   377   // Stack slot helper
   378  protected:
   379   bool stack_slot_needs_read(int index, SharkValue* value) {
   380     ShouldNotReachHere(); // entry block shouldn't have stack
   381   }
   383   // Local slot helper
   384  protected:
   385   bool local_slot_needs_read(int index, SharkValue* value) {
   386     return value != NULL;
   387   }
   388 };
   390 class SharkNormalEntryCacher : public SharkFunctionEntryCacher {
   391  public:
   392   SharkNormalEntryCacher(SharkFunction* function, llvm::Value* method)
   393     : SharkFunctionEntryCacher(function, method) {}
   394 };
   396 class SharkOSREntryCacher : public SharkFunctionEntryCacher {
   397  public:
   398   SharkOSREntryCacher(SharkFunction* function,
   399                       llvm::Value*   method,
   400                       llvm::Value*   osr_buf)
   401     : SharkFunctionEntryCacher(function, method),
   402       _osr_buf(
   403         builder()->CreateBitCast(
   404           osr_buf,
   405           llvm::PointerType::getUnqual(
   406             llvm::ArrayType::get(
   407               SharkType::intptr_type(),
   408               max_locals() + max_monitors() * 2)))) {}
   410  private:
   411   llvm::Value* _osr_buf;
   413  private:
   414   llvm::Value* osr_buf() const {
   415     return _osr_buf;
   416   }
   418   // Callbacks
   419  protected:
   420   void process_monitor(int index, int box_offset, int obj_offset);
   421   void process_local_slot(int index, SharkValue** value, int offset);
   423   // Helper
   424  private:
   425   llvm::Value* CreateAddressOfOSRBufEntry(int offset, llvm::Type* type);
   426 };
   428 #endif // SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP

mercurial