Mercurial > hg > truffle
annotate src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp @ 20304:a22acf6d7598
8048112: G1 Full GC needs to support the case when the very first region is not available
Summary: Refactor preparation for compaction during Full GC so that it lazily initializes the first compaction point. This also avoids problems later when the first region may not be committed. Also reviewed by K. Barrett.
Reviewed-by: brutisso
author | tschatzl |
---|---|
date | Mon, 21 Jul 2014 10:00:31 +0200 |
parents | 0bf37f737702 |
children | 52b4284cb496 |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
12226
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 #include "precompiled.hpp" |
26 #include "c1/c1_MacroAssembler.hpp" | |
27 #include "c1/c1_Runtime1.hpp" | |
28 #include "classfile/systemDictionary.hpp" | |
29 #include "gc_interface/collectedHeap.hpp" | |
30 #include "interpreter/interpreter.hpp" | |
31 #include "oops/arrayOop.hpp" | |
32 #include "oops/markOop.hpp" | |
33 #include "runtime/basicLock.hpp" | |
34 #include "runtime/biasedLocking.hpp" | |
35 #include "runtime/os.hpp" | |
36 #include "runtime/stubRoutines.hpp" | |
0 | 37 |
38 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { | |
39 Label L; | |
40 const Register temp_reg = G3_scratch; | |
41 // Note: needs more testing of out-of-line vs. inline slow case | |
42 verify_oop(receiver); | |
2002 | 43 load_klass(receiver, temp_reg); |
3839 | 44 cmp_and_brx_short(temp_reg, iCache, Assembler::equal, Assembler::pt, L); |
727 | 45 AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub()); |
46 jump_to(ic_miss, temp_reg); | |
0 | 47 delayed()->nop(); |
48 align(CodeEntryAlignment); | |
49 bind(L); | |
50 } | |
51 | |
52 | |
53 void C1_MacroAssembler::explicit_null_check(Register base) { | |
54 Unimplemented(); | |
55 } | |
56 | |
57 | |
17980
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17467
diff
changeset
|
58 void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) { |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17467
diff
changeset
|
59 assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect"); |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17467
diff
changeset
|
60 generate_stack_overflow_check(bang_size_in_bytes); |
0 | 61 // Create the frame. |
62 save_frame_c1(frame_size_in_bytes); | |
63 } | |
64 | |
65 | |
66 void C1_MacroAssembler::unverified_entry(Register receiver, Register ic_klass) { | |
67 if (C1Breakpoint) breakpoint_trap(); | |
68 inline_cache_check(receiver, ic_klass); | |
69 } | |
70 | |
71 | |
72 void C1_MacroAssembler::verified_entry() { | |
73 if (C1Breakpoint) breakpoint_trap(); | |
74 // build frame | |
75 verify_FPU(0, "method_entry"); | |
76 } | |
77 | |
78 | |
79 void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox, Register Rscratch, Label& slow_case) { | |
80 assert_different_registers(Rmark, Roop, Rbox, Rscratch); | |
81 | |
82 Label done; | |
83 | |
727 | 84 Address mark_addr(Roop, oopDesc::mark_offset_in_bytes()); |
0 | 85 |
86 // The following move must be the first instruction of emitted since debug | |
87 // information may be generated for it. | |
88 // Load object header | |
89 ld_ptr(mark_addr, Rmark); | |
90 | |
91 verify_oop(Roop); | |
92 | |
93 // save object being locked into the BasicObjectLock | |
94 st_ptr(Roop, Rbox, BasicObjectLock::obj_offset_in_bytes()); | |
95 | |
96 if (UseBiasedLocking) { | |
97 biased_locking_enter(Roop, Rmark, Rscratch, done, &slow_case); | |
98 } | |
99 | |
100 // Save Rbox in Rscratch to be used for the cas operation | |
101 mov(Rbox, Rscratch); | |
102 | |
103 // and mark it unlocked | |
104 or3(Rmark, markOopDesc::unlocked_value, Rmark); | |
105 | |
106 // save unlocked object header into the displaced header location on the stack | |
107 st_ptr(Rmark, Rbox, BasicLock::displaced_header_offset_in_bytes()); | |
108 | |
109 // compare object markOop with Rmark and if equal exchange Rscratch with object markOop | |
110 assert(mark_addr.disp() == 0, "cas must take a zero displacement"); | |
10997 | 111 cas_ptr(mark_addr.base(), Rmark, Rscratch); |
0 | 112 // if compare/exchange succeeded we found an unlocked object and we now have locked it |
113 // hence we are done | |
114 cmp(Rmark, Rscratch); | |
115 brx(Assembler::equal, false, Assembler::pt, done); | |
116 delayed()->sub(Rscratch, SP, Rscratch); //pull next instruction into delay slot | |
117 // we did not find an unlocked object so see if this is a recursive case | |
118 // sub(Rscratch, SP, Rscratch); | |
119 assert(os::vm_page_size() > 0xfff, "page size too small - change the constant"); | |
120 andcc(Rscratch, 0xfffff003, Rscratch); | |
121 brx(Assembler::notZero, false, Assembler::pn, slow_case); | |
122 delayed()->st_ptr(Rscratch, Rbox, BasicLock::displaced_header_offset_in_bytes()); | |
123 bind(done); | |
124 } | |
125 | |
126 | |
127 void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case) { | |
128 assert_different_registers(Rmark, Roop, Rbox); | |
129 | |
130 Label done; | |
131 | |
727 | 132 Address mark_addr(Roop, oopDesc::mark_offset_in_bytes()); |
0 | 133 assert(mark_addr.disp() == 0, "cas must take a zero displacement"); |
134 | |
135 if (UseBiasedLocking) { | |
136 // load the object out of the BasicObjectLock | |
137 ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop); | |
138 verify_oop(Roop); | |
139 biased_locking_exit(mark_addr, Rmark, done); | |
140 } | |
141 // Test first it it is a fast recursive unlock | |
142 ld_ptr(Rbox, BasicLock::displaced_header_offset_in_bytes(), Rmark); | |
3839 | 143 br_null_short(Rmark, Assembler::pt, done); |
0 | 144 if (!UseBiasedLocking) { |
145 // load object | |
146 ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop); | |
147 verify_oop(Roop); | |
148 } | |
149 | |
150 // Check if it is still a light weight lock, this is is true if we see | |
151 // the stack address of the basicLock in the markOop of the object | |
10997 | 152 cas_ptr(mark_addr.base(), Rbox, Rmark); |
0 | 153 cmp(Rbox, Rmark); |
154 | |
155 brx(Assembler::notEqual, false, Assembler::pn, slow_case); | |
156 delayed()->nop(); | |
157 // Done | |
158 bind(done); | |
159 } | |
160 | |
161 | |
162 void C1_MacroAssembler::try_allocate( | |
163 Register obj, // result: pointer to object after successful allocation | |
164 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise | |
165 int con_size_in_bytes, // object size in bytes if known at compile time | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
166 Register t1, // temp register, must be global register for incr_allocated_bytes |
0 | 167 Register t2, // temp register |
168 Label& slow_case // continuation point if fast allocation fails | |
169 ) { | |
2127
5577848f5923
7011463: Sparc MacroAssembler::incr_allocated_bytes() needs a RegisterOrConstant argument
phh
parents:
2100
diff
changeset
|
170 RegisterOrConstant size_in_bytes = var_size_in_bytes->is_valid() |
5577848f5923
7011463: Sparc MacroAssembler::incr_allocated_bytes() needs a RegisterOrConstant argument
phh
parents:
2100
diff
changeset
|
171 ? RegisterOrConstant(var_size_in_bytes) : RegisterOrConstant(con_size_in_bytes); |
0 | 172 if (UseTLAB) { |
173 tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case); | |
174 } else { | |
175 eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case); | |
2127
5577848f5923
7011463: Sparc MacroAssembler::incr_allocated_bytes() needs a RegisterOrConstant argument
phh
parents:
2100
diff
changeset
|
176 incr_allocated_bytes(size_in_bytes, t1, t2); |
0 | 177 } |
178 } | |
179 | |
180 | |
181 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) { | |
182 assert_different_registers(obj, klass, len, t1, t2); | |
183 if (UseBiasedLocking && !len->is_valid()) { | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
3839
diff
changeset
|
184 ld_ptr(klass, in_bytes(Klass::prototype_header_offset()), t1); |
0 | 185 } else { |
186 set((intx)markOopDesc::prototype(), t1); | |
187 } | |
2002 | 188 st_ptr(t1, obj, oopDesc::mark_offset_in_bytes()); |
12226
7944aba7ba41
8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents:
10997
diff
changeset
|
189 if (UseCompressedClassPointers) { |
2002 | 190 // Save klass |
191 mov(klass, t1); | |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6725
diff
changeset
|
192 encode_klass_not_null(t1); |
2002 | 193 stw(t1, obj, oopDesc::klass_offset_in_bytes()); |
194 } else { | |
195 st_ptr(klass, obj, oopDesc::klass_offset_in_bytes()); | |
196 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4762
diff
changeset
|
197 if (len->is_valid()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4762
diff
changeset
|
198 st(len, obj, arrayOopDesc::length_offset_in_bytes()); |
12226
7944aba7ba41
8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents:
10997
diff
changeset
|
199 } else if (UseCompressedClassPointers) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4762
diff
changeset
|
200 // otherwise length is in the class gap |
2002 | 201 store_klass_gap(G0, obj); |
202 } | |
0 | 203 } |
204 | |
205 | |
206 void C1_MacroAssembler::initialize_body(Register base, Register index) { | |
207 assert_different_registers(base, index); | |
208 Label loop; | |
209 bind(loop); | |
210 subcc(index, HeapWordSize, index); | |
211 brx(Assembler::greaterEqual, true, Assembler::pt, loop); | |
212 delayed()->st_ptr(G0, base, index); | |
213 } | |
214 | |
215 | |
216 void C1_MacroAssembler::allocate_object( | |
217 Register obj, // result: pointer to object after successful allocation | |
218 Register t1, // temp register | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
219 Register t2, // temp register, must be a global register for try_allocate |
0 | 220 Register t3, // temp register |
221 int hdr_size, // object header size in words | |
222 int obj_size, // object size in words | |
223 Register klass, // object klass | |
224 Label& slow_case // continuation point if fast allocation fails | |
225 ) { | |
226 assert_different_registers(obj, t1, t2, t3, klass); | |
227 assert(klass == G5, "must be G5"); | |
228 | |
229 // allocate space & initialize header | |
230 if (!is_simm13(obj_size * wordSize)) { | |
231 // would need to use extra register to load | |
232 // object size => go the slow case for now | |
3839 | 233 ba(slow_case); |
0 | 234 delayed()->nop(); |
235 return; | |
236 } | |
237 try_allocate(obj, noreg, obj_size * wordSize, t2, t3, slow_case); | |
238 | |
239 initialize_object(obj, klass, noreg, obj_size * HeapWordSize, t1, t2); | |
240 } | |
241 | |
242 void C1_MacroAssembler::initialize_object( | |
243 Register obj, // result: pointer to object after successful allocation | |
244 Register klass, // object klass | |
245 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise | |
246 int con_size_in_bytes, // object size in bytes if known at compile time | |
247 Register t1, // temp register | |
248 Register t2 // temp register | |
249 ) { | |
2002 | 250 const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; |
0 | 251 |
252 initialize_header(obj, klass, noreg, t1, t2); | |
253 | |
254 #ifdef ASSERT | |
255 { | |
256 Label ok; | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
3839
diff
changeset
|
257 ld(klass, in_bytes(Klass::layout_helper_offset()), t1); |
0 | 258 if (var_size_in_bytes != noreg) { |
3839 | 259 cmp_and_brx_short(t1, var_size_in_bytes, Assembler::equal, Assembler::pt, ok); |
0 | 260 } else { |
3839 | 261 cmp_and_brx_short(t1, con_size_in_bytes, Assembler::equal, Assembler::pt, ok); |
0 | 262 } |
263 stop("bad size in initialize_object"); | |
264 should_not_reach_here(); | |
265 | |
266 bind(ok); | |
267 } | |
268 | |
269 #endif | |
270 | |
271 // initialize body | |
272 const int threshold = 5 * HeapWordSize; // approximate break even point for code size | |
273 if (var_size_in_bytes != noreg) { | |
274 // use a loop | |
275 add(obj, hdr_size_in_bytes, t1); // compute address of first element | |
276 sub(var_size_in_bytes, hdr_size_in_bytes, t2); // compute size of body | |
277 initialize_body(t1, t2); | |
278 #ifndef _LP64 | |
10997 | 279 } else if (con_size_in_bytes < threshold * 2) { |
0 | 280 // on v9 we can do double word stores to fill twice as much space. |
281 assert(hdr_size_in_bytes % 8 == 0, "double word aligned"); | |
282 assert(con_size_in_bytes % 8 == 0, "double word aligned"); | |
283 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += 2 * HeapWordSize) stx(G0, obj, i); | |
284 #endif | |
285 } else if (con_size_in_bytes <= threshold) { | |
286 // use explicit NULL stores | |
287 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += HeapWordSize) st_ptr(G0, obj, i); | |
288 } else if (con_size_in_bytes > hdr_size_in_bytes) { | |
289 // use a loop | |
290 const Register base = t1; | |
291 const Register index = t2; | |
292 add(obj, hdr_size_in_bytes, base); // compute address of first element | |
293 // compute index = number of words to clear | |
294 set(con_size_in_bytes - hdr_size_in_bytes, index); | |
295 initialize_body(base, index); | |
296 } | |
297 | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
727
diff
changeset
|
298 if (CURRENT_ENV->dtrace_alloc_probes()) { |
0 | 299 assert(obj == O0, "must be"); |
300 call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)), | |
301 relocInfo::runtime_call_type); | |
302 delayed()->nop(); | |
303 } | |
304 | |
305 verify_oop(obj); | |
306 } | |
307 | |
308 | |
309 void C1_MacroAssembler::allocate_array( | |
310 Register obj, // result: pointer to array after successful allocation | |
311 Register len, // array length | |
312 Register t1, // temp register | |
313 Register t2, // temp register | |
314 Register t3, // temp register | |
315 int hdr_size, // object header size in words | |
316 int elt_size, // element size in bytes | |
317 Register klass, // object klass | |
318 Label& slow_case // continuation point if fast allocation fails | |
319 ) { | |
320 assert_different_registers(obj, len, t1, t2, t3, klass); | |
321 assert(klass == G5, "must be G5"); | |
322 assert(t1 == G1, "must be G1"); | |
323 | |
324 // determine alignment mask | |
325 assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work"); | |
326 | |
327 // check for negative or excessive length | |
328 // note: the maximum length allowed is chosen so that arrays of any | |
329 // element size with this length are always smaller or equal | |
330 // to the largest integer (i.e., array size computation will | |
331 // not overflow) | |
332 set(max_array_allocation_length, t1); | |
333 cmp(len, t1); | |
334 br(Assembler::greaterUnsigned, false, Assembler::pn, slow_case); | |
335 | |
336 // compute array size | |
337 // note: if 0 <= len <= max_length, len*elt_size + header + alignment is | |
338 // smaller or equal to the largest integer; also, since top is always | |
339 // aligned, we can do the alignment here instead of at the end address | |
340 // computation | |
341 const Register arr_size = t1; | |
342 switch (elt_size) { | |
343 case 1: delayed()->mov(len, arr_size); break; | |
344 case 2: delayed()->sll(len, 1, arr_size); break; | |
345 case 4: delayed()->sll(len, 2, arr_size); break; | |
346 case 8: delayed()->sll(len, 3, arr_size); break; | |
347 default: ShouldNotReachHere(); | |
348 } | |
349 add(arr_size, hdr_size * wordSize + MinObjAlignmentInBytesMask, arr_size); // add space for header & alignment | |
350 and3(arr_size, ~MinObjAlignmentInBytesMask, arr_size); // align array size | |
351 | |
352 // allocate space & initialize header | |
353 if (UseTLAB) { | |
354 tlab_allocate(obj, arr_size, 0, t2, slow_case); | |
355 } else { | |
356 eden_allocate(obj, arr_size, 0, t2, t3, slow_case); | |
357 } | |
358 initialize_header(obj, klass, len, t2, t3); | |
359 | |
360 // initialize body | |
361 const Register base = t2; | |
362 const Register index = t3; | |
363 add(obj, hdr_size * wordSize, base); // compute address of first element | |
364 sub(arr_size, hdr_size * wordSize, index); // compute index = number of words to clear | |
365 initialize_body(base, index); | |
366 | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
727
diff
changeset
|
367 if (CURRENT_ENV->dtrace_alloc_probes()) { |
0 | 368 assert(obj == O0, "must be"); |
369 call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)), | |
370 relocInfo::runtime_call_type); | |
371 delayed()->nop(); | |
372 } | |
373 | |
374 verify_oop(obj); | |
375 } | |
376 | |
377 | |
378 #ifndef PRODUCT | |
379 | |
380 void C1_MacroAssembler::verify_stack_oop(int stack_offset) { | |
381 if (!VerifyOops) return; | |
727 | 382 verify_oop_addr(Address(SP, stack_offset + STACK_BIAS)); |
0 | 383 } |
384 | |
385 void C1_MacroAssembler::verify_not_null_oop(Register r) { | |
386 Label not_null; | |
3839 | 387 br_notnull_short(r, Assembler::pt, not_null); |
0 | 388 stop("non-null oop required"); |
389 bind(not_null); | |
390 if (!VerifyOops) return; | |
391 verify_oop(r); | |
392 } | |
393 | |
394 void C1_MacroAssembler::invalidate_registers(bool iregisters, bool lregisters, bool oregisters, | |
395 Register preserve1, Register preserve2) { | |
396 if (iregisters) { | |
397 for (int i = 0; i < 6; i++) { | |
398 Register r = as_iRegister(i); | |
399 if (r != preserve1 && r != preserve2) set(0xdead, r); | |
400 } | |
401 } | |
402 if (oregisters) { | |
403 for (int i = 0; i < 6; i++) { | |
404 Register r = as_oRegister(i); | |
405 if (r != preserve1 && r != preserve2) set(0xdead, r); | |
406 } | |
407 } | |
408 if (lregisters) { | |
409 for (int i = 0; i < 8; i++) { | |
410 Register r = as_lRegister(i); | |
411 if (r != preserve1 && r != preserve2) set(0xdead, r); | |
412 } | |
413 } | |
414 } | |
415 | |
416 | |
417 #endif |