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    }