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