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