001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.jikesrvm.compilers.baseline.ia32;
014
015 import org.jikesrvm.Configuration;
016 import org.jikesrvm.ArchitectureSpecific.Assembler;
017 import org.jikesrvm.classloader.MethodReference;
018 import org.jikesrvm.classloader.NormalMethod;
019 import org.jikesrvm.ia32.BaselineConstants;
020 import org.jikesrvm.runtime.Entrypoints;
021 import org.jikesrvm.runtime.Magic;
022 import org.vmmagic.unboxed.Offset;
023 import org.vmmagic.pragma.Inline;
024
025 /**
026 * Class called from baseline compiler to generate architecture specific
027 * write barriers for garbage collectors. For baseline
028 * compiled methods, the write barrier calls methods of WriteBarrier.
029 */
030 class Barriers implements BaselineConstants {
031
032 /**
033 * Generate code to perform an array store barrier. On entry the stack holds:
034 * arrayRef, index, value.
035 *
036 * @param asm the assembler to generate the code in
037 */
038 static void compileArrayStoreBarrier(Assembler asm) {
039 BaselineCompilerImpl.genParameterRegisterLoad(asm, 3);
040 asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.aastoreMethod.getOffset()));
041 }
042
043 /**
044 * Helper function for primitive array stores
045 *
046 * @param asm the assembler to generate the code in
047 * @param compiler the compiler instance to ensure correct parameter passing
048 * @param barrier the designated barrier
049 */
050 private static void arayStoreBarrierHelper(Assembler asm, BaselineCompilerImpl compiler, NormalMethod barrier) {
051 // on entry java stack contains ...|target_array_ref|array_index|value_to_store|
052 // Use the correct calling convention to pass parameters by register and the stack
053 // (size of value_to_store varies by type of array store)
054 MethodReference method = barrier.getMemberRef().asMethodReference();
055 compiler.genParameterRegisterLoad(method, false);
056 // call the actual write barrier
057 asm.emitCALL_Abs(Magic.getTocPointer().plus(barrier.getOffset()));
058 }
059
060 /**
061 * Generate code to perform a bastore barrier. On entry the stack holds:
062 * arrayRef, index, value.
063 *
064 * @param asm the assembler to generate the code in
065 * @param compiler the compiler instance to ensure correct parameter passing
066 */
067 static void compileArrayStoreBarrierByte(Assembler asm, BaselineCompilerImpl compiler) {
068 arayStoreBarrierHelper(asm, compiler, Entrypoints.byteArrayWriteBarrierMethod);
069 }
070
071 /**
072 * Generate code to perform a castore barrier. On entry the stack holds:
073 * arrayRef, index, value.
074 *
075 * @param asm the assembler to generate the code in
076 * @param compiler the compiler instance to ensure correct parameter passing
077 */
078 static void compileArrayStoreBarrierChar(Assembler asm, BaselineCompilerImpl compiler) {
079 arayStoreBarrierHelper(asm, compiler, Entrypoints.charArrayWriteBarrierMethod);
080 }
081
082 /**
083 * Generate code to perform a dastore barrier. On entry the stack holds:
084 * arrayRef, index, value.
085 *
086 * @param asm the assembler to generate the code in
087 * @param compiler the compiler instance to ensure correct parameter passing
088 */
089 static void compileArrayStoreBarrierDouble(Assembler asm, BaselineCompilerImpl compiler) {
090 arayStoreBarrierHelper(asm, compiler, Entrypoints.doubleArrayWriteBarrierMethod);
091 }
092
093 /**
094 * Generate code to perform a fastore barrier. On entry the stack holds:
095 * arrayRef, index, value.
096 *
097 * @param asm the assembler to generate the code in
098 * @param compiler the compiler instance to ensure correct parameter passing
099 */
100 static void compileArrayStoreBarrierFloat(Assembler asm, BaselineCompilerImpl compiler) {
101 arayStoreBarrierHelper(asm, compiler, Entrypoints.floatArrayWriteBarrierMethod);
102 }
103
104 /**
105 * Generate code to perform a iastore barrier. On entry the stack holds:
106 * arrayRef, index, value.
107 *
108 * @param asm the assembler to generate the code in
109 * @param compiler the compiler instance to ensure correct parameter passing
110 */
111 static void compileArrayStoreBarrierInt(Assembler asm, BaselineCompilerImpl compiler) {
112 arayStoreBarrierHelper(asm, compiler, Entrypoints.intArrayWriteBarrierMethod);
113 }
114
115 /**
116 * Generate code to perform a lastore barrier. On entry the stack holds:
117 * arrayRef, index, value.
118 *
119 * @param asm the assembler to generate the code in
120 * @param compiler the compiler instance to ensure correct parameter passing
121 */
122 static void compileArrayStoreBarrierLong(Assembler asm, BaselineCompilerImpl compiler) {
123 arayStoreBarrierHelper(asm, compiler, Entrypoints.longArrayWriteBarrierMethod);
124 }
125
126 /**
127 * Generate code to perform a sastore barrier. On entry the stack holds:
128 * arrayRef, index, value.
129 *
130 * @param asm the assembler to generate the code in
131 * @param compiler the compiler instance to ensure correct parameter passing
132 */
133 static void compileArrayStoreBarrierShort(Assembler asm, BaselineCompilerImpl compiler) {
134 arayStoreBarrierHelper(asm, compiler, Entrypoints.shortArrayWriteBarrierMethod);
135 }
136
137 /**
138 * Generate code to perform a putfield barrier. On entry the stack holds:
139 * object, value.
140 *
141 * @param asm the assembler to generate the code in
142 * @param offset the register holding the offset of the field
143 * @param locationMetadata meta-data about the location
144 */
145 @Inline
146 static void compilePutfieldBarrier(Assembler asm, GPR offset, int locationMetadata) {
147 asm.emitPUSH_Reg(offset);
148 asm.emitPUSH_Imm(locationMetadata);
149 BaselineCompilerImpl.genParameterRegisterLoad(asm, 4);
150 genNullCheck(asm, T0);
151 asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.objectFieldWriteBarrierMethod.getOffset()));
152 }
153
154 /**
155 * Generate code to perform a putfield barrier when the field is at a known
156 * offset. On entry the stack holds: object, value.
157 *
158 * @param asm the assembler to generate the code in
159 * @param fieldOffset the offset of the field
160 * @param locationMetadata meta-data about the location
161 */
162 @Inline
163 static void compilePutfieldBarrierImm(Assembler asm, Offset fieldOffset, int locationMetadata) {
164 asm.emitPUSH_Imm(fieldOffset.toInt());
165 asm.emitPUSH_Imm(locationMetadata);
166 BaselineCompilerImpl.genParameterRegisterLoad(asm, 4);
167 genNullCheck(asm, T0);
168 asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.objectFieldWriteBarrierMethod.getOffset()));
169 }
170
171 /**
172 * Private helper method for primitive putfields
173 *
174 * @param asm the assembler to generate the code in
175 * @param compiler the compiler instance to ensure correct parameter passing
176 * @param offset the register holding the offset of the field
177 * @param locationMetadata meta-data about the location
178 * @param barrier the barrier method to call
179 */
180 @Inline
181 private static void putfieldStoreBarrierHelper(Assembler asm, BaselineCompilerImpl compiler, GPR offset, int locationMetadata,
182 NormalMethod barrier) {
183 // on entry the java stack contains... |object|value|
184 asm.emitPUSH_Reg(offset);
185 asm.emitPUSH_Imm(locationMetadata);
186 // Use the correct calling convention to pass parameters by register and the stack
187 // (size of value varies by type of putfield)
188 MethodReference method = barrier.getMemberRef().asMethodReference();
189 compiler.genParameterRegisterLoad(method, false);
190 genNullCheck(asm, T0);
191 asm.emitCALL_Abs(Magic.getTocPointer().plus(barrier.getOffset()));
192 }
193
194 /**
195 * Private helper method for primitive putfields
196 *
197 * @param asm the assembler to generate the code in
198 * @param compiler the compiler instance to ensure correct parameter passing
199 * @param fieldOffset offset of the field
200 * @param locationMetadata meta-data about the location
201 * @param barrier the barrier method to call
202 */
203 @Inline
204 private static void putfieldStoreBarrierHelper(Assembler asm, BaselineCompilerImpl compiler, Offset fieldOffset, int locationMetadata,
205 NormalMethod barrier) {
206 // on entry the java stack contains... |object|value|
207 asm.emitPUSH_Imm(fieldOffset.toInt());
208 asm.emitPUSH_Imm(locationMetadata);
209 // Use the correct calling convention to pass parameters by register and the stack
210 // (size of value varies by type of putfield)
211 MethodReference method = barrier.getMemberRef().asMethodReference();
212 compiler.genParameterRegisterLoad(method, false);
213 genNullCheck(asm, T0);
214 asm.emitCALL_Abs(Magic.getTocPointer().plus(barrier.getOffset()));
215 }
216
217 /**
218 * Generate code to perform a putfield barrier for a boolean field.
219 * On entry the stack holds: object, value.
220 *
221 * @param asm the assembler to generate the code in
222 * @param offset the register holding the offset of the field
223 * @param locationMetadata meta-data about the location
224 */
225 @Inline
226 static void compilePutfieldBarrierBoolean(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
227 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.booleanFieldWriteBarrierMethod);
228 }
229
230 /**
231 * Generate code to perform a putfield barrier for a boolean field when
232 * the field is at a known offset. On entry the stack holds: object, value.
233 *
234 * @param asm the assembler to generate the code in
235 * @param fieldOffset the offset of the field
236 * @param locationMetadata meta-data about the location
237 */
238 @Inline
239 static void compilePutfieldBarrierBooleanImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
240 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.booleanFieldWriteBarrierMethod);
241 }
242
243 /**
244 * Generate code to perform a putfield barrier for a byte field.
245 * On entry the stack holds: object, value.
246 *
247 * @param asm the assembler to generate the code in
248 * @param offset the register holding the offset of the field
249 * @param locationMetadata meta-data about the location
250 */
251 @Inline
252 static void compilePutfieldBarrierByte(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
253 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.byteFieldWriteBarrierMethod);
254 }
255
256 /**
257 * Generate code to perform a putfield barrier for a byte field when
258 * the field is at a known offset. On entry the stack holds: object, value.
259 *
260 * @param asm the assembler to generate the code in
261 * @param fieldOffset the offset of the field
262 * @param locationMetadata meta-data about the location
263 */
264 @Inline
265 static void compilePutfieldBarrierByteImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
266 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.byteFieldWriteBarrierMethod);
267 }
268
269 /**
270 * Generate code to perform a putfield barrier for a char field.
271 * On entry the stack holds: object, value.
272 *
273 * @param asm the assembler to generate the code in
274 * @param offset the register holding the offset of the field
275 * @param locationMetadata meta-data about the location
276 */
277 @Inline
278 static void compilePutfieldBarrierChar(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
279 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.charFieldWriteBarrierMethod);
280 }
281
282 /**
283 * Generate code to perform a putfield barrier for a char field when
284 * the field is at a known offset. On entry the stack holds: object, value.
285 *
286 * @param asm the assembler to generate the code in
287 * @param fieldOffset the offset of the field
288 * @param locationMetadata meta-data about the location
289 */
290 @Inline
291 static void compilePutfieldBarrierCharImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
292 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.charFieldWriteBarrierMethod);
293 }
294
295 /**
296 * Generate code to perform a putfield barrier for a double field.
297 * On entry the stack holds: object, value.
298 *
299 * @param asm the assembler to generate the code in
300 * @param offset the register holding the offset of the field
301 * @param locationMetadata meta-data about the location
302 */
303 @Inline
304 static void compilePutfieldBarrierDouble(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
305 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.doubleFieldWriteBarrierMethod);
306 }
307
308 /**
309 * Generate code to perform a putfield barrier for a double field when
310 * the field is at a known offset. On entry the stack holds: object, value.
311 *
312 * @param asm the assembler to generate the code in
313 * @param fieldOffset the offset of the field
314 * @param locationMetadata meta-data about the location
315 */
316 @Inline
317 static void compilePutfieldBarrierDoubleImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
318 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.doubleFieldWriteBarrierMethod);
319 }
320
321 /**
322 * Generate code to perform a putfield barrier for a float field.
323 * On entry the stack holds: object, value.
324 *
325 * @param asm the assembler to generate the code in
326 * @param offset the register holding the offset of the field
327 * @param locationMetadata meta-data about the location
328 */
329 @Inline
330 static void compilePutfieldBarrierFloat(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
331 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.floatFieldWriteBarrierMethod);
332 }
333
334 /**
335 * Generate code to perform a putfield barrier for a float field when
336 * the field is at a known offset. On entry the stack holds: object, value.
337 *
338 * @param asm the assembler to generate the code in
339 * @param fieldOffset the offset of the field
340 * @param locationMetadata meta-data about the location
341 */
342 @Inline
343 static void compilePutfieldBarrierFloatImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
344 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.floatFieldWriteBarrierMethod);
345 }
346
347 /**
348 * Generate code to perform a putfield barrier for a int field.
349 * On entry the stack holds: object, value.
350 *
351 * @param asm the assembler to generate the code in
352 * @param offset the register holding the offset of the field
353 * @param locationMetadata meta-data about the location
354 */
355 @Inline
356 static void compilePutfieldBarrierInt(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
357 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.intFieldWriteBarrierMethod);
358 }
359
360 /**
361 * Generate code to perform a putfield barrier for a int field when
362 * the field is at a known offset. On entry the stack holds: object, value.
363 *
364 * @param asm the assembler to generate the code in
365 * @param fieldOffset the offset of the field
366 * @param locationMetadata meta-data about the location
367 */
368 @Inline
369 static void compilePutfieldBarrierIntImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
370 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.intFieldWriteBarrierMethod);
371 }
372
373 /**
374 * Generate code to perform a putfield barrier for a long field.
375 * On entry the stack holds: object, value.
376 *
377 * @param asm the assembler to generate the code in
378 * @param offset the register holding the offset of the field
379 * @param locationMetadata meta-data about the location
380 */
381 @Inline
382 static void compilePutfieldBarrierLong(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
383 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.longFieldWriteBarrierMethod);
384 }
385
386 /**
387 * Generate code to perform a putfield barrier for a long field when
388 * the field is at a known offset. On entry the stack holds: object, value.
389 *
390 * @param asm the assembler to generate the code in
391 * @param fieldOffset the offset of the field
392 * @param locationMetadata meta-data about the location
393 */
394 @Inline
395 static void compilePutfieldBarrierLongImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
396 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.longFieldWriteBarrierMethod);
397 }
398
399 /**
400 * Generate code to perform a putfield barrier for a short field.
401 * On entry the stack holds: object, value.
402 *
403 * @param asm the assembler to generate the code in
404 * @param offset the register holding the offset of the field
405 * @param locationMetadata meta-data about the location
406 */
407 @Inline
408 static void compilePutfieldBarrierShort(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
409 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.shortFieldWriteBarrierMethod);
410 }
411
412 /**
413 * Generate code to perform a putfield barrier for a short field when
414 * the field is at a known offset. On entry the stack holds: object, value.
415 *
416 * @param asm the assembler to generate the code in
417 * @param fieldOffset the offset of the field
418 * @param locationMetadata meta-data about the location
419 */
420 @Inline
421 static void compilePutfieldBarrierShortImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
422 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.shortFieldWriteBarrierMethod);
423 }
424
425 /**
426 * Generate code to perform a putfield barrier for a unboxed Word field.
427 * On entry the stack holds: object, value.
428 *
429 * @param asm the assembler to generate the code in
430 * @param offset the register holding the offset of the field
431 * @param locationMetadata meta-data about the location
432 */
433 @Inline
434 static void compilePutfieldBarrierWord(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
435 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.wordFieldWriteBarrierMethod);
436 }
437
438 /**
439 * Generate code to perform a putfield barrier for a unboxed Word field when
440 * the field is at a known offset. On entry the stack holds: object, value.
441 *
442 * @param asm the assembler to generate the code in
443 * @param fieldOffset the offset of the field
444 * @param locationMetadata meta-data about the location
445 */
446 @Inline
447 static void compilePutfieldBarrierWordImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
448 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.wordFieldWriteBarrierMethod);
449 }
450
451 /**
452 * Generate code to perform a putfield barrier for a unboxed Address field.
453 * On entry the stack holds: object, value.
454 *
455 * @param asm the assembler to generate the code in
456 * @param offset the register holding the offset of the field
457 * @param locationMetadata meta-data about the location
458 */
459 @Inline
460 static void compilePutfieldBarrierAddress(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
461 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.addressFieldWriteBarrierMethod);
462 }
463
464 /**
465 * Generate code to perform a putfield barrier for a unboxed Address field when
466 * the field is at a known offset. On entry the stack holds: object, value.
467 *
468 * @param asm the assembler to generate the code in
469 * @param fieldOffset the offset of the field
470 * @param locationMetadata meta-data about the location
471 */
472 @Inline
473 static void compilePutfieldBarrierAddressImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
474 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.addressFieldWriteBarrierMethod);
475 }
476
477 /**
478 * Generate code to perform a putfield barrier for a unboxed Extent field.
479 * On entry the stack holds: object, value.
480 *
481 * @param asm the assembler to generate the code in
482 * @param offset the register holding the offset of the field
483 * @param locationMetadata meta-data about the location
484 */
485 @Inline
486 static void compilePutfieldBarrierExtent(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
487 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.extentFieldWriteBarrierMethod);
488 }
489
490 /**
491 * Generate code to perform a putfield barrier for a unboxed Extent field when
492 * the field is at a known offset. On entry the stack holds: object, value.
493 *
494 * @param asm the assembler to generate the code in
495 * @param fieldOffset the offset of the field
496 * @param locationMetadata meta-data about the location
497 */
498 @Inline
499 static void compilePutfieldBarrierExtentImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
500 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.extentFieldWriteBarrierMethod);
501 }
502
503 /**
504 * Generate code to perform a putfield barrier for a unboxed Offset field.
505 * On entry the stack holds: object, value.
506 *
507 * @param asm the assembler to generate the code in
508 * @param offset the register holding the offset of the field
509 * @param locationMetadata meta-data about the location
510 */
511 @Inline
512 static void compilePutfieldBarrierOffset(Assembler asm, GPR offset, int locationMetadata, BaselineCompilerImpl compiler) {
513 putfieldStoreBarrierHelper(asm, compiler, offset, locationMetadata, Entrypoints.offsetFieldWriteBarrierMethod);
514 }
515
516 /**
517 * Generate code to perform a putfield barrier for a unboxed Offset field when
518 * the field is at a known offset. On entry the stack holds: object, value.
519 *
520 * @param asm the assembler to generate the code in
521 * @param fieldOffset the offset of the field
522 * @param locationMetadata meta-data about the location
523 */
524 @Inline
525 static void compilePutfieldBarrierOffsetImm(Assembler asm, Offset fieldOffset, int locationMetadata, BaselineCompilerImpl compiler) {
526 putfieldStoreBarrierHelper(asm, compiler, fieldOffset, locationMetadata, Entrypoints.offsetFieldWriteBarrierMethod);
527 }
528
529 static void compilePutstaticBarrier(Assembler asm, GPR reg, int locationMetadata) {
530 // on entry java stack contains ...|ref_to_store|
531 // reg holds offset of field
532 asm.emitPUSH_Reg(reg); // offset
533 asm.emitPUSH_Imm(locationMetadata);
534 BaselineCompilerImpl.genParameterRegisterLoad(asm, 3);
535 asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.objectStaticWriteBarrierMethod.getOffset()));
536 }
537
538 static void compilePutstaticBarrierImm(Assembler asm, Offset fieldOffset, int locationMetadata) {
539 // on entry java stack contains ...|ref_to_store|
540 asm.emitPUSH_Imm(fieldOffset.toInt());
541 asm.emitPUSH_Imm(locationMetadata);
542 BaselineCompilerImpl.genParameterRegisterLoad(asm, 3);
543 asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.objectStaticWriteBarrierMethod.getOffset()));
544 }
545
546 static void compileArrayLoadBarrier(Assembler asm, boolean pushResult) {
547 // on entry java stack contains ...|target_array_ref|array_index|
548 // SP -> index, SP+4 -> target_ref
549 BaselineCompilerImpl.genParameterRegisterLoad(asm, 2);
550 asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.objectArrayReadBarrierMethod.getOffset()));
551 if (pushResult) asm.emitPUSH_Reg(T0);
552 }
553
554 static void compileGetfieldBarrier(Assembler asm, GPR reg, int locationMetadata) {
555 // on entry java stack contains ...|target_ref|
556 // SP -> target_ref
557 asm.emitPUSH_Reg(reg);
558 asm.emitPUSH_Imm(locationMetadata);
559 BaselineCompilerImpl.genParameterRegisterLoad(asm, 3);
560 genNullCheck(asm, T0);
561 asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.objectFieldReadBarrierMethod.getOffset()));
562 asm.emitPUSH_Reg(T0);
563 }
564
565 static void compileGetfieldBarrierImm(Assembler asm, Offset fieldOffset, int locationMetadata) {
566 asm.emitPUSH_Imm(fieldOffset.toInt());
567 asm.emitPUSH_Imm(locationMetadata);
568 BaselineCompilerImpl.genParameterRegisterLoad(asm, 3);
569 genNullCheck(asm, T0);
570 asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.objectFieldReadBarrierMethod.getOffset()));
571 asm.emitPUSH_Reg(T0);
572 }
573
574 static void compileGetstaticBarrier(Assembler asm, GPR reg, int locationMetadata) {
575 asm.emitPUSH_Reg(reg);
576 asm.emitPUSH_Imm(locationMetadata);
577 BaselineCompilerImpl.genParameterRegisterLoad(asm, 2);
578 asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.objectStaticReadBarrierMethod.getOffset()));
579 asm.emitPUSH_Reg(T0);
580 }
581
582 static void compileGetstaticBarrierImm(Assembler asm, Offset fieldOffset, int locationMetadata) {
583 asm.emitPUSH_Imm(fieldOffset.toInt());
584 asm.emitPUSH_Imm(locationMetadata);
585 BaselineCompilerImpl.genParameterRegisterLoad(asm, 2);
586 asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.objectStaticReadBarrierMethod.getOffset()));
587 asm.emitPUSH_Reg(T0);
588 }
589
590 static void compileModifyCheck(Assembler asm, int offset) {
591 if (!Configuration.ExtremeAssertions) return;
592 // on entry java stack contains ... [SP+offset] -> target_ref
593 // on exit: stack is the same
594 asm.emitPUSH_RegDisp(SP, Offset.fromIntSignExtend(offset)); // dup
595 BaselineCompilerImpl.genParameterRegisterLoad(asm, 1);
596 asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.modifyCheckMethod.getOffset()));
597 }
598
599 /**
600 * Generate an implicit null check by loading the TIB of the given object.
601 * Scribbles over S0.
602 *
603 * @param asm the assembler to generate into
604 * @param objRefReg the register containing the reference
605 */
606 private static void genNullCheck(Assembler asm, GPR objRefReg) {
607 BaselineCompilerImpl.baselineEmitLoadTIB(asm, S0, T0);
608 }
609 }