src/share/vm/shark/sharkCacheDecache.cpp

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, 2012, 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 #include "precompiled.hpp"
    27 #include "ci/ciMethod.hpp"
    28 #include "code/debugInfoRec.hpp"
    29 #include "shark/llvmValue.hpp"
    30 #include "shark/sharkBuilder.hpp"
    31 #include "shark/sharkCacheDecache.hpp"
    32 #include "shark/sharkFunction.hpp"
    33 #include "shark/sharkState.hpp"
    35 using namespace llvm;
    37 void SharkDecacher::start_frame() {
    38   // Start recording the debug information
    39   _pc_offset = code_buffer()->create_unique_offset();
    40   _oopmap = new OopMap(
    41     oopmap_slot_munge(stack()->oopmap_frame_size()),
    42     oopmap_slot_munge(arg_size()));
    43   debug_info()->add_safepoint(pc_offset(), oopmap());
    44 }
    46 void SharkDecacher::start_stack(int stack_depth) {
    47   // Create the array we'll record our stack slots in
    48   _exparray = new GrowableArray<ScopeValue*>(stack_depth);
    50   // Set the stack pointer
    51   stack()->CreateStoreStackPointer(
    52     builder()->CreatePtrToInt(
    53       stack()->slot_addr(
    54         stack()->stack_slots_offset() + max_stack() - stack_depth),
    55       SharkType::intptr_type()));
    56 }
    58 void SharkDecacher::process_stack_slot(int          index,
    59                                        SharkValue** addr,
    60                                        int          offset) {
    61   SharkValue *value = *addr;
    63   // Write the value to the frame if necessary
    64   if (stack_slot_needs_write(index, value)) {
    65     write_value_to_frame(
    66       SharkType::to_stackType(value->basic_type()),
    67       value->generic_value(),
    68       adjusted_offset(value, offset));
    69   }
    71   // Record the value in the oopmap if necessary
    72   if (stack_slot_needs_oopmap(index, value)) {
    73     oopmap()->set_oop(slot2reg(offset));
    74   }
    76   // Record the value in the debuginfo if necessary
    77   if (stack_slot_needs_debuginfo(index, value)) {
    78     exparray()->append(slot2lv(offset, stack_location_type(index, addr)));
    79   }
    80 }
    82 void SharkDecacher::start_monitors(int num_monitors) {
    83   // Create the array we'll record our monitors in
    84   _monarray = new GrowableArray<MonitorValue*>(num_monitors);
    85 }
    87 void SharkDecacher::process_monitor(int index, int box_offset, int obj_offset) {
    88   oopmap()->set_oop(slot2reg(obj_offset));
    90   monarray()->append(new MonitorValue(
    91     slot2lv (obj_offset, Location::oop),
    92     slot2loc(box_offset, Location::normal)));
    93 }
    95 void SharkDecacher::process_oop_tmp_slot(Value** value, int offset) {
    96   // Decache the temporary oop slot
    97   if (*value) {
    98     write_value_to_frame(
    99       SharkType::oop_type(),
   100       *value,
   101       offset);
   103     oopmap()->set_oop(slot2reg(offset));
   104   }
   105 }
   107 void SharkDecacher::process_method_slot(Value** value, int offset) {
   108   // Decache the method pointer
   109   write_value_to_frame(
   110     SharkType::Method_type(),
   111     *value,
   112     offset);
   114 }
   116 void SharkDecacher::process_pc_slot(int offset) {
   117   // Record the PC
   118   builder()->CreateStore(
   119     builder()->code_buffer_address(pc_offset()),
   120     stack()->slot_addr(offset));
   121 }
   123 void SharkDecacher::start_locals() {
   124   // Create the array we'll record our local variables in
   125   _locarray = new GrowableArray<ScopeValue*>(max_locals());}
   127 void SharkDecacher::process_local_slot(int          index,
   128                                        SharkValue** addr,
   129                                        int          offset) {
   130   SharkValue *value = *addr;
   132   // Write the value to the frame if necessary
   133   if (local_slot_needs_write(index, value)) {
   134     write_value_to_frame(
   135       SharkType::to_stackType(value->basic_type()),
   136       value->generic_value(),
   137       adjusted_offset(value, offset));
   138   }
   140   // Record the value in the oopmap if necessary
   141   if (local_slot_needs_oopmap(index, value)) {
   142     oopmap()->set_oop(slot2reg(offset));
   143   }
   145   // Record the value in the debuginfo if necessary
   146   if (local_slot_needs_debuginfo(index, value)) {
   147     locarray()->append(slot2lv(offset, local_location_type(index, addr)));
   148   }
   149 }
   151 void SharkDecacher::end_frame() {
   152   // Record the scope
   153   debug_info()->describe_scope(
   154     pc_offset(),
   155     target(),
   156     bci(),
   157     true,
   158     false,
   159     false,
   160     debug_info()->create_scope_values(locarray()),
   161     debug_info()->create_scope_values(exparray()),
   162     debug_info()->create_monitor_values(monarray()));
   164   // Finish recording the debug information
   165   debug_info()->end_safepoint(pc_offset());
   166 }
   168 void SharkCacher::process_stack_slot(int          index,
   169                                      SharkValue** addr,
   170                                      int          offset) {
   171   SharkValue *value = *addr;
   173   // Read the value from the frame if necessary
   174   if (stack_slot_needs_read(index, value)) {
   175     *addr = SharkValue::create_generic(
   176       value->type(),
   177       read_value_from_frame(
   178         SharkType::to_stackType(value->basic_type()),
   179         adjusted_offset(value, offset)),
   180       value->zero_checked());
   181   }
   182 }
   184 void SharkOSREntryCacher::process_monitor(int index,
   185                                           int box_offset,
   186                                           int obj_offset) {
   187   // Copy the monitor from the OSR buffer to the frame
   188   int src_offset = max_locals() + index * 2;
   189   builder()->CreateStore(
   190     builder()->CreateLoad(
   191       CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())),
   192     stack()->slot_addr(box_offset, SharkType::intptr_type()));
   193   builder()->CreateStore(
   194     builder()->CreateLoad(
   195       CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())),
   196     stack()->slot_addr(obj_offset, SharkType::oop_type()));
   197 }
   199 void SharkCacher::process_oop_tmp_slot(Value** value, int offset) {
   200   // Cache the temporary oop
   201   if (*value)
   202     *value = read_value_from_frame(SharkType::oop_type(), offset);
   203 }
   205 void SharkCacher::process_method_slot(Value** value, int offset) {
   206   // Cache the method pointer
   207   *value = read_value_from_frame(SharkType::Method_type(), offset);
   208 }
   210 void SharkFunctionEntryCacher::process_method_slot(Value** value, int offset) {
   211   // "Cache" the method pointer
   212   *value = method();
   213 }
   215 void SharkCacher::process_local_slot(int          index,
   216                                      SharkValue** addr,
   217                                      int          offset) {
   218   SharkValue *value = *addr;
   220   // Read the value from the frame if necessary
   221   if (local_slot_needs_read(index, value)) {
   222     *addr = SharkValue::create_generic(
   223       value->type(),
   224       read_value_from_frame(
   225         SharkType::to_stackType(value->basic_type()),
   226         adjusted_offset(value, offset)),
   227       value->zero_checked());
   228   }
   229 }
   231 Value* SharkOSREntryCacher::CreateAddressOfOSRBufEntry(int         offset,
   232                                                        Type* type) {
   233   Value *result = builder()->CreateStructGEP(osr_buf(), offset);
   234   if (type != SharkType::intptr_type())
   235     result = builder()->CreateBitCast(result, PointerType::getUnqual(type));
   236   return result;
   237 }
   239 void SharkOSREntryCacher::process_local_slot(int          index,
   240                                              SharkValue** addr,
   241                                              int          offset) {
   242   SharkValue *value = *addr;
   244   // Read the value from the OSR buffer if necessary
   245   if (local_slot_needs_read(index, value)) {
   246     *addr = SharkValue::create_generic(
   247       value->type(),
   248       builder()->CreateLoad(
   249         CreateAddressOfOSRBufEntry(
   250           adjusted_offset(value, max_locals() - 1 - index),
   251           SharkType::to_stackType(value->basic_type()))),
   252       value->zero_checked());
   253   }
   254 }
   256 void SharkDecacher::write_value_to_frame(Type* type,
   257                                          Value*      value,
   258                                          int         offset) {
   259   builder()->CreateStore(value, stack()->slot_addr(offset, type));
   260 }
   262 Value* SharkCacher::read_value_from_frame(Type* type, int offset) {
   263   return builder()->CreateLoad(stack()->slot_addr(offset, type));
   264 }

mercurial