Mercurial > hg > truffle
annotate src/share/vm/c1/c1_CodeStubs.hpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 55fb97c4c58d |
children | 4ca6dc0799b6 |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
12160
diff
changeset
|
2 * Copyright (c) 1999, 2013, 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" | |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
6725
diff
changeset
|
34 #include "utilities/macros.hpp" |
1972 | 35 |
0 | 36 class CodeEmitInfo; |
37 class LIR_Assembler; | |
38 class LIR_OpVisitState; | |
39 | |
40 // CodeStubs are little 'out-of-line' pieces of code that | |
41 // usually handle slow cases of operations. All code stubs | |
42 // are collected and code is emitted at the end of the | |
43 // nmethod. | |
44 | |
45 class CodeStub: public CompilationResourceObj { | |
46 protected: | |
47 Label _entry; // label at the stub entry point | |
48 Label _continuation; // label where stub continues, if any | |
49 | |
50 public: | |
51 CodeStub() {} | |
52 | |
53 // code generation | |
54 void assert_no_unbound_labels() { assert(!_entry.is_unbound() && !_continuation.is_unbound(), "unbound label"); } | |
55 virtual void emit_code(LIR_Assembler* e) = 0; | |
56 virtual CodeEmitInfo* info() const { return NULL; } | |
57 virtual bool is_exception_throw_stub() const { return false; } | |
58 virtual bool is_range_check_stub() const { return false; } | |
59 virtual bool is_divbyzero_stub() const { return false; } | |
60 #ifndef PRODUCT | |
61 virtual void print_name(outputStream* out) const = 0; | |
62 #endif | |
63 | |
64 // label access | |
65 Label* entry() { return &_entry; } | |
66 Label* continuation() { return &_continuation; } | |
67 // for LIR | |
68 virtual void visit(LIR_OpVisitState* visit) { | |
69 #ifndef PRODUCT | |
70 if (LIRTracePeephole && Verbose) { | |
71 tty->print("no visitor for "); | |
72 print_name(tty); | |
73 tty->cr(); | |
74 } | |
75 #endif | |
76 } | |
77 }; | |
78 | |
79 | |
80 define_array(CodeStubArray, CodeStub*) | |
81 define_stack(_CodeStubList, CodeStubArray) | |
82 | |
83 class CodeStubList: public _CodeStubList { | |
84 public: | |
85 CodeStubList(): _CodeStubList() {} | |
86 | |
87 void append(CodeStub* stub) { | |
88 if (!contains(stub)) { | |
89 _CodeStubList::append(stub); | |
90 } | |
91 } | |
92 }; | |
93 | |
94 class CounterOverflowStub: public CodeStub { | |
95 private: | |
96 CodeEmitInfo* _info; | |
97 int _bci; | |
1783 | 98 LIR_Opr _method; |
0 | 99 |
100 public: | |
1783 | 101 CounterOverflowStub(CodeEmitInfo* info, int bci, LIR_Opr method) : _info(info), _bci(bci), _method(method) { |
0 | 102 } |
103 | |
104 virtual void emit_code(LIR_Assembler* e); | |
105 | |
106 virtual void visit(LIR_OpVisitState* visitor) { | |
107 visitor->do_slow_case(_info); | |
1783 | 108 visitor->do_input(_method); |
0 | 109 } |
110 | |
111 #ifndef PRODUCT | |
112 virtual void print_name(outputStream* out) const { out->print("CounterOverflowStub"); } | |
113 #endif // PRODUCT | |
114 | |
115 }; | |
116 | |
117 class ConversionStub: public CodeStub { | |
118 private: | |
119 Bytecodes::Code _bytecode; | |
120 LIR_Opr _input; | |
121 LIR_Opr _result; | |
122 | |
123 static float float_zero; | |
124 static double double_zero; | |
125 public: | |
126 ConversionStub(Bytecodes::Code bytecode, LIR_Opr input, LIR_Opr result) | |
127 : _bytecode(bytecode), _input(input), _result(result) { | |
128 } | |
129 | |
130 Bytecodes::Code bytecode() { return _bytecode; } | |
131 LIR_Opr input() { return _input; } | |
132 LIR_Opr result() { return _result; } | |
133 | |
134 virtual void emit_code(LIR_Assembler* e); | |
135 virtual void visit(LIR_OpVisitState* visitor) { | |
136 visitor->do_slow_case(); | |
137 visitor->do_input(_input); | |
138 visitor->do_output(_result); | |
139 } | |
140 #ifndef PRODUCT | |
141 virtual void print_name(outputStream* out) const { out->print("ConversionStub"); } | |
142 #endif // PRODUCT | |
143 }; | |
144 | |
145 | |
146 // Throws ArrayIndexOutOfBoundsException by default but can be | |
147 // configured to throw IndexOutOfBoundsException in constructor | |
148 class RangeCheckStub: public CodeStub { | |
149 private: | |
150 CodeEmitInfo* _info; | |
151 LIR_Opr _index; | |
152 bool _throw_index_out_of_bounds_exception; | |
153 | |
154 public: | |
155 RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, bool throw_index_out_of_bounds_exception = false); | |
156 virtual void emit_code(LIR_Assembler* e); | |
157 virtual CodeEmitInfo* info() const { return _info; } | |
158 virtual bool is_exception_throw_stub() const { return true; } | |
159 virtual bool is_range_check_stub() const { return true; } | |
160 virtual void visit(LIR_OpVisitState* visitor) { | |
161 visitor->do_slow_case(_info); | |
162 visitor->do_input(_index); | |
163 } | |
164 #ifndef PRODUCT | |
165 virtual void print_name(outputStream* out) const { out->print("RangeCheckStub"); } | |
166 #endif // PRODUCT | |
167 }; | |
168 | |
8860 | 169 // stub used when predicate fails and deoptimization is needed |
170 class PredicateFailedStub: public CodeStub { | |
171 private: | |
172 CodeEmitInfo* _info; | |
173 | |
174 public: | |
175 PredicateFailedStub(CodeEmitInfo* info); | |
176 virtual void emit_code(LIR_Assembler* e); | |
177 virtual CodeEmitInfo* info() const { return _info; } | |
178 virtual void visit(LIR_OpVisitState* visitor) { | |
179 visitor->do_slow_case(_info); | |
180 } | |
181 #ifndef PRODUCT | |
182 virtual void print_name(outputStream* out) const { out->print("PredicateFailedStub"); } | |
183 #endif // PRODUCT | |
184 }; | |
0 | 185 |
186 class DivByZeroStub: public CodeStub { | |
187 private: | |
188 CodeEmitInfo* _info; | |
189 int _offset; | |
190 | |
191 public: | |
192 DivByZeroStub(CodeEmitInfo* info) | |
193 : _info(info), _offset(-1) { | |
194 } | |
195 DivByZeroStub(int offset, CodeEmitInfo* info) | |
196 : _info(info), _offset(offset) { | |
197 } | |
198 virtual void emit_code(LIR_Assembler* e); | |
199 virtual CodeEmitInfo* info() const { return _info; } | |
200 virtual bool is_exception_throw_stub() const { return true; } | |
201 virtual bool is_divbyzero_stub() const { return true; } | |
202 virtual void visit(LIR_OpVisitState* visitor) { | |
203 visitor->do_slow_case(_info); | |
204 } | |
205 #ifndef PRODUCT | |
206 virtual void print_name(outputStream* out) const { out->print("DivByZeroStub"); } | |
207 #endif // PRODUCT | |
208 }; | |
209 | |
210 | |
211 class ImplicitNullCheckStub: public CodeStub { | |
212 private: | |
213 CodeEmitInfo* _info; | |
214 int _offset; | |
215 | |
216 public: | |
217 ImplicitNullCheckStub(int offset, CodeEmitInfo* info) | |
218 : _offset(offset), _info(info) { | |
219 } | |
220 virtual void emit_code(LIR_Assembler* e); | |
221 virtual CodeEmitInfo* info() const { return _info; } | |
222 virtual bool is_exception_throw_stub() const { return true; } | |
223 virtual void visit(LIR_OpVisitState* visitor) { | |
224 visitor->do_slow_case(_info); | |
225 } | |
226 #ifndef PRODUCT | |
227 virtual void print_name(outputStream* out) const { out->print("ImplicitNullCheckStub"); } | |
228 #endif // PRODUCT | |
229 }; | |
230 | |
231 | |
232 class NewInstanceStub: public CodeStub { | |
233 private: | |
234 ciInstanceKlass* _klass; | |
235 LIR_Opr _klass_reg; | |
236 LIR_Opr _result; | |
237 CodeEmitInfo* _info; | |
238 Runtime1::StubID _stub_id; | |
239 | |
240 public: | |
241 NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id); | |
242 virtual void emit_code(LIR_Assembler* e); | |
243 virtual CodeEmitInfo* info() const { return _info; } | |
244 virtual void visit(LIR_OpVisitState* visitor) { | |
245 visitor->do_slow_case(_info); | |
246 visitor->do_input(_klass_reg); | |
247 visitor->do_output(_result); | |
248 } | |
249 #ifndef PRODUCT | |
250 virtual void print_name(outputStream* out) const { out->print("NewInstanceStub"); } | |
251 #endif // PRODUCT | |
252 }; | |
253 | |
254 | |
255 class NewTypeArrayStub: public CodeStub { | |
256 private: | |
257 LIR_Opr _klass_reg; | |
258 LIR_Opr _length; | |
259 LIR_Opr _result; | |
260 CodeEmitInfo* _info; | |
261 | |
262 public: | |
263 NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info); | |
264 virtual void emit_code(LIR_Assembler* e); | |
265 virtual CodeEmitInfo* info() const { return _info; } | |
266 virtual void visit(LIR_OpVisitState* visitor) { | |
267 visitor->do_slow_case(_info); | |
268 visitor->do_input(_klass_reg); | |
269 visitor->do_input(_length); | |
270 assert(_result->is_valid(), "must be valid"); visitor->do_output(_result); | |
271 } | |
272 #ifndef PRODUCT | |
273 virtual void print_name(outputStream* out) const { out->print("NewTypeArrayStub"); } | |
274 #endif // PRODUCT | |
275 }; | |
276 | |
277 | |
278 class NewObjectArrayStub: public CodeStub { | |
279 private: | |
280 LIR_Opr _klass_reg; | |
281 LIR_Opr _length; | |
282 LIR_Opr _result; | |
283 CodeEmitInfo* _info; | |
284 | |
285 public: | |
286 NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info); | |
287 virtual void emit_code(LIR_Assembler* e); | |
288 virtual CodeEmitInfo* info() const { return _info; } | |
289 virtual void visit(LIR_OpVisitState* visitor) { | |
290 visitor->do_slow_case(_info); | |
291 visitor->do_input(_klass_reg); | |
292 visitor->do_input(_length); | |
293 assert(_result->is_valid(), "must be valid"); visitor->do_output(_result); | |
294 } | |
295 #ifndef PRODUCT | |
296 virtual void print_name(outputStream* out) const { out->print("NewObjectArrayStub"); } | |
297 #endif // PRODUCT | |
298 }; | |
299 | |
300 | |
301 class MonitorAccessStub: public CodeStub { | |
302 protected: | |
303 LIR_Opr _obj_reg; | |
304 LIR_Opr _lock_reg; | |
305 | |
306 public: | |
307 MonitorAccessStub(LIR_Opr obj_reg, LIR_Opr lock_reg) { | |
308 _obj_reg = obj_reg; | |
309 _lock_reg = lock_reg; | |
310 } | |
311 | |
312 #ifndef PRODUCT | |
313 virtual void print_name(outputStream* out) const { out->print("MonitorAccessStub"); } | |
314 #endif // PRODUCT | |
315 }; | |
316 | |
317 | |
318 class MonitorEnterStub: public MonitorAccessStub { | |
319 private: | |
320 CodeEmitInfo* _info; | |
321 | |
322 public: | |
323 MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info); | |
324 | |
325 virtual void emit_code(LIR_Assembler* e); | |
326 virtual CodeEmitInfo* info() const { return _info; } | |
327 virtual void visit(LIR_OpVisitState* visitor) { | |
328 visitor->do_input(_obj_reg); | |
329 visitor->do_input(_lock_reg); | |
330 visitor->do_slow_case(_info); | |
331 } | |
332 #ifndef PRODUCT | |
333 virtual void print_name(outputStream* out) const { out->print("MonitorEnterStub"); } | |
334 #endif // PRODUCT | |
335 }; | |
336 | |
337 | |
338 class MonitorExitStub: public MonitorAccessStub { | |
339 private: | |
340 bool _compute_lock; | |
341 int _monitor_ix; | |
342 | |
343 public: | |
344 MonitorExitStub(LIR_Opr lock_reg, bool compute_lock, int monitor_ix) | |
345 : MonitorAccessStub(LIR_OprFact::illegalOpr, lock_reg), | |
346 _compute_lock(compute_lock), _monitor_ix(monitor_ix) { } | |
347 virtual void emit_code(LIR_Assembler* e); | |
348 virtual void visit(LIR_OpVisitState* visitor) { | |
349 assert(_obj_reg->is_illegal(), "unused"); | |
350 if (_compute_lock) { | |
351 visitor->do_temp(_lock_reg); | |
352 } else { | |
353 visitor->do_input(_lock_reg); | |
354 } | |
355 } | |
356 #ifndef PRODUCT | |
357 virtual void print_name(outputStream* out) const { out->print("MonitorExitStub"); } | |
358 #endif // PRODUCT | |
359 }; | |
360 | |
361 | |
362 class PatchingStub: public CodeStub { | |
363 public: | |
364 enum PatchID { | |
365 access_field_id, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
366 load_klass_id, |
12160
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
8860
diff
changeset
|
367 load_mirror_id, |
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
8860
diff
changeset
|
368 load_appendix_id |
0 | 369 }; |
370 enum constants { | |
371 patch_info_size = 3 | |
372 }; | |
373 private: | |
374 PatchID _id; | |
375 address _pc_start; | |
376 int _bytes_to_copy; | |
377 Label _patched_code_entry; | |
378 Label _patch_site_entry; | |
379 Label _patch_site_continuation; | |
380 Register _obj; | |
381 CodeEmitInfo* _info; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
382 int _index; // index of the patchable oop or Klass* in nmethod oop or metadata table if needed |
0 | 383 static int _patch_info_offset; |
384 | |
385 void align_patch_site(MacroAssembler* masm); | |
386 | |
387 public: | |
388 static int patch_info_offset() { return _patch_info_offset; } | |
389 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
390 PatchingStub(MacroAssembler* masm, PatchID id, int index = -1): |
0 | 391 _id(id) |
392 , _info(NULL) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
393 , _index(index) { |
0 | 394 if (os::is_MP()) { |
395 // force alignment of patch sites on MP hardware so we | |
396 // can guarantee atomic writes to the patch site. | |
397 align_patch_site(masm); | |
398 } | |
399 _pc_start = masm->pc(); | |
400 masm->bind(_patch_site_entry); | |
401 } | |
402 | |
403 void install(MacroAssembler* masm, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) { | |
404 _info = info; | |
405 _obj = obj; | |
406 masm->bind(_patch_site_continuation); | |
407 _bytes_to_copy = masm->pc() - pc_start(); | |
408 if (_id == PatchingStub::access_field_id) { | |
409 // embed a fixed offset to handle long patches which need to be offset by a word. | |
410 // the patching code will just add the field offset field to this offset so | |
411 // that we can refernce either the high or low word of a double word field. | |
412 int field_offset = 0; | |
413 switch (patch_code) { | |
414 case lir_patch_low: field_offset = lo_word_offset_in_bytes; break; | |
415 case lir_patch_high: field_offset = hi_word_offset_in_bytes; break; | |
416 case lir_patch_normal: field_offset = 0; break; | |
417 default: ShouldNotReachHere(); | |
418 } | |
419 NativeMovRegMem* n_move = nativeMovRegMem_at(pc_start()); | |
420 n_move->set_offset(field_offset); | |
12160
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
8860
diff
changeset
|
421 } else if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
422 assert(_obj != noreg, "must have register object for load_klass/load_mirror"); |
0 | 423 #ifdef ASSERT |
424 // verify that we're pointing at a NativeMovConstReg | |
425 nativeMovConstReg_at(pc_start()); | |
426 #endif | |
427 } else { | |
428 ShouldNotReachHere(); | |
429 } | |
430 assert(_bytes_to_copy <= (masm->pc() - pc_start()), "not enough bytes"); | |
431 } | |
432 | |
433 address pc_start() const { return _pc_start; } | |
434 PatchID id() const { return _id; } | |
435 | |
436 virtual void emit_code(LIR_Assembler* e); | |
437 virtual CodeEmitInfo* info() const { return _info; } | |
438 virtual void visit(LIR_OpVisitState* visitor) { | |
439 visitor->do_slow_case(_info); | |
440 } | |
441 #ifndef PRODUCT | |
442 virtual void print_name(outputStream* out) const { out->print("PatchingStub"); } | |
443 #endif // PRODUCT | |
444 }; | |
445 | |
446 | |
1295 | 447 //------------------------------------------------------------------------------ |
448 // DeoptimizeStub | |
449 // | |
450 class DeoptimizeStub : public CodeStub { | |
451 private: | |
452 CodeEmitInfo* _info; | |
453 | |
454 public: | |
455 DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {} | |
456 | |
457 virtual void emit_code(LIR_Assembler* e); | |
458 virtual CodeEmitInfo* info() const { return _info; } | |
459 virtual bool is_exception_throw_stub() const { return true; } | |
460 virtual void visit(LIR_OpVisitState* visitor) { | |
461 visitor->do_slow_case(_info); | |
462 } | |
463 #ifndef PRODUCT | |
464 virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); } | |
465 #endif // PRODUCT | |
466 }; | |
467 | |
468 | |
0 | 469 class SimpleExceptionStub: public CodeStub { |
470 private: | |
471 LIR_Opr _obj; | |
472 Runtime1::StubID _stub; | |
473 CodeEmitInfo* _info; | |
474 | |
475 public: | |
476 SimpleExceptionStub(Runtime1::StubID stub, LIR_Opr obj, CodeEmitInfo* info): | |
477 _obj(obj), _info(info), _stub(stub) { | |
478 } | |
479 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
480 void set_obj(LIR_Opr obj) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
481 _obj = obj; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
482 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
483 |
0 | 484 virtual void emit_code(LIR_Assembler* e); |
485 virtual CodeEmitInfo* info() const { return _info; } | |
486 virtual bool is_exception_throw_stub() const { return true; } | |
487 virtual void visit(LIR_OpVisitState* visitor) { | |
488 if (_obj->is_valid()) visitor->do_input(_obj); | |
489 visitor->do_slow_case(_info); | |
490 } | |
491 #ifndef PRODUCT | |
492 virtual void print_name(outputStream* out) const { out->print("SimpleExceptionStub"); } | |
493 #endif // PRODUCT | |
494 }; | |
495 | |
496 | |
497 | |
2168
e4fee0bdaa85
7008809: should report the class in ArrayStoreExceptions from compiled code
never
parents:
1972
diff
changeset
|
498 class ArrayStoreExceptionStub: public SimpleExceptionStub { |
0 | 499 private: |
500 CodeEmitInfo* _info; | |
501 | |
502 public: | |
2168
e4fee0bdaa85
7008809: should report the class in ArrayStoreExceptions from compiled code
never
parents:
1972
diff
changeset
|
503 ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, info) {} |
0 | 504 #ifndef PRODUCT |
505 virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); } | |
506 #endif // PRODUCT | |
507 }; | |
508 | |
509 | |
510 class ArrayCopyStub: public CodeStub { | |
511 private: | |
512 LIR_OpArrayCopy* _op; | |
513 | |
514 public: | |
515 ArrayCopyStub(LIR_OpArrayCopy* op): _op(op) { } | |
516 | |
517 LIR_Opr src() const { return _op->src(); } | |
518 LIR_Opr src_pos() const { return _op->src_pos(); } | |
519 LIR_Opr dst() const { return _op->dst(); } | |
520 LIR_Opr dst_pos() const { return _op->dst_pos(); } | |
521 LIR_Opr length() const { return _op->length(); } | |
522 LIR_Opr tmp() const { return _op->tmp(); } | |
523 | |
524 virtual void emit_code(LIR_Assembler* e); | |
525 virtual CodeEmitInfo* info() const { return _op->info(); } | |
526 virtual void visit(LIR_OpVisitState* visitor) { | |
527 // don't pass in the code emit info since it's processed in the fast path | |
528 visitor->do_slow_case(); | |
529 } | |
530 #ifndef PRODUCT | |
531 virtual void print_name(outputStream* out) const { out->print("ArrayCopyStub"); } | |
532 #endif // PRODUCT | |
533 }; | |
342 | 534 |
535 ////////////////////////////////////////////////////////////////////////////////////////// | |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
6725
diff
changeset
|
536 #if INCLUDE_ALL_GCS |
342 | 537 |
538 // Code stubs for Garbage-First barriers. | |
539 class G1PreBarrierStub: public CodeStub { | |
540 private: | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
541 bool _do_load; |
342 | 542 LIR_Opr _addr; |
543 LIR_Opr _pre_val; | |
544 LIR_PatchCode _patch_code; | |
545 CodeEmitInfo* _info; | |
546 | |
547 public: | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
548 // Version that _does_ generate a load of the previous value from addr. |
342 | 549 // 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
|
550 // pre_val (a temporary register) must be a register; |
342 | 551 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
|
552 _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
|
553 _patch_code(patch_code), _info(info) |
342 | 554 { |
555 assert(_pre_val->is_register(), "should be temporary register"); | |
556 assert(_addr->is_address(), "should be the address of the field"); | |
557 } | |
558 | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
559 // 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
|
560 // 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
|
561 G1PreBarrierStub(LIR_Opr pre_val) : |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
562 _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
|
563 _patch_code(lir_patch_none), _info(NULL) |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
564 { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
565 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
|
566 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
567 |
342 | 568 LIR_Opr addr() const { return _addr; } |
569 LIR_Opr pre_val() const { return _pre_val; } | |
570 LIR_PatchCode patch_code() const { return _patch_code; } | |
571 CodeEmitInfo* info() const { return _info; } | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
572 bool do_load() const { return _do_load; } |
342 | 573 |
574 virtual void emit_code(LIR_Assembler* e); | |
575 virtual void visit(LIR_OpVisitState* visitor) { | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
576 if (_do_load) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
577 // 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
|
578 // path |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
579 if (_info != NULL) |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
580 visitor->do_slow_case(_info); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
581 else |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
582 visitor->do_slow_case(); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
583 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
584 visitor->do_input(_addr); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
585 visitor->do_temp(_pre_val); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
586 } else { |
342 | 587 visitor->do_slow_case(); |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
588 visitor->do_input(_pre_val); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2168
diff
changeset
|
589 } |
342 | 590 } |
591 #ifndef PRODUCT | |
592 virtual void print_name(outputStream* out) const { out->print("G1PreBarrierStub"); } | |
593 #endif // PRODUCT | |
594 }; | |
595 | |
596 class G1PostBarrierStub: public CodeStub { | |
597 private: | |
598 LIR_Opr _addr; | |
599 LIR_Opr _new_val; | |
600 | |
601 static jbyte* _byte_map_base; | |
602 static jbyte* byte_map_base_slow(); | |
603 static jbyte* byte_map_base() { | |
604 if (_byte_map_base == NULL) { | |
605 _byte_map_base = byte_map_base_slow(); | |
606 } | |
607 return _byte_map_base; | |
608 } | |
609 | |
610 public: | |
611 // addr (the address of the object head) and new_val must be registers. | |
612 G1PostBarrierStub(LIR_Opr addr, LIR_Opr new_val): _addr(addr), _new_val(new_val) { } | |
613 | |
614 LIR_Opr addr() const { return _addr; } | |
615 LIR_Opr new_val() const { return _new_val; } | |
616 | |
617 virtual void emit_code(LIR_Assembler* e); | |
618 virtual void visit(LIR_OpVisitState* visitor) { | |
619 // don't pass in the code emit info since it's processed in the fast path | |
620 visitor->do_slow_case(); | |
621 visitor->do_input(_addr); | |
622 visitor->do_input(_new_val); | |
623 } | |
624 #ifndef PRODUCT | |
625 virtual void print_name(outputStream* out) const { out->print("G1PostBarrierStub"); } | |
626 #endif // PRODUCT | |
627 }; | |
628 | |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
6725
diff
changeset
|
629 #endif // INCLUDE_ALL_GCS |
342 | 630 ////////////////////////////////////////////////////////////////////////////////////////// |
1972 | 631 |
632 #endif // SHARE_VM_C1_C1_CODESTUBS_HPP |