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    }