Tue, 18 Jun 2013 12:31:07 -0700
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