Mercurial > hg > graal-compiler
annotate src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp @ 6812:988bf00cc564
7200261: G1: Liveness counting inconsistencies during marking verification
Summary: The clipping code in the routine that sets the bits for a range of cards, in the liveness accounting verification code was incorrect. It set all the bits in the card bitmap from the given starting index which would lead to spurious marking verification failures.
Reviewed-by: brutisso, jwilhelm, jmasa
author | johnc |
---|---|
date | Thu, 27 Sep 2012 15:44:01 -0700 |
parents | da91efe96a93 |
children | d02120b7a34f |
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 #include "precompiled.hpp" |
26 #include "c1/c1_CodeStubs.hpp" | |
27 #include "c1/c1_FrameMap.hpp" | |
28 #include "c1/c1_LIRAssembler.hpp" | |
29 #include "c1/c1_MacroAssembler.hpp" | |
30 #include "c1/c1_Runtime1.hpp" | |
31 #include "nativeInst_sparc.hpp" | |
32 #include "runtime/sharedRuntime.hpp" | |
33 #include "vmreg_sparc.inline.hpp" | |
34 #ifndef SERIALGC | |
35 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" | |
36 #endif | |
0 | 37 |
38 #define __ ce->masm()-> | |
39 | |
40 RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, | |
41 bool throw_index_out_of_bounds_exception) | |
42 : _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception) | |
43 , _index(index) | |
44 { | |
1819 | 45 assert(info != NULL, "must have info"); |
0 | 46 _info = new CodeEmitInfo(info); |
47 } | |
48 | |
49 | |
50 void RangeCheckStub::emit_code(LIR_Assembler* ce) { | |
51 __ bind(_entry); | |
52 | |
53 if (_index->is_register()) { | |
54 __ mov(_index->as_register(), G4); | |
55 } else { | |
56 __ set(_index->as_jint(), G4); | |
57 } | |
58 if (_throw_index_out_of_bounds_exception) { | |
59 __ call(Runtime1::entry_for(Runtime1::throw_index_exception_id), relocInfo::runtime_call_type); | |
60 } else { | |
61 __ call(Runtime1::entry_for(Runtime1::throw_range_check_failed_id), relocInfo::runtime_call_type); | |
62 } | |
63 __ delayed()->nop(); | |
64 ce->add_call_info_here(_info); | |
65 ce->verify_oop_map(_info); | |
66 #ifdef ASSERT | |
67 __ should_not_reach_here(); | |
68 #endif | |
69 } | |
70 | |
71 | |
72 void CounterOverflowStub::emit_code(LIR_Assembler* ce) { | |
73 __ bind(_entry); | |
74 __ set(_bci, G4); | |
75 __ call(Runtime1::entry_for(Runtime1::counter_overflow_id), relocInfo::runtime_call_type); | |
1783 | 76 __ delayed()->mov_or_nop(_method->as_register(), G5); |
0 | 77 ce->add_call_info_here(_info); |
78 ce->verify_oop_map(_info); | |
79 | |
80 __ br(Assembler::always, true, Assembler::pt, _continuation); | |
81 __ delayed()->nop(); | |
82 } | |
83 | |
84 | |
85 void DivByZeroStub::emit_code(LIR_Assembler* ce) { | |
86 if (_offset != -1) { | |
87 ce->compilation()->implicit_exception_table()->append(_offset, __ offset()); | |
88 } | |
89 __ bind(_entry); | |
90 __ call(Runtime1::entry_for(Runtime1::throw_div0_exception_id), relocInfo::runtime_call_type); | |
91 __ delayed()->nop(); | |
92 ce->add_call_info_here(_info); | |
93 ce->verify_oop_map(_info); | |
94 #ifdef ASSERT | |
95 __ should_not_reach_here(); | |
96 #endif | |
97 } | |
98 | |
99 | |
100 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) { | |
101 ce->compilation()->implicit_exception_table()->append(_offset, __ offset()); | |
102 __ bind(_entry); | |
103 __ call(Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id), | |
104 relocInfo::runtime_call_type); | |
105 __ delayed()->nop(); | |
106 ce->add_call_info_here(_info); | |
107 ce->verify_oop_map(_info); | |
108 #ifdef ASSERT | |
109 __ should_not_reach_here(); | |
110 #endif | |
111 } | |
112 | |
113 | |
114 // Implementation of SimpleExceptionStub | |
115 // Note: %g1 and %g3 are already in use | |
116 void SimpleExceptionStub::emit_code(LIR_Assembler* ce) { | |
117 __ bind(_entry); | |
118 __ call(Runtime1::entry_for(_stub), relocInfo::runtime_call_type); | |
119 | |
120 if (_obj->is_valid()) { | |
121 __ delayed()->mov(_obj->as_register(), G4); // _obj contains the optional argument to the stub | |
122 } else { | |
123 __ delayed()->mov(G0, G4); | |
124 } | |
125 ce->add_call_info_here(_info); | |
126 #ifdef ASSERT | |
127 __ should_not_reach_here(); | |
128 #endif | |
129 } | |
130 | |
131 | |
132 // Implementation of NewInstanceStub | |
133 | |
134 NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) { | |
135 _result = result; | |
136 _klass = klass; | |
137 _klass_reg = klass_reg; | |
138 _info = new CodeEmitInfo(info); | |
139 assert(stub_id == Runtime1::new_instance_id || | |
140 stub_id == Runtime1::fast_new_instance_id || | |
141 stub_id == Runtime1::fast_new_instance_init_check_id, | |
142 "need new_instance id"); | |
143 _stub_id = stub_id; | |
144 } | |
145 | |
146 | |
147 void NewInstanceStub::emit_code(LIR_Assembler* ce) { | |
148 __ bind(_entry); | |
149 __ call(Runtime1::entry_for(_stub_id), relocInfo::runtime_call_type); | |
150 __ delayed()->mov_or_nop(_klass_reg->as_register(), G5); | |
151 ce->add_call_info_here(_info); | |
152 ce->verify_oop_map(_info); | |
153 __ br(Assembler::always, false, Assembler::pt, _continuation); | |
154 __ delayed()->mov_or_nop(O0, _result->as_register()); | |
155 } | |
156 | |
157 | |
158 // Implementation of NewTypeArrayStub | |
159 NewTypeArrayStub::NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) { | |
160 _klass_reg = klass_reg; | |
161 _length = length; | |
162 _result = result; | |
163 _info = new CodeEmitInfo(info); | |
164 } | |
165 | |
166 | |
167 void NewTypeArrayStub::emit_code(LIR_Assembler* ce) { | |
168 __ bind(_entry); | |
169 | |
170 __ mov(_length->as_register(), G4); | |
171 __ call(Runtime1::entry_for(Runtime1::new_type_array_id), relocInfo::runtime_call_type); | |
172 __ delayed()->mov_or_nop(_klass_reg->as_register(), G5); | |
173 ce->add_call_info_here(_info); | |
174 ce->verify_oop_map(_info); | |
175 __ br(Assembler::always, false, Assembler::pt, _continuation); | |
176 __ delayed()->mov_or_nop(O0, _result->as_register()); | |
177 } | |
178 | |
179 | |
180 // Implementation of NewObjectArrayStub | |
181 | |
182 NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) { | |
183 _klass_reg = klass_reg; | |
184 _length = length; | |
185 _result = result; | |
186 _info = new CodeEmitInfo(info); | |
187 } | |
188 | |
189 | |
190 void NewObjectArrayStub::emit_code(LIR_Assembler* ce) { | |
191 __ bind(_entry); | |
192 | |
193 __ mov(_length->as_register(), G4); | |
194 __ call(Runtime1::entry_for(Runtime1::new_object_array_id), relocInfo::runtime_call_type); | |
195 __ delayed()->mov_or_nop(_klass_reg->as_register(), G5); | |
196 ce->add_call_info_here(_info); | |
197 ce->verify_oop_map(_info); | |
198 __ br(Assembler::always, false, Assembler::pt, _continuation); | |
199 __ delayed()->mov_or_nop(O0, _result->as_register()); | |
200 } | |
201 | |
202 | |
203 // Implementation of MonitorAccessStubs | |
204 MonitorEnterStub::MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info) | |
205 : MonitorAccessStub(obj_reg, lock_reg) { | |
206 _info = new CodeEmitInfo(info); | |
207 } | |
208 | |
209 | |
210 void MonitorEnterStub::emit_code(LIR_Assembler* ce) { | |
211 __ bind(_entry); | |
212 __ mov(_obj_reg->as_register(), G4); | |
213 if (ce->compilation()->has_fpu_code()) { | |
214 __ call(Runtime1::entry_for(Runtime1::monitorenter_id), relocInfo::runtime_call_type); | |
215 } else { | |
216 __ call(Runtime1::entry_for(Runtime1::monitorenter_nofpu_id), relocInfo::runtime_call_type); | |
217 } | |
218 __ delayed()->mov_or_nop(_lock_reg->as_register(), G5); | |
219 ce->add_call_info_here(_info); | |
220 ce->verify_oop_map(_info); | |
221 __ br(Assembler::always, true, Assembler::pt, _continuation); | |
222 __ delayed()->nop(); | |
223 } | |
224 | |
225 | |
226 void MonitorExitStub::emit_code(LIR_Assembler* ce) { | |
227 __ bind(_entry); | |
228 if (_compute_lock) { | |
229 ce->monitor_address(_monitor_ix, _lock_reg); | |
230 } | |
231 if (ce->compilation()->has_fpu_code()) { | |
232 __ call(Runtime1::entry_for(Runtime1::monitorexit_id), relocInfo::runtime_call_type); | |
233 } else { | |
234 __ call(Runtime1::entry_for(Runtime1::monitorexit_nofpu_id), relocInfo::runtime_call_type); | |
235 } | |
236 | |
237 __ delayed()->mov_or_nop(_lock_reg->as_register(), G4); | |
238 __ br(Assembler::always, true, Assembler::pt, _continuation); | |
239 __ delayed()->nop(); | |
240 } | |
241 | |
242 // Implementation of patching: | |
243 // - Copy the code at given offset to an inlined buffer (first the bytes, then the number of bytes) | |
244 // - Replace original code with a call to the stub | |
245 // At Runtime: | |
246 // - call to stub, jump to runtime | |
247 // - in runtime: preserve all registers (especially objects, i.e., source and destination object) | |
248 // - in runtime: after initializing class, restore original code, reexecute instruction | |
249 | |
250 int PatchingStub::_patch_info_offset = -NativeGeneralJump::instruction_size; | |
251 | |
252 void PatchingStub::align_patch_site(MacroAssembler* ) { | |
253 // patch sites on sparc are always properly aligned. | |
254 } | |
255 | |
256 void PatchingStub::emit_code(LIR_Assembler* ce) { | |
257 // copy original code here | |
258 assert(NativeCall::instruction_size <= _bytes_to_copy && _bytes_to_copy <= 0xFF, | |
259 "not enough room for call"); | |
260 assert((_bytes_to_copy & 0x3) == 0, "must copy a multiple of four bytes"); | |
261 | |
262 Label call_patch; | |
263 | |
264 int being_initialized_entry = __ offset(); | |
265 | |
266 if (_id == load_klass_id) { | |
267 // produce a copy of the load klass instruction for use by the being initialized case | |
727 | 268 #ifdef ASSERT |
0 | 269 address start = __ pc(); |
727 | 270 #endif |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
271 AddressLiteral addrlit(NULL, metadata_Relocation::spec(_index)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
272 __ patchable_set(addrlit, _obj); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
273 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
274 #ifdef ASSERT |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
275 for (int i = 0; i < _bytes_to_copy; i++) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
276 address ptr = (address)(_pc_start + i); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
277 int a_byte = (*ptr) & 0xFF; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
278 assert(a_byte == *start++, "should be the same code"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
279 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
280 #endif |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
281 } else if (_id == load_mirror_id) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
282 // produce a copy of the load mirror instruction for use by the being initialized case |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
283 #ifdef ASSERT |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
284 address start = __ pc(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
285 #endif |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
286 AddressLiteral addrlit(NULL, oop_Relocation::spec(_index)); |
727 | 287 __ patchable_set(addrlit, _obj); |
0 | 288 |
289 #ifdef ASSERT | |
290 for (int i = 0; i < _bytes_to_copy; i++) { | |
291 address ptr = (address)(_pc_start + i); | |
292 int a_byte = (*ptr) & 0xFF; | |
293 assert(a_byte == *start++, "should be the same code"); | |
294 } | |
295 #endif | |
296 } else { | |
297 // make a copy the code which is going to be patched. | |
298 for (int i = 0; i < _bytes_to_copy; i++) { | |
299 address ptr = (address)(_pc_start + i); | |
300 int a_byte = (*ptr) & 0xFF; | |
301 __ a_byte (a_byte); | |
302 } | |
303 } | |
304 | |
305 address end_of_patch = __ pc(); | |
306 int bytes_to_skip = 0; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
307 if (_id == load_mirror_id) { |
0 | 308 int offset = __ offset(); |
309 if (CommentedAssembly) { | |
310 __ block_comment(" being_initialized check"); | |
311 } | |
312 | |
313 // static field accesses have special semantics while the class | |
314 // initializer is being run so we emit a test which can be used to | |
315 // check that this code is being executed by the initializing | |
316 // thread. | |
317 assert(_obj != noreg, "must be a valid register"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
318 assert(_index >= 0, "must have oop index"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
319 __ ld_ptr(_obj, java_lang_Class::klass_offset_in_bytes(), G3); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
320 __ ld_ptr(G3, in_bytes(InstanceKlass::init_thread_offset()), G3); |
3839 | 321 __ cmp_and_brx_short(G2_thread, G3, Assembler::notEqual, Assembler::pn, call_patch); |
0 | 322 |
323 // load_klass patches may execute the patched code before it's | |
324 // copied back into place so we need to jump back into the main | |
325 // code of the nmethod to continue execution. | |
326 __ br(Assembler::always, false, Assembler::pt, _patch_site_continuation); | |
327 __ delayed()->nop(); | |
328 | |
329 // make sure this extra code gets skipped | |
330 bytes_to_skip += __ offset() - offset; | |
331 } | |
332 | |
333 // Now emit the patch record telling the runtime how to find the | |
334 // pieces of the patch. We only need 3 bytes but it has to be | |
335 // aligned as an instruction so emit 4 bytes. | |
336 int sizeof_patch_record = 4; | |
337 bytes_to_skip += sizeof_patch_record; | |
338 | |
339 // emit the offsets needed to find the code to patch | |
340 int being_initialized_entry_offset = __ offset() - being_initialized_entry + sizeof_patch_record; | |
341 | |
342 // Emit the patch record. We need to emit a full word, so emit an extra empty byte | |
343 __ a_byte(0); | |
344 __ a_byte(being_initialized_entry_offset); | |
345 __ a_byte(bytes_to_skip); | |
346 __ a_byte(_bytes_to_copy); | |
347 address patch_info_pc = __ pc(); | |
348 assert(patch_info_pc - end_of_patch == bytes_to_skip, "incorrect patch info"); | |
349 | |
350 address entry = __ pc(); | |
351 NativeGeneralJump::insert_unconditional((address)_pc_start, entry); | |
352 address target = NULL; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
353 relocInfo::relocType reloc_type = relocInfo::none; |
0 | 354 switch (_id) { |
355 case access_field_id: target = Runtime1::entry_for(Runtime1::access_field_patching_id); break; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
356 case load_klass_id: target = Runtime1::entry_for(Runtime1::load_klass_patching_id); reloc_type = relocInfo::metadata_type; break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
357 case load_mirror_id: target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); reloc_type = relocInfo::oop_type; break; |
0 | 358 default: ShouldNotReachHere(); |
359 } | |
360 __ bind(call_patch); | |
361 | |
362 if (CommentedAssembly) { | |
363 __ block_comment("patch entry point"); | |
364 } | |
365 __ call(target, relocInfo::runtime_call_type); | |
366 __ delayed()->nop(); | |
367 assert(_patch_info_offset == (patch_info_pc - __ pc()), "must not change"); | |
368 ce->add_call_info_here(_info); | |
369 __ br(Assembler::always, false, Assembler::pt, _patch_site_entry); | |
370 __ delayed()->nop(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
371 if (_id == load_klass_id || _id == load_mirror_id) { |
0 | 372 CodeSection* cs = __ code_section(); |
373 address pc = (address)_pc_start; | |
374 RelocIterator iter(cs, pc, pc + 1); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
375 relocInfo::change_reloc_info_for_address(&iter, (address) pc, reloc_type, relocInfo::none); |
0 | 376 |
377 pc = (address)(_pc_start + NativeMovConstReg::add_offset); | |
378 RelocIterator iter2(cs, pc, pc+1); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6615
diff
changeset
|
379 relocInfo::change_reloc_info_for_address(&iter2, (address) pc, reloc_type, relocInfo::none); |
0 | 380 } |
381 | |
382 } | |
383 | |
1295 | 384 |
385 void DeoptimizeStub::emit_code(LIR_Assembler* ce) { | |
386 __ bind(_entry); | |
4048
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3888
diff
changeset
|
387 __ call(Runtime1::entry_for(Runtime1::deoptimize_id), relocInfo::runtime_call_type); |
1295 | 388 __ delayed()->nop(); |
389 ce->add_call_info_here(_info); | |
4048
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3888
diff
changeset
|
390 DEBUG_ONLY(__ should_not_reach_here()); |
1295 | 391 } |
392 | |
393 | |
0 | 394 void ArrayCopyStub::emit_code(LIR_Assembler* ce) { |
395 //---------------slow case: call to native----------------- | |
396 __ bind(_entry); | |
397 __ mov(src()->as_register(), O0); | |
398 __ mov(src_pos()->as_register(), O1); | |
399 __ mov(dst()->as_register(), O2); | |
400 __ mov(dst_pos()->as_register(), O3); | |
401 __ mov(length()->as_register(), O4); | |
402 | |
403 ce->emit_static_call_stub(); | |
404 | |
405 __ call(SharedRuntime::get_resolve_static_call_stub(), relocInfo::static_call_type); | |
406 __ delayed()->nop(); | |
407 ce->add_call_info_here(info()); | |
408 ce->verify_oop_map(info()); | |
409 | |
410 #ifndef PRODUCT | |
411 __ set((intptr_t)&Runtime1::_arraycopy_slowcase_cnt, O0); | |
412 __ ld(O0, 0, O1); | |
413 __ inc(O1); | |
414 __ st(O1, 0, O0); | |
415 #endif | |
416 | |
417 __ br(Assembler::always, false, Assembler::pt, _continuation); | |
418 __ delayed()->nop(); | |
419 } | |
420 | |
421 | |
342 | 422 /////////////////////////////////////////////////////////////////////////////////// |
423 #ifndef SERIALGC | |
424 | |
425 void G1PreBarrierStub::emit_code(LIR_Assembler* ce) { | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2380
diff
changeset
|
426 // At this point we know that marking is in progress. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2380
diff
changeset
|
427 // If do_load() is true then we have to emit the |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2380
diff
changeset
|
428 // load of the previous value; otherwise it has already |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2380
diff
changeset
|
429 // been loaded into _pre_val. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2380
diff
changeset
|
430 |
342 | 431 __ bind(_entry); |
432 | |
433 assert(pre_val()->is_register(), "Precondition."); | |
434 Register pre_val_reg = pre_val()->as_register(); | |
435 | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2380
diff
changeset
|
436 if (do_load()) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2380
diff
changeset
|
437 ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2380
diff
changeset
|
438 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2380
diff
changeset
|
439 |
1848 | 440 if (__ is_in_wdisp16_range(_continuation)) { |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
441 __ br_null(pre_val_reg, /*annul*/false, Assembler::pt, _continuation); |
1848 | 442 } else { |
443 __ cmp(pre_val_reg, G0); | |
444 __ brx(Assembler::equal, false, Assembler::pn, _continuation); | |
445 } | |
342 | 446 __ delayed()->nop(); |
447 | |
448 __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id)); | |
449 __ delayed()->mov(pre_val_reg, G4); | |
450 __ br(Assembler::always, false, Assembler::pt, _continuation); | |
451 __ delayed()->nop(); | |
452 | |
453 } | |
454 | |
455 jbyte* G1PostBarrierStub::_byte_map_base = NULL; | |
456 | |
457 jbyte* G1PostBarrierStub::byte_map_base_slow() { | |
458 BarrierSet* bs = Universe::heap()->barrier_set(); | |
459 assert(bs->is_a(BarrierSet::G1SATBCTLogging), | |
460 "Must be if we're using this."); | |
461 return ((G1SATBCardTableModRefBS*)bs)->byte_map_base; | |
462 } | |
463 | |
464 void G1PostBarrierStub::emit_code(LIR_Assembler* ce) { | |
465 __ bind(_entry); | |
466 | |
467 assert(addr()->is_register(), "Precondition."); | |
468 assert(new_val()->is_register(), "Precondition."); | |
469 Register addr_reg = addr()->as_pointer_register(); | |
470 Register new_val_reg = new_val()->as_register(); | |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
471 |
1848 | 472 if (__ is_in_wdisp16_range(_continuation)) { |
3888
4fe626cbf0bf
7066841: remove MacroAssembler::br_on_reg_cond() on sparc
johnc
parents:
3839
diff
changeset
|
473 __ br_null(new_val_reg, /*annul*/false, Assembler::pt, _continuation); |
1848 | 474 } else { |
475 __ cmp(new_val_reg, G0); | |
476 __ brx(Assembler::equal, false, Assembler::pn, _continuation); | |
477 } | |
342 | 478 __ delayed()->nop(); |
479 | |
480 __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_post_barrier_slow_id)); | |
481 __ delayed()->mov(addr_reg, G4); | |
482 __ br(Assembler::always, false, Assembler::pt, _continuation); | |
483 __ delayed()->nop(); | |
484 } | |
485 | |
486 #endif // SERIALGC | |
487 /////////////////////////////////////////////////////////////////////////////////// | |
488 | |
0 | 489 #undef __ |