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

twisti@2047 1 /*
coleenp@4037 2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
twisti@2047 3 * Copyright 2008, 2009 Red Hat, Inc.
twisti@2047 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
twisti@2047 5 *
twisti@2047 6 * This code is free software; you can redistribute it and/or modify it
twisti@2047 7 * under the terms of the GNU General Public License version 2 only, as
twisti@2047 8 * published by the Free Software Foundation.
twisti@2047 9 *
twisti@2047 10 * This code is distributed in the hope that it will be useful, but WITHOUT
twisti@2047 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
twisti@2047 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
twisti@2047 13 * version 2 for more details (a copy is included in the LICENSE file that
twisti@2047 14 * accompanied this code).
twisti@2047 15 *
twisti@2047 16 * You should have received a copy of the GNU General Public License version
twisti@2047 17 * 2 along with this work; if not, write to the Free Software Foundation,
twisti@2047 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
twisti@2047 19 *
twisti@2047 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
twisti@2047 21 * or visit www.oracle.com if you need additional information or have any
twisti@2047 22 * questions.
twisti@2047 23 *
twisti@2047 24 */
twisti@2047 25
stefank@2314 26 #include "precompiled.hpp"
stefank@2314 27 #include "ci/ciMethod.hpp"
stefank@2314 28 #include "code/debugInfoRec.hpp"
stefank@2314 29 #include "shark/llvmValue.hpp"
stefank@2314 30 #include "shark/sharkBuilder.hpp"
stefank@2314 31 #include "shark/sharkCacheDecache.hpp"
stefank@2314 32 #include "shark/sharkFunction.hpp"
stefank@2314 33 #include "shark/sharkState.hpp"
twisti@2047 34
twisti@2047 35 using namespace llvm;
twisti@2047 36
twisti@2047 37 void SharkDecacher::start_frame() {
twisti@2047 38 // Start recording the debug information
twisti@2047 39 _pc_offset = code_buffer()->create_unique_offset();
twisti@2047 40 _oopmap = new OopMap(
twisti@2047 41 oopmap_slot_munge(stack()->oopmap_frame_size()),
twisti@2047 42 oopmap_slot_munge(arg_size()));
twisti@2047 43 debug_info()->add_safepoint(pc_offset(), oopmap());
twisti@2047 44 }
twisti@2047 45
twisti@2047 46 void SharkDecacher::start_stack(int stack_depth) {
twisti@2047 47 // Create the array we'll record our stack slots in
twisti@2047 48 _exparray = new GrowableArray<ScopeValue*>(stack_depth);
twisti@2047 49
twisti@2047 50 // Set the stack pointer
twisti@2047 51 stack()->CreateStoreStackPointer(
twisti@2047 52 builder()->CreatePtrToInt(
twisti@2047 53 stack()->slot_addr(
twisti@2047 54 stack()->stack_slots_offset() + max_stack() - stack_depth),
twisti@2047 55 SharkType::intptr_type()));
twisti@2047 56 }
twisti@2047 57
twisti@2047 58 void SharkDecacher::process_stack_slot(int index,
twisti@2047 59 SharkValue** addr,
twisti@2047 60 int offset) {
twisti@2047 61 SharkValue *value = *addr;
twisti@2047 62
twisti@2047 63 // Write the value to the frame if necessary
twisti@2047 64 if (stack_slot_needs_write(index, value)) {
twisti@2047 65 write_value_to_frame(
twisti@2047 66 SharkType::to_stackType(value->basic_type()),
twisti@2047 67 value->generic_value(),
twisti@2047 68 adjusted_offset(value, offset));
twisti@2047 69 }
twisti@2047 70
twisti@2047 71 // Record the value in the oopmap if necessary
twisti@2047 72 if (stack_slot_needs_oopmap(index, value)) {
twisti@2047 73 oopmap()->set_oop(slot2reg(offset));
twisti@2047 74 }
twisti@2047 75
twisti@2047 76 // Record the value in the debuginfo if necessary
twisti@2047 77 if (stack_slot_needs_debuginfo(index, value)) {
twisti@2047 78 exparray()->append(slot2lv(offset, stack_location_type(index, addr)));
twisti@2047 79 }
twisti@2047 80 }
twisti@2047 81
twisti@2047 82 void SharkDecacher::start_monitors(int num_monitors) {
twisti@2047 83 // Create the array we'll record our monitors in
twisti@2047 84 _monarray = new GrowableArray<MonitorValue*>(num_monitors);
twisti@2047 85 }
twisti@2047 86
twisti@2047 87 void SharkDecacher::process_monitor(int index, int box_offset, int obj_offset) {
twisti@2047 88 oopmap()->set_oop(slot2reg(obj_offset));
twisti@2047 89
twisti@2047 90 monarray()->append(new MonitorValue(
twisti@2047 91 slot2lv (obj_offset, Location::oop),
twisti@2047 92 slot2loc(box_offset, Location::normal)));
twisti@2047 93 }
twisti@2047 94
twisti@2047 95 void SharkDecacher::process_oop_tmp_slot(Value** value, int offset) {
twisti@2047 96 // Decache the temporary oop slot
twisti@2047 97 if (*value) {
twisti@2047 98 write_value_to_frame(
twisti@2047 99 SharkType::oop_type(),
twisti@2047 100 *value,
twisti@2047 101 offset);
twisti@2047 102
twisti@2047 103 oopmap()->set_oop(slot2reg(offset));
twisti@2047 104 }
twisti@2047 105 }
twisti@2047 106
twisti@2047 107 void SharkDecacher::process_method_slot(Value** value, int offset) {
twisti@2047 108 // Decache the method pointer
twisti@2047 109 write_value_to_frame(
twisti@4314 110 SharkType::Method_type(),
twisti@2047 111 *value,
twisti@2047 112 offset);
twisti@2047 113
twisti@2047 114 }
twisti@2047 115
twisti@2047 116 void SharkDecacher::process_pc_slot(int offset) {
twisti@2047 117 // Record the PC
twisti@2047 118 builder()->CreateStore(
twisti@2047 119 builder()->code_buffer_address(pc_offset()),
twisti@2047 120 stack()->slot_addr(offset));
twisti@2047 121 }
twisti@2047 122
twisti@2047 123 void SharkDecacher::start_locals() {
twisti@2047 124 // Create the array we'll record our local variables in
twisti@2047 125 _locarray = new GrowableArray<ScopeValue*>(max_locals());}
twisti@2047 126
twisti@2047 127 void SharkDecacher::process_local_slot(int index,
twisti@2047 128 SharkValue** addr,
twisti@2047 129 int offset) {
twisti@2047 130 SharkValue *value = *addr;
twisti@2047 131
twisti@2047 132 // Write the value to the frame if necessary
twisti@2047 133 if (local_slot_needs_write(index, value)) {
twisti@2047 134 write_value_to_frame(
twisti@2047 135 SharkType::to_stackType(value->basic_type()),
twisti@2047 136 value->generic_value(),
twisti@2047 137 adjusted_offset(value, offset));
twisti@2047 138 }
twisti@2047 139
twisti@2047 140 // Record the value in the oopmap if necessary
twisti@2047 141 if (local_slot_needs_oopmap(index, value)) {
twisti@2047 142 oopmap()->set_oop(slot2reg(offset));
twisti@2047 143 }
twisti@2047 144
twisti@2047 145 // Record the value in the debuginfo if necessary
twisti@2047 146 if (local_slot_needs_debuginfo(index, value)) {
twisti@2047 147 locarray()->append(slot2lv(offset, local_location_type(index, addr)));
twisti@2047 148 }
twisti@2047 149 }
twisti@2047 150
twisti@2047 151 void SharkDecacher::end_frame() {
twisti@2047 152 // Record the scope
twisti@2047 153 debug_info()->describe_scope(
twisti@2047 154 pc_offset(),
twisti@2047 155 target(),
twisti@2047 156 bci(),
twisti@2047 157 true,
twisti@2047 158 false,
twisti@2047 159 false,
twisti@2047 160 debug_info()->create_scope_values(locarray()),
twisti@2047 161 debug_info()->create_scope_values(exparray()),
twisti@2047 162 debug_info()->create_monitor_values(monarray()));
twisti@2047 163
twisti@2047 164 // Finish recording the debug information
twisti@2047 165 debug_info()->end_safepoint(pc_offset());
twisti@2047 166 }
twisti@2047 167
twisti@2047 168 void SharkCacher::process_stack_slot(int index,
twisti@2047 169 SharkValue** addr,
twisti@2047 170 int offset) {
twisti@2047 171 SharkValue *value = *addr;
twisti@2047 172
twisti@2047 173 // Read the value from the frame if necessary
twisti@2047 174 if (stack_slot_needs_read(index, value)) {
twisti@2047 175 *addr = SharkValue::create_generic(
twisti@2047 176 value->type(),
twisti@2047 177 read_value_from_frame(
twisti@2047 178 SharkType::to_stackType(value->basic_type()),
twisti@2047 179 adjusted_offset(value, offset)),
twisti@2047 180 value->zero_checked());
twisti@2047 181 }
twisti@2047 182 }
twisti@2047 183
twisti@2047 184 void SharkOSREntryCacher::process_monitor(int index,
twisti@2047 185 int box_offset,
twisti@2047 186 int obj_offset) {
twisti@2047 187 // Copy the monitor from the OSR buffer to the frame
twisti@2047 188 int src_offset = max_locals() + index * 2;
twisti@2047 189 builder()->CreateStore(
twisti@2047 190 builder()->CreateLoad(
twisti@2047 191 CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())),
twisti@2047 192 stack()->slot_addr(box_offset, SharkType::intptr_type()));
twisti@2047 193 builder()->CreateStore(
twisti@2047 194 builder()->CreateLoad(
twisti@2047 195 CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())),
twisti@2047 196 stack()->slot_addr(obj_offset, SharkType::oop_type()));
twisti@2047 197 }
twisti@2047 198
twisti@2047 199 void SharkCacher::process_oop_tmp_slot(Value** value, int offset) {
twisti@2047 200 // Cache the temporary oop
twisti@2047 201 if (*value)
twisti@2047 202 *value = read_value_from_frame(SharkType::oop_type(), offset);
twisti@2047 203 }
twisti@2047 204
twisti@2047 205 void SharkCacher::process_method_slot(Value** value, int offset) {
twisti@2047 206 // Cache the method pointer
twisti@4314 207 *value = read_value_from_frame(SharkType::Method_type(), offset);
twisti@2047 208 }
twisti@2047 209
twisti@2047 210 void SharkFunctionEntryCacher::process_method_slot(Value** value, int offset) {
twisti@2047 211 // "Cache" the method pointer
twisti@2047 212 *value = method();
twisti@2047 213 }
twisti@2047 214
twisti@2047 215 void SharkCacher::process_local_slot(int index,
twisti@2047 216 SharkValue** addr,
twisti@2047 217 int offset) {
twisti@2047 218 SharkValue *value = *addr;
twisti@2047 219
twisti@2047 220 // Read the value from the frame if necessary
twisti@2047 221 if (local_slot_needs_read(index, value)) {
twisti@2047 222 *addr = SharkValue::create_generic(
twisti@2047 223 value->type(),
twisti@2047 224 read_value_from_frame(
twisti@2047 225 SharkType::to_stackType(value->basic_type()),
twisti@2047 226 adjusted_offset(value, offset)),
twisti@2047 227 value->zero_checked());
twisti@2047 228 }
twisti@2047 229 }
twisti@2047 230
twisti@2047 231 Value* SharkOSREntryCacher::CreateAddressOfOSRBufEntry(int offset,
twisti@4314 232 Type* type) {
twisti@2047 233 Value *result = builder()->CreateStructGEP(osr_buf(), offset);
twisti@2047 234 if (type != SharkType::intptr_type())
twisti@2047 235 result = builder()->CreateBitCast(result, PointerType::getUnqual(type));
twisti@2047 236 return result;
twisti@2047 237 }
twisti@2047 238
twisti@2047 239 void SharkOSREntryCacher::process_local_slot(int index,
twisti@2047 240 SharkValue** addr,
twisti@2047 241 int offset) {
twisti@2047 242 SharkValue *value = *addr;
twisti@2047 243
twisti@2047 244 // Read the value from the OSR buffer if necessary
twisti@2047 245 if (local_slot_needs_read(index, value)) {
twisti@2047 246 *addr = SharkValue::create_generic(
twisti@2047 247 value->type(),
twisti@2047 248 builder()->CreateLoad(
twisti@2047 249 CreateAddressOfOSRBufEntry(
twisti@2047 250 adjusted_offset(value, max_locals() - 1 - index),
twisti@2047 251 SharkType::to_stackType(value->basic_type()))),
twisti@2047 252 value->zero_checked());
twisti@2047 253 }
twisti@2047 254 }
twisti@2047 255
twisti@4314 256 void SharkDecacher::write_value_to_frame(Type* type,
twisti@2047 257 Value* value,
twisti@2047 258 int offset) {
twisti@2047 259 builder()->CreateStore(value, stack()->slot_addr(offset, type));
twisti@2047 260 }
twisti@2047 261
twisti@4314 262 Value* SharkCacher::read_value_from_frame(Type* type, int offset) {
twisti@2047 263 return builder()->CreateLoad(stack()->slot_addr(offset, type));
twisti@2047 264 }

mercurial