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.VM;
016 import org.jikesrvm.Constants;
017 import org.jikesrvm.SizeConstants;
018 import org.jikesrvm.ArchitectureSpecific.CodeArray;
019 import org.jikesrvm.mm.mminterface.MemoryManager;
020 import org.jikesrvm.objectmodel.TIB;
021 import org.jikesrvm.runtime.RuntimeEntrypoints;
022 import org.jikesrvm.runtime.Statics;
023 import org.vmmagic.pragma.Entrypoint;
024 import org.vmmagic.pragma.Inline;
025 import org.vmmagic.pragma.NonMoving;
026 import org.vmmagic.pragma.Uninterruptible;
027 import org.vmmagic.unboxed.Offset;
028
029 /**
030 * A description of a java type.
031 *
032 * This class is the base of the java type system.
033 * To the three kinds of java objects
034 * (class-instances, array-instances, primitive-instances)
035 * there are three corresponding
036 * subclasses of RVMType: RVMClass, RVMArray, Primitive.
037 * <p>
038 * A RVMClass is constructed in four phases:
039 * <ul>
040 * <li> A "load" phase reads the ".class" file but does not attempt to
041 * examine any of the symbolic references present there. This is done
042 * by the RVMClass constructor as a result of a TypeReference being
043 * resolved.
044 *
045 * <li> A "resolve" phase follows symbolic references as needed to discover
046 * ancestry, to measure field sizes, and to allocate space in the jtoc
047 * for the class's static fields and methods.
048 *
049 * <li> An "instantiate" phase initializes and
050 * installs the type information block and static methods.
051 *
052 * <li> An "initialize" phase runs the class's static initializer.
053 * </ul>
054 *
055 * RVMArray's are constructed in a similar fashion.
056 *
057 * Primitive's are constructed ab initio.
058 * Their "resolution", "instantiation", and "initialization" phases
059 * are no-ops.
060 */
061 @NonMoving
062 public abstract class RVMType extends AnnotatedElement
063 implements ClassLoaderConstants, SizeConstants, Constants {
064
065 /** Next space in the the type array */
066 private static int nextId = 1;
067
068 /**
069 * 2^LOG_ROW_SIZE is the number of elements per row
070 */
071 private static final int LOG_ROW_SIZE = 10;
072 /**
073 * Mask to ascertain row from id number
074 */
075 private static final int ROW_MASK = (1 << LOG_ROW_SIZE)-1;
076 /** All types */
077 private static RVMType[][] types = new RVMType[1][1 << LOG_ROW_SIZE];
078
079 /** Canonical representation of no fields */
080 protected static final RVMField[] emptyVMField = new RVMField[0];
081 /** Canonical representation of no methods */
082 protected static final RVMMethod[] emptyVMMethod = new RVMMethod[0];
083 /** Canonical representation of no VM classes */
084 protected static final RVMClass[] emptyVMClass = new RVMClass[0];
085
086 /*
087 * We hold on to a number of special types here for easy access.
088 */
089 public static final Primitive VoidType;
090 public static final Primitive BooleanType;
091 public static final Primitive ByteType;
092 public static final Primitive ShortType;
093 public static final Primitive IntType;
094 public static final Primitive LongType;
095 public static final Primitive FloatType;
096 public static final Primitive DoubleType;
097 public static final Primitive CharType;
098 public static final RVMClass JavaLangObjectType;
099 public static final RVMArray JavaLangObjectArrayType;
100 public static final RVMClass JavaLangClassType;
101 public static final RVMClass JavaLangThrowableType;
102 public static final RVMClass JavaLangStringType;
103 public static final RVMClass JavaLangCloneableType;
104 public static final RVMClass JavaIoSerializableType;
105 public static final RVMClass JavaLangRefReferenceType;
106 public static final RVMField JavaLangRefReferenceReferenceField;
107 public static final RVMClass MagicType;
108 public static final UnboxedType WordType;
109 public static final RVMArray WordArrayType;
110 public static final UnboxedType AddressType;
111 public static final RVMArray AddressArrayType;
112 public static final RVMClass ObjectReferenceType;
113 public static final RVMArray ObjectReferenceArrayType;
114 public static final UnboxedType OffsetType;
115 public static final RVMArray OffsetArrayType;
116 public static final UnboxedType ExtentType;
117 public static final RVMArray ExtentArrayType;
118 public static final UnboxedType CodeType;
119 public static final RVMArray CodeArrayType;
120 public static final RVMClass TIBType;
121 public static final RVMClass ITableType;
122 public static final RVMClass ITableArrayType;
123 public static final RVMClass IMTType;
124 public static final RVMClass FunctionTableType;
125 public static final RVMClass LinkageTripletTableType;
126
127 static {
128 // Primitive types
129 VoidType = TypeReference.Void.resolve().asPrimitive();
130 BooleanType = TypeReference.Boolean.resolve().asPrimitive();
131 ByteType = TypeReference.Byte.resolve().asPrimitive();
132 ShortType = TypeReference.Short.resolve().asPrimitive();
133 IntType = TypeReference.Int.resolve().asPrimitive();
134 LongType = TypeReference.Long.resolve().asPrimitive();
135 FloatType = TypeReference.Float.resolve().asPrimitive();
136 DoubleType = TypeReference.Double.resolve().asPrimitive();
137 CharType = TypeReference.Char.resolve().asPrimitive();
138 // Jikes RVM primitives
139 AddressType = TypeReference.Address.resolve().asUnboxedType();
140 WordType = TypeReference.Word.resolve().asUnboxedType();
141 OffsetType = TypeReference.Offset.resolve().asUnboxedType();
142 ExtentType = TypeReference.Extent.resolve().asUnboxedType();
143 CodeType = TypeReference.Code.resolve().asUnboxedType();
144 ObjectReferenceType = TypeReference.ObjectReference.resolve().asClass();
145 // Jikes RVM classes
146 MagicType = TypeReference.Magic.resolve().asClass();
147 // Array types
148 CodeArrayType = TypeReference.CodeArray.resolve().asArray();
149 WordArrayType = TypeReference.WordArray.resolve().asArray();
150 AddressArrayType = TypeReference.AddressArray.resolve().asArray();
151 ObjectReferenceArrayType = TypeReference.ObjectReferenceArray.resolve().asArray();
152 OffsetArrayType = TypeReference.OffsetArray.resolve().asArray();
153 ExtentArrayType = TypeReference.ExtentArray.resolve().asArray();
154 // Runtime Tables
155 TIBType = TypeReference.TIB.resolve().asClass();
156 ITableType = TypeReference.ITable.resolve().asClass();
157 ITableArrayType = TypeReference.ITableArray.resolve().asClass();
158 IMTType = TypeReference.IMT.resolve().asClass();
159 FunctionTableType = TypeReference.FunctionTable.resolve().asClass();
160 LinkageTripletTableType = TypeReference.LinkageTripletTable.resolve().asClass();
161 // Java clases
162 JavaLangObjectType = TypeReference.JavaLangObject.resolve().asClass();
163 JavaLangObjectArrayType = TypeReference.JavaLangObjectArray.resolve().asArray();
164 JavaLangClassType = TypeReference.JavaLangClass.resolve().asClass();
165 JavaLangThrowableType = TypeReference.JavaLangThrowable.resolve().asClass();
166 JavaLangStringType = TypeReference.JavaLangString.resolve().asClass();
167 JavaLangCloneableType = TypeReference.JavaLangCloneable.resolve().asClass();
168 JavaIoSerializableType = TypeReference.JavaIoSerializable.resolve().asClass();
169 JavaLangRefReferenceType = TypeReference.JavaLangRefReference.resolve().asClass();
170 JavaLangRefReferenceReferenceField = JavaLangRefReferenceType.findDeclaredField(Atom.findAsciiAtom("_referent"));
171 }
172
173 /**
174 * Canonical type reference for this RVMType instance
175 */
176 protected final TypeReference typeRef;
177
178 /**
179 * Type id -- used to index into typechecking datastructures
180 */
181 @Entrypoint
182 protected final int id;
183
184 /**
185 * index of jtoc slot that has type information block for this RVMType
186 */
187 protected final int tibOffset;
188
189 /**
190 * instance of java.lang.Class corresponding to this type
191 */
192 private final Class<?> classForType;
193
194 /**
195 * Number of [ in descriptor for arrays; -1 for primitives; 0 for
196 * classes. NB this field must appear in all Types for fast type
197 * checks (See {@link org.jikesrvm.compilers.opt.hir2lir.DynamicTypeCheckExpansion}).
198 */
199 @Entrypoint
200 protected final int dimension;
201 /**
202 * Number of superclasses to Object. Known immediately for
203 * primitives and arrays, but only after resolving for classes. NB
204 * this field must appear in all Types for fast object array
205 * store checks (See {@link org.jikesrvm.compilers.opt.hir2lir.DynamicTypeCheckExpansion}).
206 */
207 @Entrypoint
208 protected int depth;
209 /**
210 * cached RVMArray that corresponds to arrays of this type.
211 * (null ->> not created yet).
212 */
213 private RVMArray cachedElementType;
214
215 /**
216 * The superclass ids for this type.
217 */
218 protected short[] superclassIds;
219
220 /**
221 * The interface implementation array for this type.
222 */
223 protected int[] doesImplement;
224
225 /**
226 * Create an instance of a {@link RVMType}
227 * @param typeRef The canonical type reference for this type.
228 * @param classForType The java.lang.Class representation
229 * @param dimension The dimensionality
230 * @param annotations array of runtime visible annotations
231 */
232 protected RVMType(TypeReference typeRef, Class<?> classForType, int dimension, RVMAnnotation[] annotations) {
233 super(annotations);
234 this.typeRef = typeRef;
235 this.tibOffset = Statics.allocateReferenceSlot(false).toInt();
236 this.id = nextId(this);
237 this.classForType = classForType;
238 this.dimension = dimension;
239
240 /* install partial type information block (no method dispatch table) for use in type checking. */
241 TIB tib = MemoryManager.newTIB(0);
242 tib.setType(this);
243 Statics.setSlotContents(getTibOffset(), tib);
244 }
245
246 /**
247 * Create an instance of a {@link RVMType}
248 * @param typeRef The canonical type reference for this type.
249 * @param dimension The dimensionality
250 * @param annotations array of runtime visible annotations
251 */
252 protected RVMType(TypeReference typeRef, int dimension, RVMAnnotation[] annotations) {
253 super(annotations);
254 this.typeRef = typeRef;
255 this.tibOffset = Statics.allocateReferenceSlot(false).toInt();
256 this.id = nextId(this);
257 this.classForType = createClassForType(this, typeRef);
258 this.dimension = dimension;
259
260 /* install partial type information block (no method dispatch table) for use in type checking. */
261 TIB tib = MemoryManager.newTIB(0);
262 tib.setType(this);
263 Statics.setSlotContents(getTibOffset(), tib);
264 }
265
266 /**
267 * Canonical type reference for this type.
268 */
269 @Uninterruptible
270 public final TypeReference getTypeRef() {
271 return typeRef;
272 }
273
274 /**
275 * Get the numeric identifier for this type
276 */
277 @Uninterruptible
278 public final int getId() {
279 return id;
280 }
281
282 /**
283 * Instance of java.lang.Class corresponding to this type.
284 * This is commonly used for reflection.
285 */
286 public final Class<?> getClassForType() {
287 if (VM.runningVM) {
288 // Resolve the class so that we don't need to resolve it
289 // in reflection code
290 if (!isResolved()) {
291 resolve();
292 }
293 return classForType;
294 } else {
295 return createClassForType(this, getTypeRef());
296 }
297 }
298
299 /**
300 * Instance of java.lang.Class corresponding to this type.
301 * This is commonly used for reflection.
302 */
303 @Uninterruptible
304 public final Class<?> getResolvedClassForType() {
305 // Resolve the class so that we don't need to resolve it
306 // in reflection code
307 if (VM.VerifyAssertions) VM._assert(VM.runningVM && isResolved());
308 return classForType;
309 }
310
311 /**
312 * Get offset of tib slot from start of jtoc, in bytes.
313 */
314 @Uninterruptible
315 public final Offset getTibOffset() {
316 return Offset.fromIntSignExtend(tibOffset);
317 }
318
319 /**
320 * Get the class loader for this type
321 */
322 @Uninterruptible
323 public final ClassLoader getClassLoader() {
324 return typeRef.getClassLoader();
325 }
326
327 /**
328 * Should assertions be enabled on this type?
329 * @return false
330 */
331 public boolean getDesiredAssertionStatus() {
332 return false;
333 }
334
335 /**
336 * Descriptor for this type.
337 * For a class, something like "Ljava/lang/String;".
338 * For an array, something like "[I" or "[Ljava/lang/String;".
339 * For a primitive, something like "I".
340 */
341 @Uninterruptible
342 public final Atom getDescriptor() {
343 return typeRef.getName();
344 }
345
346 /**
347 * Define hashCode(), to allow use of consistent hash codes during
348 * bootImage writing and run-time
349 */
350 @Override
351 public final int hashCode() {
352 return typeRef.hashCode();
353 }
354
355 /**
356 * get number of superclasses to Object
357 * 0 java.lang.Object, Primitive, and Classes that are interfaces
358 * 1 for RVMArrays and classes that extend Object directly
359 */
360 @Uninterruptible
361 public abstract int getTypeDepth();
362
363 /**
364 * Reference Count GC: Is a reference of this type contained in
365 * another object inherently acyclic (without cycles) ?
366 */
367 @Uninterruptible
368 public abstract boolean isAcyclicReference();
369
370 /**
371 * Number of [ in descriptor for arrays; -1 for primitives; 0 for classes
372 */
373 @Uninterruptible
374 public abstract int getDimensionality();
375
376 /**
377 * @return this cast to a RVMClass
378 */
379 @Uninterruptible
380 public final RVMClass asClass() {
381 return (RVMClass) this;
382 }
383
384 /**
385 * @return this cast to a RVMArray
386 */
387 @Uninterruptible
388 public final RVMArray asArray() {
389 return (RVMArray) this;
390 }
391
392 /**
393 * @return this cast to a Primitive
394 */
395 @Uninterruptible
396 public final Primitive asPrimitive() {
397 return (Primitive) this;
398 }
399
400 /**
401 * @return this cast to a UnboxedType
402 */
403 @Uninterruptible
404 public final UnboxedType asUnboxedType() {
405 return (UnboxedType) this;
406 }
407 // Convenience methods.
408 //
409 /** @return is this type void? */
410 @Uninterruptible
411 public final boolean isVoidType() {
412 return this == VoidType;
413 }
414
415 /** @return is this type the primitive boolean? */
416 @Uninterruptible
417 public final boolean isBooleanType() {
418 return this == BooleanType;
419 }
420
421 /** @return is this type the primitive byte? */
422 @Uninterruptible
423 public final boolean isByteType() {
424 return this == ByteType;
425 }
426
427 /** @return is this type the primitive short? */
428 @Uninterruptible
429 public final boolean isShortType() {
430 return this == ShortType;
431 }
432
433 /** @return is this type the primitive int? */
434 @Uninterruptible
435 public final boolean isIntType() {
436 return this == IntType;
437 }
438
439 /** @return is this type the primitive long? */
440 @Uninterruptible
441 public final boolean isLongType() {
442 return this == LongType;
443 }
444
445 /** @return is this type the primitive float? */
446 @Uninterruptible
447 public final boolean isFloatType() {
448 return this == FloatType;
449 }
450
451 /** @return is this type the primitive double? */
452 @Uninterruptible
453 public final boolean isDoubleType() {
454 return this == DoubleType;
455 }
456
457 /** @return is this type the primitive char? */
458 @Uninterruptible
459 public final boolean isCharType() {
460 return this == CharType;
461 }
462
463 /**
464 * @return is this type the primitive int like? ie is it held as an
465 * int on the JVM stack
466 */
467 @Uninterruptible
468 public final boolean isIntLikeType() {
469 return isBooleanType() || isByteType() || isShortType() || isIntType() || isCharType();
470 }
471
472 /** @return is this type the class Object? */
473 @Uninterruptible
474 public final boolean isJavaLangObjectType() {
475 return this == JavaLangObjectType;
476 }
477
478 /** @return is this type the class Throwable? */
479 @Uninterruptible
480 public final boolean isJavaLangThrowableType() {
481 return this == JavaLangThrowableType;
482 }
483
484 /** @return is this type the class String? */
485 @Uninterruptible
486 public final boolean isJavaLangStringType() {
487 return this == JavaLangStringType;
488 }
489
490 /**
491 * Get array type corresponding to "this" array element type.
492 */
493 public final RVMArray getArrayTypeForElementType() {
494 if (cachedElementType == null) {
495 TypeReference tr = typeRef.getArrayTypeForElementType();
496 cachedElementType = tr.resolve().asArray();
497 /* Can't fail to resolve the type, because the element type already
498 exists (it is 'this') and the VM creates array types itself without
499 any possibility of error if the element type is already loaded. */
500 }
501 return cachedElementType;
502 }
503
504 /**
505 * get superclass id vector (@see DynamicTypeCheck)
506 */
507 @Uninterruptible
508 public final short[] getSuperclassIds() {
509 return superclassIds;
510 }
511
512 /**
513 * get doesImplement vector (@see DynamicTypeCheck)
514 */
515 @Uninterruptible
516 public final int[] getDoesImplement() {
517 return doesImplement;
518 }
519
520 /**
521 * Allocate entry in types array and add it (NB resize array if it's
522 * not long enough)
523 */
524 private static synchronized int nextId(RVMType it) {
525 int ans = nextId++;
526 int column = ans >> LOG_ROW_SIZE;
527 if (column >= types.length) {
528 RVMType[][] newTypes = new RVMType[column+1][];
529 for (int i = 0; i < types.length; i++) {
530 newTypes[i] = types[i];
531 }
532 newTypes[column] = new RVMType[1<<LOG_ROW_SIZE];
533 types = newTypes;
534 }
535 types[ans >> LOG_ROW_SIZE][ans & ROW_MASK] = it;
536 return ans;
537 }
538
539 /**
540 * How many types have been created?
541 * Only intended to be used by the bootimage writer!
542 */
543 @Uninterruptible
544 public static int numTypes() {
545 return nextId - 1;
546 }
547
548 /**
549 * Get the type for the given id
550 */
551 @Uninterruptible
552 public static RVMType getType(int id) {
553 return types[id >> LOG_ROW_SIZE][id & ROW_MASK];
554 }
555
556 /**
557 * Utility to create a java.lang.Class for the given type using the
558 * given type reference
559 */
560 protected static Class<?> createClassForType(RVMType type, TypeReference typeRef) {
561 if (VM.runningVM) {
562 return java.lang.JikesRVMSupport.createClass(type);
563 } else {
564 Exception x;
565 try {
566 Atom className = typeRef.getName();
567 if (className.isAnnotationClass()) {
568 return Class.forName(className.annotationClassToAnnotationInterface(), false, RVMType.class.getClassLoader());
569 } else if (className.isClassDescriptor()) {
570 return Class.forName(className.classNameFromDescriptor(), false, RVMType.class.getClassLoader());
571 } else {
572 String classNameString = className.toString();
573 if (classNameString.equals("V")) {
574 return void.class;
575 } else if(classNameString.equals("I")){
576 return int.class;
577 } else if(classNameString.equals("J")){
578 return long.class;
579 } else if(classNameString.equals("F")){
580 return float.class;
581 } else if(classNameString.equals("D")){
582 return double.class;
583 } else if(classNameString.equals("C")){
584 return char.class;
585 } else if(classNameString.equals("S")){
586 return short.class;
587 } else if(classNameString.equals("Z")){
588 return boolean.class;
589 } else if(classNameString.equals("B")){
590 return byte.class;
591 } else {
592 return Class.forName(classNameString.replace('/', '.'), false, RVMType.class.getClassLoader());
593 }
594 }
595 } catch (ClassNotFoundException e) { x = e; } catch (SecurityException e) { x = e; }
596 if (typeRef.isArrayType() && typeRef.getArrayElementType().isCodeType()) {
597 // fix up class for code array
598 return CodeArray.class;
599 } else if (!VM.runningVM) {
600 // Give a warning as this is probably a protection issue for
601 // the tool and JVM
602 VM.sysWriteln("Warning unable to find Java class for RVM type");
603 x.printStackTrace();
604 return null;
605 } else {
606 throw new Error("Unable to find Java class for RVM type", x);
607 }
608 }
609 }
610
611 /**
612 * Find specified virtual method description.
613 * @param memberName method name - something like "foo"
614 * @param memberDescriptor method descriptor - something like "I" or "()I"
615 * @return method description (null --> not found)
616 */
617 public final RVMMethod findVirtualMethod(Atom memberName, Atom memberDescriptor) {
618 if (VM.VerifyAssertions) VM._assert(isResolved());
619 RVMMethod[] methods = getVirtualMethods();
620 for (int i = 0, n = methods.length; i < n; ++i) {
621 RVMMethod method = methods[i];
622 if (method.getName() == memberName && method.getDescriptor() == memberDescriptor) {
623 return method;
624 }
625 }
626 return null;
627 }
628
629 /**
630 * Return the method at the given TIB slot
631 * @param slot the slot that contains the method
632 * @return the method at that slot
633 */
634 public final RVMMethod getTIBMethodAtSlot(int slot) {
635 int index = TIB.getVirtualMethodIndex(slot);
636 RVMMethod[] methods = getVirtualMethods();
637 if (VM.VerifyAssertions) VM._assert(methods[index].getOffset().toInt() == slot << LOG_BYTES_IN_ADDRESS);
638 return methods[index];
639 }
640 // Methods implemented in Primitive, RVMArray or RVMClass
641
642 /**
643 * Resolution status.
644 * If the class/array has been "resolved", then size and offset information is
645 * available by which the compiler can generate code to access this
646 * class/array's
647 * fields/methods via direct loads/stores/calls (rather than generating
648 * code to access fields/methods symbolically, via dynamic linking stubs).
649 * Primitives are always treated as "resolved".
650 */
651 @Uninterruptible
652 public abstract boolean isResolved();
653
654 /**
655 * Instantiation status.
656 * If the class/array has been "instantiated",
657 * then all its methods have been compiled
658 * and its type information block has been placed in the jtoc.
659 * Primitives are always treated as "instantiated".
660 */
661 @Uninterruptible
662 public abstract boolean isInstantiated();
663
664 /**
665 * Initialization status.
666 * If the class has been "initialized",
667 * then its <clinit> method has been executed.
668 * Arrays have no <clinit> methods so they become
669 * "initialized" immediately upon "instantiation".
670 * Primitives are always treated as "initialized".
671 */
672 @Uninterruptible
673 public abstract boolean isInitialized();
674
675 /**
676 * Only intended to be used by the BootImageWriter
677 */
678 public abstract void markAsBootImageClass();
679
680 /**
681 * Is this class part of the virtual machine's boot image?
682 */
683 @Uninterruptible
684 public abstract boolean isInBootImage();
685
686 /**
687 * Get the offset in instances of this type assigned to the thin lock word.
688 * Offset.max() if instances of this type do not have thin lock words.
689 */
690 @Uninterruptible
691 public abstract Offset getThinLockOffset();
692
693 /**
694 * @return whether or not this is an instance of RVMClass?
695 */
696 @Uninterruptible
697 public abstract boolean isClassType();
698
699 /**
700 * @return whether or not this is an instance of RVMArray?
701 */
702 @Uninterruptible
703 public abstract boolean isArrayType();
704
705 /**
706 * @return whether or not this is a primitive type
707 */
708 @Uninterruptible
709 public abstract boolean isPrimitiveType();
710
711 /**
712 * @return whether or not this is an unboxed type
713 */
714 @Uninterruptible
715 public abstract boolean isUnboxedType();
716
717 /**
718 * @return whether or not this is a reference (ie non-primitive) type.
719 */
720 @Uninterruptible
721 public abstract boolean isReferenceType();
722
723 /**
724 * @return whether type can be assigned to things of this RVMType
725 */
726 public boolean isAssignableFrom(RVMType type) {
727 return this == type || RuntimeEntrypoints.isAssignableWith(this, type);
728 }
729
730 /**
731 * Space required when this type is stored on the stack
732 * (or as a field), in words.
733 * Ie. 0, 1, or 2 words:
734 * <ul>
735 * <li> reference types (classes and arrays) require 1 word
736 * <li> void types require 0 words
737 * <li> long and double types require 2 words
738 * <li> all other primitive types require 1 word
739 * </ul>
740 */
741 @Uninterruptible
742 public abstract int getStackWords();
743
744 /**
745 * Number of bytes in memory required to represent the type
746 */
747 @Uninterruptible
748 public abstract int getMemoryBytes();
749
750 /**
751 * Cause resolution to take place.
752 * This will cause slots to be allocated in the jtoc.
753 */
754 public abstract void resolve();
755
756 /**
757 * This method is only called by the bootimage writer.
758 * It is called after {@link #resolve()} has been called on all
759 * bootimaage types but before {@link #instantiate()} has been called
760 * on any bootimaage type.
761 * This provides a hook to compute various summaries that cannot be computed before types
762 * are resolved.
763 */
764 public abstract void allBootImageTypesResolved();
765
766 /**
767 * Cause instantiation to take place.
768 * This will cause the class's methods to be compiled and slots in the
769 * jtoc to be filled-in.
770 */
771 public abstract void instantiate();
772
773 /**
774 * Cause initialization to take place.
775 * This will cause the class's <clinit> method to be executed.
776 */
777 public abstract void initialize();
778
779 /**
780 * Does this type override java.lang.Object.finalize()?
781 */
782 @Uninterruptible
783 public abstract boolean hasFinalizer();
784
785 /**
786 * Static fields of this class/array type.
787 */
788 public abstract RVMField[] getStaticFields();
789
790 /**
791 * Non-static fields of this class/array type
792 * (composed with supertypes, if any).
793 */
794 public abstract RVMField[] getInstanceFields();
795
796 /**
797 * Statically dispatched methods of this class/array type.
798 */
799 public abstract RVMMethod[] getStaticMethods();
800
801 /**
802 * Virtually dispatched methods of this class/array type
803 * (composed with supertypes, if any).
804 */
805 public abstract RVMMethod[] getVirtualMethods();
806
807 /**
808 * Runtime type information for this class/array type.
809 */
810 @Uninterruptible
811 public abstract TIB getTypeInformationBlock();
812
813 /**
814 * Set the specialized method for a class or array.
815 */
816 public final void setSpecializedMethod(int id, CodeArray code) {
817 getTypeInformationBlock().setSpecializedMethod(id, code);
818 }
819
820 /**
821 * The memory manager's allocator id for this type.
822 */
823 private int mmAllocator;
824
825 /**
826 * Record the allocator information the memory manager holds about this type.
827 *
828 * @param allocator the allocator to record
829 */
830 public final void setMMAllocator(int allocator) {
831 this.mmAllocator = allocator;
832 }
833
834 /**
835 * This returns the allocator id as supplied by the memory manager.
836 * The method is located here as this is the only common superclass of RVMArray
837 * and RVMClass, and due to performance reasons this needs to be a non-abstract
838 * method. For Primitive this field is unused.
839 *
840 * @return the allocator id previously recorded.
841 */
842 @Uninterruptible
843 @Inline
844 public final int getMMAllocator() {
845 return mmAllocator;
846 }
847
848 /**
849 * Is this field a type that must never move?
850 */
851 public boolean isNonMoving() {
852 return hasNonMovingAnnotation();
853 }
854 }