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.mm.mminterface; 014 015import static org.jikesrvm.runtime.UnboxedSizeConstants.BYTES_IN_ADDRESS; 016 017import org.jikesrvm.classloader.RVMType; 018import org.jikesrvm.objectmodel.JavaHeader; 019import org.jikesrvm.objectmodel.ObjectModel; 020import org.mmtk.plan.TransitiveClosure; 021import org.vmmagic.pragma.Inline; 022import org.vmmagic.pragma.Uninterruptible; 023 024/** 025 * Supply and interpretation of values to be alignment-encoded into 026 * the TIB pointer of an object. 027 */ 028public class HandInlinedScanning { 029 030 public static final int AE_FALLBACK = (1 << AlignmentEncoding.FIELD_WIDTH) - 1; 031 public static final int AE_REFARRAY = AE_FALLBACK - 1; 032 033 public static final int AE_PATTERN_0x0 = 0; 034 public static final int AE_PATTERN_0x1 = 1; 035 public static final int AE_PATTERN_0x7 = 2; 036 public static final int AE_PATTERN_0x3F = 3; 037 public static final int AE_PATTERN_0x3 = 4; 038 public static final int AE_PATTERN_0x3D = 5; 039 040 private static final int FIELD0_OFFSET = 041 JavaHeader.objectStartOffset(RVMType.JavaLangObjectType) + 042 ObjectModel.computeScalarHeaderSize(RVMType.JavaLangObjectType); 043 044 private static final int FIELD1_OFFSET = FIELD0_OFFSET + BYTES_IN_ADDRESS; 045 private static final int FIELD2_OFFSET = FIELD1_OFFSET + BYTES_IN_ADDRESS; 046 private static final int FIELD3_OFFSET = FIELD2_OFFSET + BYTES_IN_ADDRESS; 047 private static final int FIELD4_OFFSET = FIELD3_OFFSET + BYTES_IN_ADDRESS; 048 private static final int FIELD5_OFFSET = FIELD4_OFFSET + BYTES_IN_ADDRESS; 049 050 /** Master switch */ 051 public static final boolean ENABLED = true; 052 053 public static int referenceArray() { 054 if (!ENABLED) 055 return AlignmentEncoding.ALIGN_CODE_NONE; 056 return AE_REFARRAY; 057 } 058 059 public static int primitiveArray() { 060 if (!ENABLED) 061 return AlignmentEncoding.ALIGN_CODE_NONE; 062 return AE_PATTERN_0x0; 063 } 064 065 public static int fallback() { 066 if (!ENABLED) 067 return AlignmentEncoding.ALIGN_CODE_NONE; 068 return AE_FALLBACK; 069 } 070 071 public static int scalar(int[] offsets) { 072 if (!ENABLED) 073 return AlignmentEncoding.ALIGN_CODE_NONE; 074 if (offsets.length == 0) { 075 return AE_PATTERN_0x0; 076 } 077 if (offsets.length == 1) { 078 if (offsets[0] == FIELD0_OFFSET) 079 return AE_PATTERN_0x1; 080 } 081// if (offsets.length == 2) { 082// if (offsets[0] == FIELD0_OFFSET && 083// offsets[1] == FIELD1_OFFSET) 084// return AE_PATTERN_0x3; 085// } 086 if (offsets.length == 3) { 087 if (offsets[0] == FIELD0_OFFSET && 088 offsets[1] == FIELD1_OFFSET && 089 offsets[2] == FIELD2_OFFSET) 090 return AE_PATTERN_0x7; 091 } 092// if (offsets.length == 5) { 093// if (offsets[0] == FIELD0_OFFSET && 094// offsets[1] == FIELD2_OFFSET && 095// offsets[2] == FIELD3_OFFSET && 096// offsets[3] == FIELD4_OFFSET && 097// offsets[4] == FIELD5_OFFSET) 098// return AE_PATTERN_0x3D; 099// } 100 if (offsets.length == 6) { 101 if (offsets[0] == FIELD0_OFFSET && 102 offsets[1] == FIELD1_OFFSET && 103 offsets[2] == FIELD2_OFFSET && 104 offsets[3] == FIELD3_OFFSET && 105 offsets[4] == FIELD4_OFFSET && 106 offsets[5] == FIELD5_OFFSET) 107 return AE_PATTERN_0x3F; 108 } 109 return AE_FALLBACK; 110 } 111 112 /** 113 * Hand-inlined scanning of objects. The cases of the conditional 114 * are ordered in descending frequency of patterns. 115 * 116 * This entry point falls back to specialized scanning if it is enabled. 117 * 118 * @param code the code to use for specialized scanning. This determines 119 * the pattern that will be used. 120 * @param id the id of the specialized scan method 121 * @param object the object to scan 122 * @param trace the closure to use 123 */ 124 @Inline 125 @Uninterruptible 126 public static void scanObject(int code, int id, Object object, TransitiveClosure trace) { 127 scanObject(code, id, object, trace, SpecializedScanMethod.ENABLED); 128 } 129 130 /** 131 * Hand-inlined scanning of objects. The cases of the conditional 132 * are ordered in descending frequency of patterns. 133 * <p> 134 * This entry point does not fall back to specialized scanning. 135 * 136 * @param code the code to use for specialized scanning. This determines 137 * the pattern that will be used. 138 * @param object the object to scan 139 * @param trace the closure to use 140 */ 141 @Inline 142 @Uninterruptible 143 public static void scanObject(int code, Object object, TransitiveClosure trace) { 144 scanObject(code, 0, object, trace, false); 145 } 146 147 @Inline 148 @Uninterruptible 149 private static void scanObject(int code, int id, Object object, TransitiveClosure trace, boolean specialize) { 150 if (code == AE_PATTERN_0x0) { 151 ; 152 } else if (code == AE_PATTERN_0x1) { 153 SpecializedScanMethod.pattern(0x1,object,trace); 154 } else if (code == AE_PATTERN_0x7) { 155 SpecializedScanMethod.pattern(0x7,object,trace); 156 } else if (code == AE_PATTERN_0x3F) { 157 SpecializedScanMethod.pattern(0x3F,object,trace); 158 } else if (code == AE_FALLBACK) { 159 if (specialize) { 160 SpecializedScanMethod.invoke(id, object,trace); 161 } else { 162 SpecializedScanMethod.fallback(object, trace); 163 } 164 } else if (code == AE_REFARRAY) { 165 SpecializedScanMethod.referenceArray(object,trace); 166 } else if (code == AE_PATTERN_0x3) { 167 SpecializedScanMethod.pattern(0x3,object,trace); 168 } else if (code == AE_PATTERN_0x3D) { 169 SpecializedScanMethod.pattern(0x3D,object,trace); 170 } 171 } 172}