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.<p> 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 * @return 0 because unboxed types do not extend java.lang.Object 113 */ 114 @Override 115 @Pure 116 @Uninterruptible 117 public int getTypeDepth() { 118 return 0; 119 } 120 121 /** 122 * @return <code>true</code> because unboxed types cannot contain any references 123 */ 124 @Override 125 @Pure 126 @Uninterruptible 127 public boolean isAcyclicReference() { 128 return true; 129 } 130 131 /** 132 * @return -1 133 */ 134 @Override 135 @Pure 136 @Uninterruptible 137 public int getDimensionality() { 138 return -1; 139 } 140 141 /** 142 * @return <code>true</code> because unboxed types are always considered 143 * resolved" 144 */ 145 @Override 146 @Uninterruptible 147 public boolean isResolved() { 148 return true; 149 } 150 151 /** 152 * @return <code>true</code> because unboxed types are always considered 153 * "instantiated" 154 */ 155 @Override 156 @Pure 157 @Uninterruptible 158 public boolean isInstantiated() { 159 return true; 160 } 161 162 /** 163 * @return <code>true</code> because unboxed types are always considered 164 * "initialized" 165 */ 166 @Override 167 @Pure 168 @Uninterruptible 169 public boolean isInitialized() { 170 return true; 171 } 172 173 @Override 174 public void markAsBootImageClass() {} 175 176 /** 177 * @return <code>true</code>. All unboxed types are included in the bootimage 178 * because they are needed for starting Jikes RVM. 179 */ 180 @Override 181 @Pure 182 @Uninterruptible 183 public boolean isInBootImage() { 184 return true; 185 } 186 187 /** 188 * @return <code>Offset.max()</code> 189 */ 190 @Override 191 @Pure 192 @Uninterruptible 193 public Offset getThinLockOffset() { 194 if (VM.VerifyAssertions) VM._assert(NOT_REACHED); 195 return Offset.max(); 196 } 197 198 /** 199 * @return <code>false</code> 200 */ 201 @Override 202 @Pure 203 @Uninterruptible 204 public boolean isClassType() { 205 return false; 206 } 207 208 /** 209 * @return <code>false</code> 210 */ 211 @Override 212 @Pure 213 @Uninterruptible 214 public boolean isArrayType() { 215 return false; 216 } 217 218 /** 219 * @return <code>false</code> 220 */ 221 @Override 222 @Pure 223 @Uninterruptible 224 public boolean isPrimitiveType() { 225 return false; 226 } 227 228 /** 229 * @return <code>false</code> 230 */ 231 @Override 232 @Pure 233 @Uninterruptible 234 public boolean isReferenceType() { 235 return false; 236 } 237 238 /** 239 * @return <code>true</code> 240 */ 241 @Override 242 @Pure 243 @Uninterruptible 244 public boolean isUnboxedType() { 245 return true; 246 } 247 248 /** 249 * Stack space requirement in words. 250 */ 251 @Override 252 @Pure 253 @Uninterruptible 254 public int getStackWords() { 255 return stackWords; 256 } 257 258 @Override 259 @Pure 260 @Uninterruptible 261 public int getMemoryBytes() { 262 return memoryBytes; 263 } 264 265 /** 266 * Cause resolution to take place. This is a no-op for unboxed types. 267 * @see UnboxedType#isResolved() 268 */ 269 @Override 270 @Pure 271 public void resolve() {} 272 273 @Override 274 public void allBootImageTypesResolved() { } 275 276 /** 277 * Cause instantiation to take place. This is a no-op for unboxed types. 278 * @see UnboxedType#isInstantiated() 279 */ 280 @Override 281 @Pure 282 public void instantiate() {} 283 284 /** 285 * Cause initialization to take place. This is a no-op for unboxed types. 286 * @see UnboxedType#isInitialized() 287 */ 288 @Override 289 @Pure 290 public void initialize() {} 291 292 /** 293 * @return false 294 */ 295 @Override 296 @Pure 297 @Uninterruptible 298 public boolean hasFinalizer() { 299 return false; 300 } 301 302 /* 303 * Primitives are not first class objects - 304 * but the implementation of reflection is cleaner if 305 * we pretend that they are and provide dummy implementations of 306 * the following methods 307 */ 308 309 /** 310 * Static fields of this class/array type. 311 * @return zero length array 312 */ 313 @Override 314 @Pure 315 public RVMField[] getStaticFields() { 316 return emptyVMField; 317 } 318 319 /** 320 * Non-static fields of this class/array type 321 * (composed with supertypes, if any). 322 * @return zero length array 323 */ 324 @Override 325 @Pure 326 public RVMField[] getInstanceFields() { 327 return emptyVMField; 328 } 329 330 /** 331 * Statically dispatched methods of this class/array type. 332 * @return zero length array 333 */ 334 @Override 335 @Pure 336 public RVMMethod[] getStaticMethods() { 337 return emptyVMMethod; 338 } 339 340 /** 341 * Virtually dispatched methods of this class/array type 342 * (composed with supertypes, if any). 343 * @return zero length array 344 */ 345 @Override 346 @Pure 347 public RVMMethod[] getVirtualMethods() { 348 return emptyVMMethod; 349 } 350 351 /** 352 * Runtime type information for this class/array type. 353 */ 354 @Override 355 @Uninterruptible 356 public TIB getTypeInformationBlock() { 357 if (VM.VerifyAssertions) VM._assert(NOT_REACHED); 358 return null; 359 } 360 }