/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.mm.mminterface; import static org.jikesrvm.runtime.UnboxedSizeConstants.BYTES_IN_ADDRESS; import org.jikesrvm.classloader.RVMType; import org.jikesrvm.objectmodel.JavaHeader; import org.jikesrvm.objectmodel.ObjectModel; import org.mmtk.plan.TransitiveClosure; import org.vmmagic.pragma.Inline; import org.vmmagic.pragma.Uninterruptible; /** * Supply and interpretation of values to be alignment-encoded into * the TIB pointer of an object. */ public class HandInlinedScanning { public static final int AE_FALLBACK = (1 << AlignmentEncoding.FIELD_WIDTH) - 1; public static final int AE_REFARRAY = AE_FALLBACK - 1; public static final int AE_PATTERN_0x0 = 0; public static final int AE_PATTERN_0x1 = 1; public static final int AE_PATTERN_0x7 = 2; public static final int AE_PATTERN_0x3F = 3; public static final int AE_PATTERN_0x3 = 4; public static final int AE_PATTERN_0x3D = 5; private static final int FIELD0_OFFSET = JavaHeader.objectStartOffset(RVMType.JavaLangObjectType) + ObjectModel.computeScalarHeaderSize(RVMType.JavaLangObjectType); private static final int FIELD1_OFFSET = FIELD0_OFFSET + BYTES_IN_ADDRESS; private static final int FIELD2_OFFSET = FIELD1_OFFSET + BYTES_IN_ADDRESS; private static final int FIELD3_OFFSET = FIELD2_OFFSET + BYTES_IN_ADDRESS; private static final int FIELD4_OFFSET = FIELD3_OFFSET + BYTES_IN_ADDRESS; private static final int FIELD5_OFFSET = FIELD4_OFFSET + BYTES_IN_ADDRESS; /** Master switch */ public static final boolean ENABLED = true; public static int referenceArray() { if (!ENABLED) return AlignmentEncoding.ALIGN_CODE_NONE; return AE_REFARRAY; } public static int primitiveArray() { if (!ENABLED) return AlignmentEncoding.ALIGN_CODE_NONE; return AE_PATTERN_0x0; } public static int fallback() { if (!ENABLED) return AlignmentEncoding.ALIGN_CODE_NONE; return AE_FALLBACK; } public static int scalar(int[] offsets) { if (!ENABLED) return AlignmentEncoding.ALIGN_CODE_NONE; if (offsets.length == 0) { return AE_PATTERN_0x0; } if (offsets.length == 1) { if (offsets[0] == FIELD0_OFFSET) return AE_PATTERN_0x1; } // if (offsets.length == 2) { // if (offsets[0] == FIELD0_OFFSET && // offsets[1] == FIELD1_OFFSET) // return AE_PATTERN_0x3; // } if (offsets.length == 3) { if (offsets[0] == FIELD0_OFFSET && offsets[1] == FIELD1_OFFSET && offsets[2] == FIELD2_OFFSET) return AE_PATTERN_0x7; } // if (offsets.length == 5) { // if (offsets[0] == FIELD0_OFFSET && // offsets[1] == FIELD2_OFFSET && // offsets[2] == FIELD3_OFFSET && // offsets[3] == FIELD4_OFFSET && // offsets[4] == FIELD5_OFFSET) // return AE_PATTERN_0x3D; // } if (offsets.length == 6) { if (offsets[0] == FIELD0_OFFSET && offsets[1] == FIELD1_OFFSET && offsets[2] == FIELD2_OFFSET && offsets[3] == FIELD3_OFFSET && offsets[4] == FIELD4_OFFSET && offsets[5] == FIELD5_OFFSET) return AE_PATTERN_0x3F; } return AE_FALLBACK; } /** * Hand-inlined scanning of objects. The cases of the conditional * are ordered in descending frequency of patterns. * * This entry point falls back to specialized scanning if it is enabled. * * @param code the code to use for specialized scanning. This determines * the pattern that will be used. * @param id the id of the specialized scan method * @param object the object to scan * @param trace the closure to use */ @Inline @Uninterruptible public static void scanObject(int code, int id, Object object, TransitiveClosure trace) { scanObject(code, id, object, trace, SpecializedScanMethod.ENABLED); } /** * Hand-inlined scanning of objects. The cases of the conditional * are ordered in descending frequency of patterns. * <p> * This entry point does not fall back to specialized scanning. * * @param code the code to use for specialized scanning. This determines * the pattern that will be used. * @param object the object to scan * @param trace the closure to use */ @Inline @Uninterruptible public static void scanObject(int code, Object object, TransitiveClosure trace) { scanObject(code, 0, object, trace, false); } @Inline @Uninterruptible private static void scanObject(int code, int id, Object object, TransitiveClosure trace, boolean specialize) { if (code == AE_PATTERN_0x0) { ; } else if (code == AE_PATTERN_0x1) { SpecializedScanMethod.pattern(0x1,object,trace); } else if (code == AE_PATTERN_0x7) { SpecializedScanMethod.pattern(0x7,object,trace); } else if (code == AE_PATTERN_0x3F) { SpecializedScanMethod.pattern(0x3F,object,trace); } else if (code == AE_FALLBACK) { if (specialize) { SpecializedScanMethod.invoke(id, object,trace); } else { SpecializedScanMethod.fallback(object, trace); } } else if (code == AE_REFARRAY) { SpecializedScanMethod.referenceArray(object,trace); } else if (code == AE_PATTERN_0x3) { SpecializedScanMethod.pattern(0x3,object,trace); } else if (code == AE_PATTERN_0x3D) { SpecializedScanMethod.pattern(0x3D,object,trace); } } }