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