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