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 }