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.classloader;
014    
015    import org.jikesrvm.Constants;
016    import org.jikesrvm.VM;
017    import org.jikesrvm.objectmodel.TIB;
018    import org.vmmagic.pragma.NonMoving;
019    import org.vmmagic.pragma.Pure;
020    import org.vmmagic.pragma.Uninterruptible;
021    import org.vmmagic.unboxed.Offset;
022    
023    /**
024     * Description of an Unboxed Magic type.
025     *
026     * Currently, unboxed types are restricted to be values that can fit in a single machines word.
027     *
028     * @see RVMType
029     * @see RVMClass
030     * @see RVMArray
031     * @see Primitive
032     */
033    @NonMoving
034    public final class UnboxedType extends RVMType implements Constants, ClassLoaderConstants {
035      /**
036       * The pretty (external) name for this Unboxed type.
037       */
038      private final Atom name;
039    
040      /**
041       * How many slots in the Java Expression Stack does it take
042       * to hold a value of this primitive type?
043       */
044      private final int stackWords;
045    
046      /**
047       * How many bytes in memory does it take to hold a value of this
048       * primitive type?
049       */
050      private final int memoryBytes;
051    
052      /**
053       * Name - something like "int".
054       */
055      @Override
056      @Pure
057      public String toString() {
058        return name.toString();
059      }
060    
061      /**
062       * Constructor
063       * @param tr   The canonical type reference for this primitive
064       * @param classForType The java.lang.Class representation
065       * @param name The name for this primitive
066       * @param stackWords The stack slots used by this primitive
067       * @param memoryBytes The bytes in memory used by this primitive
068       */
069      private UnboxedType(TypeReference tr, Class<?> classForType, Atom name, int stackWords, int memoryBytes) {
070        super(tr,    // type reference
071              classForType, // j.l.Class representation
072              -1,    // dimensionality
073              null  // runtime visible annotations
074        );
075        this.name = name;
076        this.stackWords = stackWords;
077        this.memoryBytes = memoryBytes;
078        this.depth = 0;
079      }
080    
081      /**
082       * Create an instance of a {@link UnboxedType}
083       * @param tr   The canonical type reference for this primitive
084       */
085      static UnboxedType createUnboxedType(TypeReference tr) {
086        Atom name;
087        int stackWords = 1;
088        int memoryBytes;
089        Class<?> classForType;
090    
091        name = tr.getName();
092        if (tr == TypeReference.Address ||
093            tr == TypeReference.Word ||
094            tr == TypeReference.Offset ||
095            tr == TypeReference.Extent) {
096          memoryBytes = BYTES_IN_ADDRESS;
097        } else if (tr == TypeReference.Code) {
098          memoryBytes = VM.BuildForIA32 ? BYTES_IN_BYTE : BYTES_IN_INT;
099        } else {
100          throw new Error("Unknown unboxed type " + tr.getName());
101        }
102        try {
103          classForType = Class.forName(name.classNameFromDescriptor());
104        } catch (Exception e) {
105          throw new Error("Error getting java.lang.Class wrapper for type " + name.classNameFromDescriptor());
106        }
107    
108        return new UnboxedType(tr, classForType, name, stackWords, memoryBytes);
109      }
110    
111      /**
112       * get number of superclasses to Object
113       * @return 0
114       */
115      @Override
116      @Pure
117      @Uninterruptible
118      public int getTypeDepth() {
119        return 0;
120      }
121    
122      /**
123       * Reference Count GC: Is a reference of this type contained in
124       * another object inherently acyclic (without cycles) ?
125       * @return true
126       */
127      @Override
128      @Pure
129      @Uninterruptible
130      public boolean isAcyclicReference() {
131        return true;
132      }
133    
134      /**
135       * Number of [ in descriptor for arrays; -1 for primitives; 0 for
136       * classes
137       * @return -1;
138       */
139      @Override
140      @Pure
141      @Uninterruptible
142      public int getDimensionality() {
143        return -1;
144      }
145    
146      /**
147       * Resolution status.
148       * @return true
149       */
150      @Override
151      @Uninterruptible
152      public boolean isResolved() {
153        return true;
154      }
155    
156      /**
157       * Instantiation status.
158       * @return true
159       */
160      @Override
161      @Pure
162      @Uninterruptible
163      public boolean isInstantiated() {
164        return true;
165      }
166    
167      /**
168       * Initialization status.
169       * @return true
170       */
171      @Override
172      @Pure
173      @Uninterruptible
174      public boolean isInitialized() {
175        return true;
176      }
177    
178      /**
179       * Only intended to be used by the BootImageWriter
180       */
181      @Override
182      public void markAsBootImageClass() {}
183    
184      /**
185       * Is this class part of the virtual machine's boot image?
186       */
187      @Override
188      @Pure
189      @Uninterruptible
190      public boolean isInBootImage() {
191        return true;
192      }
193    
194      /**
195       * Get the offset in instances of this type assigned to the thin
196       * lock word.  Offset.max() if instances of this type do not have thin lock
197       * words.
198       * @return Offset.max();
199       */
200      @Override
201      @Pure
202      @Uninterruptible
203      public Offset getThinLockOffset() {
204        if (VM.VerifyAssertions) VM._assert(NOT_REACHED);
205        return Offset.max();
206      }
207    
208      /**
209       * Whether or not this is an instance of RVMClass?
210       * @return false
211       */
212      @Override
213      @Pure
214      @Uninterruptible
215      public boolean isClassType() {
216        return false;
217      }
218    
219      /**
220       * Whether or not this is an instance of RVMArray?
221       * @return false
222       */
223      @Override
224      @Pure
225      @Uninterruptible
226      public boolean isArrayType() {
227        return false;
228      }
229    
230      /**
231       * Whether or not this is a primitive type
232       * @return true
233       */
234      @Override
235      @Pure
236      @Uninterruptible
237      public boolean isPrimitiveType() {
238        return false;
239      }
240    
241      /**
242       * @return whether or not this is a reference (ie non-primitive) type.
243       */
244      @Override
245      @Pure
246      @Uninterruptible
247      public boolean isReferenceType() {
248        return false;
249      }
250    
251      /**
252       * @return whether or not this is an unboxed type
253       */
254      @Override
255      @Pure
256      @Uninterruptible
257      public boolean isUnboxedType() {
258        return true;
259      }
260    
261      /**
262       * Stack space requirement in words.
263       */
264      @Override
265      @Pure
266      @Uninterruptible
267      public int getStackWords() {
268        return stackWords;
269      }
270    
271      /**
272       * Space required in memory in bytes.
273       */
274      @Override
275      @Pure
276      @Uninterruptible
277      public int getMemoryBytes() {
278        return memoryBytes;
279      }
280    
281      /**
282       * Cause resolution to take place.
283       */
284      @Override
285      @Pure
286      public void resolve() {}
287    
288      @Override
289      public void allBootImageTypesResolved() { }
290    
291      /**
292       * Cause instantiation to take place.
293       */
294      @Override
295      @Pure
296      public void instantiate() {}
297    
298      /**
299       * Cause initialization to take place.
300       */
301      @Override
302      @Pure
303      public void initialize() {}
304    
305      /**
306       * Does this type override java.lang.Object.finalize()?
307       */
308      @Override
309      @Pure
310      @Uninterruptible
311      public boolean hasFinalizer() {
312        return false;
313      }
314    
315      /*
316       * Primitives are not first class objects -
317       * but the implementation of reflection is cleaner if
318       * we pretend that they are and provide dummy implementations of
319       * the following methods
320       */
321    
322      /**
323       * Static fields of this class/array type.
324       * @return zero length array
325       */
326      @Override
327      @Pure
328      public RVMField[] getStaticFields() {
329        return emptyVMField;
330      }
331    
332      /**
333       * Non-static fields of this class/array type
334       * (composed with supertypes, if any).
335       * @return zero length array
336       */
337      @Override
338      @Pure
339      public RVMField[] getInstanceFields() {
340        return emptyVMField;
341      }
342    
343      /**
344       * Statically dispatched methods of this class/array type.
345       * @return zero length array
346       */
347      @Override
348      @Pure
349      public RVMMethod[] getStaticMethods() {
350        return emptyVMMethod;
351      }
352    
353      /**
354       * Virtually dispatched methods of this class/array type
355       * (composed with supertypes, if any).
356       * @return zero length array
357       */
358      @Override
359      @Pure
360      public RVMMethod[] getVirtualMethods() {
361        return emptyVMMethod;
362      }
363    
364      /**
365       * Runtime type information for this class/array type.
366       */
367      @Override
368      @Uninterruptible
369      public TIB getTypeInformationBlock() {
370        if (VM.VerifyAssertions) VM._assert(NOT_REACHED);
371        return null;
372      }
373    }