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