0
|
1 /*
|
|
2 * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved.
|
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 *
|
|
5 * This code is free software; you can redistribute it and/or modify it
|
|
6 * under the terms of the GNU General Public License version 2 only, as
|
|
7 * published by the Free Software Foundation.
|
|
8 *
|
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 * version 2 for more details (a copy is included in the LICENSE file that
|
|
13 * accompanied this code).
|
|
14 *
|
|
15 * You should have received a copy of the GNU General Public License version
|
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 *
|
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 // type hierarchy
|
|
26 class ValueType;
|
|
27 class VoidType;
|
|
28 class IntType;
|
|
29 class IntConstant;
|
|
30 class IntInterval;
|
|
31 class LongType;
|
|
32 class LongConstant;
|
|
33 class FloatType;
|
|
34 class FloatConstant;
|
|
35 class DoubleType;
|
|
36 class DoubleConstant;
|
|
37 class ObjectType;
|
|
38 class ObjectConstant;
|
|
39 class ArrayType;
|
|
40 class ArrayConstant;
|
|
41 class InstanceType;
|
|
42 class InstanceConstant;
|
|
43 class ClassType;
|
|
44 class ClassConstant;
|
|
45 class AddressType;
|
|
46 class AddressConstant;
|
|
47 class IllegalType;
|
|
48
|
|
49
|
|
50 // predefined types
|
|
51 extern VoidType* voidType;
|
|
52 extern IntType* intType;
|
|
53 extern LongType* longType;
|
|
54 extern FloatType* floatType;
|
|
55 extern DoubleType* doubleType;
|
|
56 extern ObjectType* objectType;
|
|
57 extern ArrayType* arrayType;
|
|
58 extern InstanceType* instanceType;
|
|
59 extern ClassType* classType;
|
|
60 extern AddressType* addressType;
|
|
61 extern IllegalType* illegalType;
|
|
62
|
|
63
|
|
64 // predefined constants
|
|
65 extern IntConstant* intZero;
|
|
66 extern IntConstant* intOne;
|
|
67 extern ObjectConstant* objectNull;
|
|
68
|
|
69
|
|
70 // tags
|
|
71 enum ValueTag {
|
|
72 // all legal tags must come first
|
|
73 intTag,
|
|
74 longTag,
|
|
75 floatTag,
|
|
76 doubleTag,
|
|
77 objectTag,
|
|
78 addressTag,
|
|
79 number_of_legal_tags,
|
|
80 // all other tags must follow afterwards
|
|
81 voidTag = number_of_legal_tags,
|
|
82 illegalTag,
|
|
83 number_of_tags
|
|
84 };
|
|
85
|
|
86
|
|
87 class ValueType: public CompilationResourceObj {
|
|
88 private:
|
|
89 const int _size;
|
|
90 const ValueTag _tag;
|
|
91 ValueType();
|
|
92 protected:
|
|
93 ValueType(ValueTag tag, int size): _tag(tag), _size(size) {}
|
|
94
|
|
95 public:
|
|
96 // initialization
|
|
97 static void initialize();
|
|
98
|
|
99 // accessors
|
|
100 virtual ValueType* base() const = 0; // the 'canonical' type (e.g., intType for an IntConstant)
|
|
101 ValueTag tag() const { return _tag; } // the 'canonical' tag (useful for type matching)
|
|
102 int size() const { // the size of an object of the type in words
|
|
103 assert(_size > -1, "shouldn't be asking for size");
|
|
104 return _size;
|
|
105 }
|
|
106 virtual const char tchar() const = 0; // the type 'character' for printing
|
|
107 virtual const char* name() const = 0; // the type name for printing
|
|
108 virtual bool is_constant() const { return false; }
|
|
109
|
|
110 // testers
|
|
111 bool is_void() { return tag() == voidTag; }
|
|
112 bool is_int() { return tag() == intTag; }
|
|
113 bool is_long() { return tag() == longTag; }
|
|
114 bool is_float() { return tag() == floatTag; }
|
|
115 bool is_double() { return tag() == doubleTag; }
|
|
116 bool is_object() { return as_ObjectType() != NULL; }
|
|
117 bool is_array() { return as_ArrayType() != NULL; }
|
|
118 bool is_instance() { return as_InstanceType() != NULL; }
|
|
119 bool is_class() { return as_ClassType() != NULL; }
|
|
120 bool is_address() { return as_AddressType() != NULL; }
|
|
121 bool is_illegal() { return tag() == illegalTag; }
|
|
122
|
|
123 bool is_int_kind() const { return tag() == intTag || tag() == longTag; }
|
|
124 bool is_float_kind() const { return tag() == floatTag || tag() == doubleTag; }
|
|
125 bool is_object_kind() const { return tag() == objectTag; }
|
|
126
|
|
127 bool is_single_word() const { return _size == 1; }
|
|
128 bool is_double_word() const { return _size == 2; }
|
|
129
|
|
130 // casting
|
|
131 virtual VoidType* as_VoidType() { return NULL; }
|
|
132 virtual IntType* as_IntType() { return NULL; }
|
|
133 virtual LongType* as_LongType() { return NULL; }
|
|
134 virtual FloatType* as_FloatType() { return NULL; }
|
|
135 virtual DoubleType* as_DoubleType() { return NULL; }
|
|
136 virtual ObjectType* as_ObjectType() { return NULL; }
|
|
137 virtual ArrayType* as_ArrayType() { return NULL; }
|
|
138 virtual InstanceType* as_InstanceType() { return NULL; }
|
|
139 virtual ClassType* as_ClassType() { return NULL; }
|
|
140 virtual AddressType* as_AddressType() { return NULL; }
|
|
141 virtual IllegalType* as_IllegalType() { return NULL; }
|
|
142
|
|
143 virtual IntConstant* as_IntConstant() { return NULL; }
|
|
144 virtual LongConstant* as_LongConstant() { return NULL; }
|
|
145 virtual FloatConstant* as_FloatConstant() { return NULL; }
|
|
146 virtual DoubleConstant* as_DoubleConstant() { return NULL; }
|
|
147 virtual ObjectConstant* as_ObjectConstant() { return NULL; }
|
|
148 virtual InstanceConstant* as_InstanceConstant(){ return NULL; }
|
|
149 virtual ClassConstant* as_ClassConstant() { return NULL; }
|
|
150 virtual ArrayConstant* as_ArrayConstant() { return NULL; }
|
|
151 virtual AddressConstant* as_AddressConstant() { return NULL; }
|
|
152
|
|
153 // type operations
|
|
154 ValueType* meet(ValueType* y) const;
|
|
155 ValueType* join(ValueType* y) const;
|
|
156
|
|
157 // debugging
|
|
158 void print(outputStream* s = tty) { s->print(name()); }
|
|
159 };
|
|
160
|
|
161
|
|
162 class VoidType: public ValueType {
|
|
163 public:
|
|
164 VoidType(): ValueType(voidTag, 0) {}
|
|
165 virtual ValueType* base() const { return voidType; }
|
|
166 virtual const char tchar() const { return 'v'; }
|
|
167 virtual const char* name() const { return "void"; }
|
|
168 virtual VoidType* as_VoidType() { return this; }
|
|
169 };
|
|
170
|
|
171
|
|
172 class IntType: public ValueType {
|
|
173 public:
|
|
174 IntType(): ValueType(intTag, 1) {}
|
|
175 virtual ValueType* base() const { return intType; }
|
|
176 virtual const char tchar() const { return 'i'; }
|
|
177 virtual const char* name() const { return "int"; }
|
|
178 virtual IntType* as_IntType() { return this; }
|
|
179 };
|
|
180
|
|
181
|
|
182 class IntConstant: public IntType {
|
|
183 private:
|
|
184 jint _value;
|
|
185
|
|
186 public:
|
|
187 IntConstant(jint value) { _value = value; }
|
|
188
|
|
189 jint value() const { return _value; }
|
|
190
|
|
191 virtual bool is_constant() const { return true; }
|
|
192 virtual IntConstant* as_IntConstant() { return this; }
|
|
193 };
|
|
194
|
|
195
|
|
196 class IntInterval: public IntType {
|
|
197 private:
|
|
198 jint _beg;
|
|
199 jint _end;
|
|
200
|
|
201 public:
|
|
202 IntInterval(jint beg, jint end) {
|
|
203 assert(beg <= end, "illegal interval");
|
|
204 _beg = beg;
|
|
205 _end = end;
|
|
206 }
|
|
207
|
|
208 jint beg() const { return _beg; }
|
|
209 jint end() const { return _end; }
|
|
210
|
|
211 virtual bool is_interval() const { return true; }
|
|
212 };
|
|
213
|
|
214
|
|
215 class LongType: public ValueType {
|
|
216 public:
|
|
217 LongType(): ValueType(longTag, 2) {}
|
|
218 virtual ValueType* base() const { return longType; }
|
|
219 virtual const char tchar() const { return 'l'; }
|
|
220 virtual const char* name() const { return "long"; }
|
|
221 virtual LongType* as_LongType() { return this; }
|
|
222 };
|
|
223
|
|
224
|
|
225 class LongConstant: public LongType {
|
|
226 private:
|
|
227 jlong _value;
|
|
228
|
|
229 public:
|
|
230 LongConstant(jlong value) { _value = value; }
|
|
231
|
|
232 jlong value() const { return _value; }
|
|
233
|
|
234 virtual bool is_constant() const { return true; }
|
|
235 virtual LongConstant* as_LongConstant() { return this; }
|
|
236 };
|
|
237
|
|
238
|
|
239 class FloatType: public ValueType {
|
|
240 public:
|
|
241 FloatType(): ValueType(floatTag, 1) {}
|
|
242 virtual ValueType* base() const { return floatType; }
|
|
243 virtual const char tchar() const { return 'f'; }
|
|
244 virtual const char* name() const { return "float"; }
|
|
245 virtual FloatType* as_FloatType() { return this; }
|
|
246 };
|
|
247
|
|
248
|
|
249 class FloatConstant: public FloatType {
|
|
250 private:
|
|
251 jfloat _value;
|
|
252
|
|
253 public:
|
|
254 FloatConstant(jfloat value) { _value = value; }
|
|
255
|
|
256 jfloat value() const { return _value; }
|
|
257
|
|
258 virtual bool is_constant() const { return true; }
|
|
259 virtual FloatConstant* as_FloatConstant() { return this; }
|
|
260 };
|
|
261
|
|
262
|
|
263 class DoubleType: public ValueType {
|
|
264 public:
|
|
265 DoubleType(): ValueType(doubleTag, 2) {}
|
|
266 virtual ValueType* base() const { return doubleType; }
|
|
267 virtual const char tchar() const { return 'd'; }
|
|
268 virtual const char* name() const { return "double"; }
|
|
269 virtual DoubleType* as_DoubleType() { return this; }
|
|
270 };
|
|
271
|
|
272
|
|
273 class DoubleConstant: public DoubleType {
|
|
274 private:
|
|
275 jdouble _value;
|
|
276
|
|
277 public:
|
|
278 DoubleConstant(jdouble value) { _value = value; }
|
|
279
|
|
280 jdouble value() const { return _value; }
|
|
281
|
|
282 virtual bool is_constant() const { return true; }
|
|
283 virtual DoubleConstant* as_DoubleConstant() { return this; }
|
|
284 };
|
|
285
|
|
286
|
|
287 class ObjectType: public ValueType {
|
|
288 public:
|
|
289 ObjectType(): ValueType(objectTag, 1) {}
|
|
290 virtual ValueType* base() const { return objectType; }
|
|
291 virtual const char tchar() const { return 'a'; }
|
|
292 virtual const char* name() const { return "object"; }
|
|
293 virtual ObjectType* as_ObjectType() { return this; }
|
|
294 virtual ciObject* constant_value() const { ShouldNotReachHere(); return NULL; }
|
|
295 bool is_loaded() const;
|
|
296 jobject encoding() const;
|
|
297 };
|
|
298
|
|
299
|
|
300 class ObjectConstant: public ObjectType {
|
|
301 private:
|
|
302 ciObject* _value;
|
|
303
|
|
304 public:
|
|
305 ObjectConstant(ciObject* value) { _value = value; }
|
|
306
|
|
307 ciObject* value() const { return _value; }
|
|
308
|
|
309 virtual bool is_constant() const { return true; }
|
|
310 virtual ObjectConstant* as_ObjectConstant() { return this; }
|
|
311 virtual ciObject* constant_value() const;
|
|
312 };
|
|
313
|
|
314
|
|
315 class ArrayType: public ObjectType {
|
|
316 public:
|
|
317 virtual ArrayType* as_ArrayType() { return this; }
|
|
318 };
|
|
319
|
|
320
|
|
321 class ArrayConstant: public ArrayType {
|
|
322 private:
|
|
323 ciArray* _value;
|
|
324
|
|
325 public:
|
|
326 ArrayConstant(ciArray* value) { _value = value; }
|
|
327
|
|
328 ciArray* value() const { return _value; }
|
|
329
|
|
330 virtual bool is_constant() const { return true; }
|
|
331
|
|
332 virtual ArrayConstant* as_ArrayConstant() { return this; }
|
|
333 virtual ciObject* constant_value() const;
|
|
334 };
|
|
335
|
|
336
|
|
337 class InstanceType: public ObjectType {
|
|
338 public:
|
|
339 virtual InstanceType* as_InstanceType() { return this; }
|
|
340 };
|
|
341
|
|
342
|
|
343 class InstanceConstant: public InstanceType {
|
|
344 private:
|
|
345 ciInstance* _value;
|
|
346
|
|
347 public:
|
|
348 InstanceConstant(ciInstance* value) { _value = value; }
|
|
349
|
|
350 ciInstance* value() const { return _value; }
|
|
351
|
|
352 virtual bool is_constant() const { return true; }
|
|
353
|
|
354 virtual InstanceConstant* as_InstanceConstant(){ return this; }
|
|
355 virtual ciObject* constant_value() const;
|
|
356 };
|
|
357
|
|
358
|
|
359 class ClassType: public ObjectType {
|
|
360 public:
|
|
361 virtual ClassType* as_ClassType() { return this; }
|
|
362 };
|
|
363
|
|
364
|
|
365 class ClassConstant: public ClassType {
|
|
366 private:
|
|
367 ciInstanceKlass* _value;
|
|
368
|
|
369 public:
|
|
370 ClassConstant(ciInstanceKlass* value) { _value = value; }
|
|
371
|
|
372 ciInstanceKlass* value() const { return _value; }
|
|
373
|
|
374 virtual bool is_constant() const { return true; }
|
|
375
|
|
376 virtual ClassConstant* as_ClassConstant() { return this; }
|
|
377 virtual ciObject* constant_value() const;
|
|
378 };
|
|
379
|
|
380
|
|
381 class AddressType: public ValueType {
|
|
382 public:
|
|
383 AddressType(): ValueType(addressTag, 1) {}
|
|
384 virtual ValueType* base() const { return addressType; }
|
|
385 virtual const char tchar() const { return 'r'; }
|
|
386 virtual const char* name() const { return "address"; }
|
|
387 virtual AddressType* as_AddressType() { return this; }
|
|
388 };
|
|
389
|
|
390
|
|
391 class AddressConstant: public AddressType {
|
|
392 private:
|
|
393 jint _value;
|
|
394
|
|
395 public:
|
|
396 AddressConstant(jint value) { _value = value; }
|
|
397
|
|
398 jint value() const { return _value; }
|
|
399
|
|
400 virtual bool is_constant() const { return true; }
|
|
401
|
|
402 virtual AddressConstant* as_AddressConstant() { return this; }
|
|
403 };
|
|
404
|
|
405
|
|
406 class IllegalType: public ValueType {
|
|
407 public:
|
|
408 IllegalType(): ValueType(illegalTag, -1) {}
|
|
409 virtual ValueType* base() const { return illegalType; }
|
|
410 virtual const char tchar() const { return ' '; }
|
|
411 virtual const char* name() const { return "illegal"; }
|
|
412 virtual IllegalType* as_IllegalType() { return this; }
|
|
413 };
|
|
414
|
|
415
|
|
416 // conversion between ValueTypes, BasicTypes, and ciConstants
|
|
417 ValueType* as_ValueType(BasicType type);
|
|
418 ValueType* as_ValueType(ciConstant value);
|
|
419 BasicType as_BasicType(ValueType* type);
|
|
420
|
|
421 inline ValueType* as_ValueType(ciType* type) { return as_ValueType(type->basic_type()); }
|