Mercurial > hg > truffle
annotate src/share/vm/c1/c1_CodeStubs.hpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | da91efe96a93 |
children | db9981fd3124 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_C1_C1_CODESTUBS_HPP |
26 #define SHARE_VM_C1_C1_CODESTUBS_HPP | |
27 | |
28 #include "c1/c1_FrameMap.hpp" | |
29 #include "c1/c1_IR.hpp" | |
30 #include "c1/c1_Instruction.hpp" | |
31 #include "c1/c1_LIR.hpp" | |
32 #include "c1/c1_Runtime1.hpp" | |
33 #include "utilities/array.hpp" | |
34 | |
0 | 35 class CodeEmitInfo; |
36 class LIR_Assembler; | |
37 class LIR_OpVisitState; | |
38 | |
39 // CodeStubs are little 'out-of-line' pieces of code that | |
40 // usually handle slow cases of operations. All code stubs | |
41 // are collected and code is emitted at the end of the | |
42 // nmethod. | |
43 | |
44 class CodeStub: public CompilationResourceObj { | |
45 protected: | |
46 Label _entry; // label at the stub entry point | |
47 Label _continuation; // label where stub continues, if any | |
48 | |
49 public: | |
50 CodeStub() {} | |
51 | |
52 // code generation | |
53 void assert_no_unbound_labels() { assert(!_entry.is_unbound() && !_continuation.is_unbound(), "unbound label"); } | |
54 virtual void emit_code(LIR_Assembler* e) = 0; | |
55 virtual CodeEmitInfo* info() const { return NULL; } | |
56 virtual bool is_exception_throw_stub() const { return false; } | |
57 virtual bool is_range_check_stub() const { return false; } | |
58 virtual bool is_divbyzero_stub() const { return false; } | |
59 #ifndef PRODUCT | |
60 virtual void print_name(outputStream* out) const = 0; | |
61 #endif | |
62 | |
63 // label access | |
64 Label* entry() { return &_entry; } | |
65 Label* continuation() { return &_continuation; } | |
66 // for LIR | |
67 virtual void visit(LIR_OpVisitState* visit) { | |
68 #ifndef PRODUCT | |
69 if (LIRTracePeephole && Verbose) { | |
70 tty->print("no visitor for "); | |
71 print_name(tty); | |
72 tty->cr(); | |
73 } | |
74 #endif | |
75 } | |
76 }; | |
77 | |
78 | |
79 define_array(CodeStubArray, CodeStub*) | |
80 define_stack(_CodeStubList, CodeStubArray) | |
81 | |
82 class CodeStubList: public _CodeStubList { | |
83 public: | |
84 CodeStubList(): _CodeStubList() {} | |
85 | |
86 void append(CodeStub* stub) { | |
87 if (!contains(stub)) { | |
88 _CodeStubList::append(stub); | |
89 } | |
90 } | |
91 }; | |
92 | |
93 class CounterOverflowStub: public CodeStub { | |
94 private: | |
95 CodeEmitInfo* _info; | |
96 int _bci; | |
1783 | 97 LIR_Opr _method; |
0 | 98 |
99 public: | |
1783 | 100 CounterOverflowStub(CodeEmitInfo* info, int bci, LIR_Opr method) : _info(info), _bci(bci), _method(method) { |
0 | 101 } |
102 | |
103 virtual void emit_code(LIR_Assembler* e); | |
104 | |
105 virtual void visit(LIR_OpVisitState* visitor) { | |
106 visitor->do_slow_case(_info); | |
1783 | 107 visitor->do_input(_method); |
0 | 108 } |
109 | |
110 #ifndef PRODUCT | |
111 virtual void print_name(outputStream* out) const { out->print("CounterOverflowStub"); } | |
112 #endif // PRODUCT | |
113 | |
114 }; | |
115 | |
116 class ConversionStub: public CodeStub { | |
117 private: | |
118 Bytecodes::Code _bytecode; | |
119 LIR_Opr _input; | |
120 LIR_Opr _result; | |
121 | |
122 static float float_zero; | |
123 static double double_zero; | |
124 public: | |
125 ConversionStub(Bytecodes::Code bytecode, LIR_Opr input, LIR_Opr result) | |
126 : _bytecode(bytecode), _input(input), _result(result) { | |
127 } | |
128 | |
129 Bytecodes::Code bytecode() { return _bytecode; } | |
130 LIR_Opr input() { return _input; } | |
131 LIR_Opr result() { return _result; } | |
132 | |
133 virtual void emit_code(LIR_Assembler* e); | |
134 virtual void visit(LIR_OpVisitState* visitor) { | |
135 visitor->do_slow_case(); | |
136 visitor->do_input(_input); | |
137 visitor->do_output(_result); | |
138 } | |
139 #ifndef PRODUCT | |
140 virtual void print_name(outputStream* out) const { out->print("ConversionStub"); } | |
141 #endif // PRODUCT | |
142 }; | |
143 | |
144 | |
145 // Throws ArrayIndexOutOfBoundsException by default but can be | |
146 // configured to throw IndexOutOfBoundsException in constructor | |
147 class RangeCheckStub: public CodeStub { | |
148 private: | |
149 CodeEmitInfo* _info; | |
150 LIR_Opr _index; | |
151 bool _throw_index_out_of_bounds_exception; | |
152 | |
153 public: | |
154 RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, bool throw_index_out_of_bounds_exception = false); | |
155 virtual void emit_code(LIR_Assembler* e); | |
156 virtual CodeEmitInfo* info() const { return _info; } | |
157 virtual bool is_exception_throw_stub() const { return true; } | |
158 virtual bool is_range_check_stub() const { return true; } | |
159 virtual void visit(LIR_OpVisitState* visitor) { | |
160 visitor->do_slow_case(_info); | |
161 visitor->do_input(_index); | |
162 } | |
163 #ifndef PRODUCT | |
164 virtual void print_name(outputStream* out) const { out->print("RangeCheckStub"); } | |
165 #endif // PRODUCT | |
166 }; | |
167 | |
168 | |
169 class DivByZeroStub: public CodeStub { | |
170 private: | |
171 CodeEmitInfo* _info; | |
172 int _offset; | |
173 | |
174 public: | |
175 DivByZeroStub(CodeEmitInfo* info) | |
176 : _info(info), _offset(-1) { | |
177 } | |
178 DivByZeroStub(int offset, CodeEmitInfo* info) | |
179 : _info(info), _offset(offset) { | |
180 } | |
181 virtual void emit_code(LIR_Assembler* e); | |
182 virtual CodeEmitInfo* info() const { return _info; } | |
183 virtual bool is_exception_throw_stub() const { return true; } | |
184 virtual bool is_divbyzero_stub() const { return true; } | |
185 virtual void visit(LIR_OpVisitState* visitor) { | |
186 visitor->do_slow_case(_info); | |
187 } | |
188 #ifndef PRODUCT | |
189 virtual void print_name(outputStream* out) const { out->print("DivByZeroStub"); } | |
190 #endif // PRODUCT | |
191 }; | |
192 | |
193 | |
194 class ImplicitNullCheckStub: public CodeStub { | |
195 private: | |
196 CodeEmitInfo* _info; | |
197 int _offset; | |
198 | |
199 public: | |
200 ImplicitNullCheckStub(int offset, CodeEmitInfo* info) | |
201 : _offset(offset), _info(info) { | |
202 } | |
203 virtual void emit_code(LIR_Assembler* e); | |
204 virtual CodeEmitInfo* info() const { return _info; } | |
205 virtual bool is_exception_throw_stub() const { return true; } | |
206 virtual void visit(LIR_OpVisitState* visitor) { | |
207 visitor->do_slow_case(_info); | |
208 } | |
209 #ifndef PRODUCT | |
210 virtual void print_name(outputStream* out) const { out->print("ImplicitNullCheckStub"); } | |
211 #endif // PRODUCT | |
212 }; | |
213 | |
214 | |
215 class NewInstanceStub: public CodeStub { | |
216 private: | |
217 ciInstanceKlass* _klass; | |
218 LIR_Opr _klass_reg; | |
219 LIR_Opr _result; | |
220 CodeEmitInfo* _info; | |
221 Runtime1::StubID _stub_id; | |
222 | |
223 public: | |
224 NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id); | |
225 virtual void emit_code(LIR_Assembler* e); | |
226 virtual CodeEmitInfo* info() const { return _info; } | |
227 virtual void visit(LIR_OpVisitState* visitor) { | |
228 visitor->do_slow_case(_info); | |
229 visitor->do_input(_klass_reg); | |
230 visitor->do_output(_result); | |
231 } | |
232 #ifndef PRODUCT | |
233 virtual void print_name(outputStream* out) const { out->print("NewInstanceStub"); } | |
234 #endif // PRODUCT | |
235 }; | |
236 | |
237 | |
238 class NewTypeArrayStub: public CodeStub { | |
239 private: | |
240 LIR_Opr _klass_reg; | |
241 LIR_Opr _length; | |
242 LIR_Opr _result; | |
243 CodeEmitInfo* _info; | |
244 | |
245 public: | |
246 NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info); | |
247 virtual void emit_code(LIR_Assembler* e); | |
248 virtual CodeEmitInfo* info() const { return _info; } | |
249 virtual void visit(LIR_OpVisitState* visitor) { | |
250 visitor->do_slow_case(_info); | |
251 visitor->do_input(_klass_reg); | |
252 visitor->do_input(_length); | |
253 assert(_result->is_valid(), "must be valid"); visitor->do_output(_result); | |
254 } | |
255 #ifndef PRODUCT | |
256 virtual void print_name(outputStream* out) const { out->print("NewTypeArrayStub"); } | |
257 #endif // PRODUCT | |
258 }; | |
259 | |
260 | |
261 class NewObjectArrayStub: public CodeStub { | |
262 private: | |
263 LIR_Opr _klass_reg; | |
264 LIR_Opr _length; | |
265 LIR_Opr _result; | |
266 CodeEmitInfo* _info; | |
267 | |
268 public: | |
269 NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info); | |
270 virtual void emit_code(LIR_Assembler* e); | |
271 virtual CodeEmitInfo* info() const { return _info; } | |
272 virtual void visit(LIR_OpVisitState* visitor) { | |
273 visitor->do_slow_case(_info); | |
274 visitor->do_input(_klass_reg); | |
275 visitor->do_input(_length); | |
276 assert(_result->is_valid(), "must be valid"); visitor->do_output(_result); | |
277 } | |
278 #ifndef PRODUCT | |
279 virtual void print_name(outputStream* out) const { out->print("NewObjectArrayStub"); } | |
280 #endif // PRODUCT | |
281 }; | |
282 | |
283 | |
284 class MonitorAccessStub: public CodeStub { | |
285 protected: | |
286 LIR_Opr _obj_reg; | |
287 LIR_Opr _lock_reg; | |
288 | |
289 public: | |
290 MonitorAccessStub(LIR_Opr obj_reg, LIR_Opr lock_reg) { | |
291 _obj_reg = obj_reg; | |
292 _lock_reg = lock_reg; | |
293 } | |
294 | |
295 #ifndef PRODUCT | |
296 virtual void print_name(outputStream* out) const { out->print("MonitorAccessStub"); } | |
297 #endif // PRODUCT | |
298 }; | |
299 | |
300 | |
301 class MonitorEnterStub: public MonitorAccessStub { | |
302 private: | |
303 CodeEmitInfo* _info; | |
304 | |
305 public: | |
306 MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info); | |
307 | |
308 virtual void emit_code(LIR_Assembler* e); | |
309 virtual CodeEmitInfo* info() const { return _info; } | |
310 virtual void visit(LIR_OpVisitState* visitor) { | |
311 visitor->do_input(_obj_reg); | |
312 visitor->do_input(_lock_reg); | |
313 visitor->do_slow_case(_info); | |
314 } | |
315 #ifndef PRODUCT | |
316 virtual void print_name(outputStream* out) const { out->print("MonitorEnterStub"); } | |
317 #endif // PRODUCT | |
318 }; | |
319 | |
320 | |
321 class MonitorExitStub: public MonitorAccessStub { | |
322 private: | |
323 bool _compute_lock; | |
324 int _monitor_ix; | |
325 | |
326 public: | |
327 MonitorExitStub(LIR_Opr lock_reg, bool compute_lock, int monitor_ix) | |
328 : MonitorAccessStub(LIR_OprFact::illegalOpr, lock_reg), | |
329 _compute_lock(compute_lock), _monitor_ix(monitor_ix) { } | |
330 virtual void emit_code(LIR_Assembler* e); | |
331 virtual void visit(LIR_OpVisitState* visitor) { | |
332 assert(_obj_reg->is_illegal(), "unused"); | |
333 if (_compute_lock) { | |
334 visitor->do_temp(_lock_reg); | |
335 } else { | |
336 visitor->do_input(_lock_reg); | |
337 } | |
338 } | |
339 #ifndef PRODUCT | |
340 virtual void print_name(outputStream* out) const { out->print("MonitorExitStub"); } | |
341 #endif // PRODUCT | |
342 }; | |
343 | |
344 | |
345 class PatchingStub: public CodeStub { | |
346 public: | |
347 enum PatchID { | |
348 access_field_id, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
349 load_klass_id, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
350 load_mirror_id |
0 | 351 }; |
352 enum constants { | |
353 patch_info_size = 3 | |
354 }; | |
355 private: | |
356 PatchID _id; | |
357 address _pc_start; | |
358 int _bytes_to_copy; | |
359 Label _patched_code_entry; | |
360 Label _patch_site_entry; | |
361 Label _patch_site_continuation; | |
362 Register _obj; | |
363 CodeEmitInfo* _info; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
364 int _index; // index of the patchable oop or Klass* in nmethod oop or metadata table if needed |
0 | 365 static int _patch_info_offset; |
366 | |
367 void align_patch_site(MacroAssembler* masm); | |
368 | |
369 public: | |
370 static int patch_info_offset() { return _patch_info_offset; } | |
371 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
372 PatchingStub(MacroAssembler* masm, PatchID id, int index = -1): |
0 | 373 _id(id) |
374 , _info(NULL) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
375 , _index(index) { |
0 | 376 if (os::is_MP()) { |
377 // force alignment of patch sites on MP hardware so we | |
378 // can guarantee atomic writes to the patch site. | |
379 align_patch_site(masm); | |
380 } | |
381 _pc_start = masm->pc(); | |
382 masm->bind(_patch_site_entry); | |
383 } | |
384 | |
385 void install(MacroAssembler* masm, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) { | |
386 _info = info; | |
387 _obj = obj; | |
388 masm->bind(_patch_site_continuation); | |
389 _bytes_to_copy = masm->pc() - pc_start(); | |
390 if (_id == PatchingStub::access_field_id) { | |
391 // embed a fixed offset to handle long patches which need to be offset by a word. | |
392 // the patching code will just add the field offset field to this offset so | |
393 // that we can refernce either the high or low word of a double word field. | |
394 int field_offset = 0; | |
395 switch (patch_code) { | |
396 case lir_patch_low: field_offset = lo_word_offset_in_bytes; break; | |
397 case lir_patch_high: field_offset = hi_word_offset_in_bytes; break; | |
398 case lir_patch_normal: field_offset = 0; break; | |
399 default: ShouldNotReachHere(); | |
400 } | |
401 NativeMovRegMem* n_move = nativeMovRegMem_at(pc_start()); | |
402 n_move->set_offset(field_offset); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
403 } else if (_id == load_klass_id || _id == load_mirror_id) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
404 assert(_obj != noreg, "must have register object for load_klass/load_mirror"); |
0 | 405 #ifdef ASSERT |
406 // verify that we're pointing at a NativeMovConstReg | |
407 nativeMovConstReg_at(pc_start()); | |
408 #endif | |
409 } else { | |
410 ShouldNotReachHere(); | |
411 } | |
412 assert(_bytes_to_copy <= (masm->pc() - pc_start()), "not enough bytes"); | |
413 } | |
414 | |
415 address pc_start() const { return _pc_start; } | |
416 PatchID id() const { return _id; } | |
417 | |
418 virtual void emit_code(LIR_Assembler* e); | |
419 virtual CodeEmitInfo* info() const { return _info; } | |
420 virtual void visit(LIR_OpVisitState* visitor) { | |
421 visitor->do_slow_case(_info); | |
422 } | |
423 #ifndef PRODUCT | |
424 virtual void print_name(outputStream* out) const { out->print("PatchingStub"); } | |
425 #endif // PRODUCT | |
426 }; | |
427 | |
428 | |
1295 | 429 //------------------------------------------------------------------------------ |
430 // DeoptimizeStub | |
431 // | |
432 class DeoptimizeStub : public CodeStub { | |
433 private: | |
434 CodeEmitInfo* _info; | |
435 | |
436 public: | |
437 DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {} | |
438 | |
439 virtual void emit_code(LIR_Assembler* e); | |
440 virtual CodeEmitInfo* info() const { return _info; } | |
441 virtual bool is_exception_throw_stub() const { return true; } | |
442 virtual void visit(LIR_OpVisitState* visitor) { | |
443 visitor->do_slow_case(_info); | |
444 } | |
445 #ifndef PRODUCT | |
446 virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); } | |
447 #endif // PRODUCT | |
448 }; | |
449 | |
450 | |
0 | 451 class SimpleExceptionStub: public CodeStub { |
452 private: | |
453 LIR_Opr _obj; | |
454 Runtime1::StubID _stub; | |
455 CodeEmitInfo* _info; | |
456 | |
457 public: | |
458 SimpleExceptionStub(Runtime1::StubID stub, LIR_Opr obj, CodeEmitInfo* info): | |
459 _obj(obj), _info(info), _stub(stub) { | |
460 } | |
461 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
462 void set_obj(LIR_Opr obj) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
463 _obj = obj; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
464 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
465 |
0 | 466 virtual void emit_code(LIR_Assembler* e); |
467 virtual CodeEmitInfo* info() const { return _info; } | |
468 virtual bool is_exception_throw_stub() const { return true; } | |
469 virtual void visit(LIR_OpVisitState* visitor) { | |
470 if (_obj->is_valid()) visitor->do_input(_obj); | |
471 visitor->do_slow_case(_info); | |
472 } | |
473 #ifndef PRODUCT | |
474 virtual void print_name(outputStream* out) const { out->print("SimpleExceptionStub"); } | |
475 #endif // PRODUCT | |
476 }; | |
477 | |
478 | |
479 | |
2168
e4fee0bdaa85
7008809: should report the class in ArrayStoreExceptions from compiled code
never
parents:
1972
diff
changeset
|
480 class ArrayStoreExceptionStub: public SimpleExceptionStub { |
0 | 481 private: |
482 CodeEmitInfo* _info; | |
483 | |
484 public: | |
2168
e4fee0bdaa85
7008809: should report the class in ArrayStoreExceptions from compiled code
never
parents:
1972
diff
changeset
|
485 ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, info) {} |
0 | 486 #ifndef PRODUCT |
487 virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); } | |
488 #endif // PRODUCT | |
489 }; | |
490 | |
491 | |
492 class ArrayCopyStub: public CodeStub { | |
493 private: | |
494 LIR_OpArrayCopy* _op; | |
495 | |
496 public: | |
497 ArrayCopyStub(LIR_OpArrayCopy* op): _op(op) { } | |
498 | |
499 LIR_Opr src() const { return _op->src(); } | |
500 LIR_Opr src_pos() const { return _op->src_pos(); } | |
501 LIR_Opr dst() const { return _op->dst(); } | |
502 LIR_Opr dst_pos() const { return _op->dst_pos(); } | |
503 LIR_Opr length() const { return _op->length(); } | |
504 LIR_Opr tmp() const { return _op->tmp(); } | |
505 | |
506 virtual void emit_code(LIR_Assembler* e); | |
507 virtual CodeEmitInfo* info() const { return _op->info(); } | |
508 virtual void visit(LIR_OpVisitState* visitor) { | |
509 // don't pass in the code emit info since it's processed in the fast path | |
510 visitor->do_slow_case(); | |
511 } | |
512 #ifndef PRODUCT | |
513 virtual void print_name(outputStream* out) const { out->print("ArrayCopyStub"); } | |
514 #endif // PRODUCT | |
515 }; | |
342 | 516 |
517 ////////////////////////////////////////////////////////////////////////////////////////// | |
518 #ifndef SERIALGC | |
519 | |
520 // Code stubs for Garbage-First barriers. | |
521 class G1PreBarrierStub: public CodeStub { | |
522 private: | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
523 bool _do_load; |
342 | 524 LIR_Opr _addr; |
525 LIR_Opr _pre_val; | |
526 LIR_PatchCode _patch_code; | |
527 CodeEmitInfo* _info; | |
528 | |
529 public: | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
530 // Version that _does_ generate a load of the previous value from addr. |
342 | 531 // addr (the address of the field to be read) must be a LIR_Address |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
532 // pre_val (a temporary register) must be a register; |
342 | 533 G1PreBarrierStub(LIR_Opr addr, LIR_Opr pre_val, LIR_PatchCode patch_code, CodeEmitInfo* info) : |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
534 _addr(addr), _pre_val(pre_val), _do_load(true), |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
535 _patch_code(patch_code), _info(info) |
342 | 536 { |
537 assert(_pre_val->is_register(), "should be temporary register"); | |
538 assert(_addr->is_address(), "should be the address of the field"); | |
539 } | |
540 | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
541 // Version that _does not_ generate load of the previous value; the |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
542 // previous value is assumed to have already been loaded into pre_val. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
543 G1PreBarrierStub(LIR_Opr pre_val) : |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
544 _addr(LIR_OprFact::illegalOpr), _pre_val(pre_val), _do_load(false), |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
545 _patch_code(lir_patch_none), _info(NULL) |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
546 { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
547 assert(_pre_val->is_register(), "should be a register"); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
548 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
549 |
342 | 550 LIR_Opr addr() const { return _addr; } |
551 LIR_Opr pre_val() const { return _pre_val; } | |
552 LIR_PatchCode patch_code() const { return _patch_code; } | |
553 CodeEmitInfo* info() const { return _info; } | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
554 bool do_load() const { return _do_load; } |
342 | 555 |
556 virtual void emit_code(LIR_Assembler* e); | |
557 virtual void visit(LIR_OpVisitState* visitor) { | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
558 if (_do_load) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
559 // don't pass in the code emit info since it's processed in the fast |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
560 // path |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
561 if (_info != NULL) |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
562 visitor->do_slow_case(_info); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
563 else |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
564 visitor->do_slow_case(); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
565 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
566 visitor->do_input(_addr); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
567 visitor->do_temp(_pre_val); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
568 } else { |
342 | 569 visitor->do_slow_case(); |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
570 visitor->do_input(_pre_val); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
571 } |
342 | 572 } |
573 #ifndef PRODUCT | |
574 virtual void print_name(outputStream* out) const { out->print("G1PreBarrierStub"); } | |
575 #endif // PRODUCT | |
576 }; | |
577 | |
578 class G1PostBarrierStub: public CodeStub { | |
579 private: | |
580 LIR_Opr _addr; | |
581 LIR_Opr _new_val; | |
582 | |
583 static jbyte* _byte_map_base; | |
584 static jbyte* byte_map_base_slow(); | |
585 static jbyte* byte_map_base() { | |
586 if (_byte_map_base == NULL) { | |
587 _byte_map_base = byte_map_base_slow(); | |
588 } | |
589 return _byte_map_base; | |
590 } | |
591 | |
592 public: | |
593 // addr (the address of the object head) and new_val must be registers. | |
594 G1PostBarrierStub(LIR_Opr addr, LIR_Opr new_val): _addr(addr), _new_val(new_val) { } | |
595 | |
596 LIR_Opr addr() const { return _addr; } | |
597 LIR_Opr new_val() const { return _new_val; } | |
598 | |
599 virtual void emit_code(LIR_Assembler* e); | |
600 virtual void visit(LIR_OpVisitState* visitor) { | |
601 // don't pass in the code emit info since it's processed in the fast path | |
602 visitor->do_slow_case(); | |
603 visitor->do_input(_addr); | |
604 visitor->do_input(_new_val); | |
605 } | |
606 #ifndef PRODUCT | |
607 virtual void print_name(outputStream* out) const { out->print("G1PostBarrierStub"); } | |
608 #endif // PRODUCT | |
609 }; | |
610 | |
611 #endif // SERIALGC | |
612 ////////////////////////////////////////////////////////////////////////////////////////// | |
1972 | 613 |
614 #endif // SHARE_VM_C1_C1_CODESTUBS_HPP |