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

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

mercurial