1 /*
2  * Copyright (c) 1999, 2019, 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_C1_C1_VALUETYPE_HPP
26 #define SHARE_C1_C1_VALUETYPE_HPP
27 
28 #include "c1/c1_Compilation.hpp"
29 #include "ci/ciConstant.hpp"
30 #include "ci/ciMethodData.hpp"
31 
32 // type hierarchy
33 class ValueType;
34 class   VoidType;
35 class   IntType;
36 class     IntConstant;
37 class     IntInterval;
38 class   LongType;
39 class     LongConstant;
40 class   FloatType;
41 class     FloatConstant;
42 class   DoubleType;
43 class     DoubleConstant;
44 class   ObjectType;
45 class     ObjectConstant;
46 class     ArrayType;
47 class       ArrayConstant;
48 class         StableArrayConstant;
49 class     InstanceType;
50 class       InstanceConstant;
51 class   MetadataType;
52 class     ClassType;
53 class       ClassConstant;
54 class     MethodType;
55 class       MethodConstant;
56 class     MethodDataType;
57 class       MethodDataConstant;
58 class   AddressType;
59 class     AddressConstant;
60 class   IllegalType;
61 
62 
63 // predefined types
64 extern VoidType*       voidType;
65 extern IntType*        intType;
66 extern LongType*       longType;
67 extern FloatType*      floatType;
68 extern DoubleType*     doubleType;
69 extern ObjectType*     objectType;
70 extern ArrayType*      arrayType;
71 extern InstanceType*   instanceType;
72 extern ClassType*      classType;
73 extern AddressType*    addressType;
74 extern IllegalType*    illegalType;
75 
76 
77 // predefined constants
78 extern IntConstant*    intZero;
79 extern IntConstant*    intOne;
80 extern ObjectConstant* objectNull;
81 
82 
83 // tags
84 enum ValueTag {
85   // all legal tags must come first
86   intTag,
87   longTag,
88   floatTag,
89   doubleTag,
90   objectTag,
91   addressTag,
92   metaDataTag,
93   number_of_legal_tags,
94   // all other tags must follow afterwards
95   voidTag = number_of_legal_tags,
96   illegalTag,
97   number_of_tags
98 };
99 
100 
101 class ValueType: public CompilationResourceObj {
102  private:
103   const int _size;
104   const ValueTag _tag;
105   ValueType();
106  protected:
ValueType(ValueTag tag,int size)107   ValueType(ValueTag tag, int size): _size(size), _tag(tag) {}
108 
109  public:
110   // initialization
111   static void initialize(Arena* arena);
112 
113   // accessors
114   virtual ValueType* base() const                = 0; // the 'canonical' type (e.g., intType for an IntConstant)
tag() const115   ValueTag tag() const { return _tag; }          // the 'canonical' tag  (useful for type matching)
size() const116   int size() const {                             // the size of an object of the type in words
117     assert(_size > -1, "shouldn't be asking for size");
118     return _size;
119   }
120   virtual const char tchar() const               = 0; // the type 'character' for printing
121   virtual const char* name() const               = 0; // the type name for printing
is_constant() const122   virtual bool is_constant() const               { return false; }
123 
124   // testers
is_void()125   bool is_void()                                 { return tag() == voidTag;   }
is_int()126   bool is_int()                                  { return tag() == intTag;    }
is_long()127   bool is_long()                                 { return tag() == longTag;   }
is_float()128   bool is_float()                                { return tag() == floatTag;  }
is_double()129   bool is_double()                               { return tag() == doubleTag; }
is_object()130   bool is_object()                               { return as_ObjectType()   != NULL; }
is_array()131   bool is_array()                                { return as_ArrayType()    != NULL; }
is_instance()132   bool is_instance()                             { return as_InstanceType() != NULL; }
is_class()133   bool is_class()                                { return as_ClassType()    != NULL; }
is_method()134   bool is_method()                               { return as_MethodType()   != NULL; }
is_method_data()135   bool is_method_data()                          { return as_MethodDataType() != NULL; }
is_address()136   bool is_address()                              { return as_AddressType()  != NULL; }
is_illegal()137   bool is_illegal()                              { return tag() == illegalTag; }
138 
is_int_kind() const139   bool is_int_kind() const                       { return tag() == intTag || tag() == longTag; }
is_float_kind() const140   bool is_float_kind() const                     { return tag() == floatTag || tag() == doubleTag; }
is_object_kind() const141   bool is_object_kind() const                    { return tag() == objectTag; }
142 
is_single_word() const143   bool is_single_word() const                    { return _size == 1; }
is_double_word() const144   bool is_double_word() const                    { return _size == 2; }
145 
146   // casting
as_VoidType()147   virtual VoidType*         as_VoidType()        { return NULL; }
as_IntType()148   virtual IntType*          as_IntType()         { return NULL; }
as_LongType()149   virtual LongType*         as_LongType()        { return NULL; }
as_FloatType()150   virtual FloatType*        as_FloatType()       { return NULL; }
as_DoubleType()151   virtual DoubleType*       as_DoubleType()      { return NULL; }
as_ObjectType()152   virtual ObjectType*       as_ObjectType()      { return NULL; }
as_ArrayType()153   virtual ArrayType*        as_ArrayType()       { return NULL; }
as_InstanceType()154   virtual InstanceType*     as_InstanceType()    { return NULL; }
as_ClassType()155   virtual ClassType*        as_ClassType()       { return NULL; }
as_MetadataType()156   virtual MetadataType*     as_MetadataType()    { return NULL; }
as_MethodType()157   virtual MethodType*       as_MethodType()      { return NULL; }
as_MethodDataType()158   virtual MethodDataType*   as_MethodDataType()  { return NULL; }
as_AddressType()159   virtual AddressType*      as_AddressType()     { return NULL; }
as_IllegalType()160   virtual IllegalType*      as_IllegalType()     { return NULL; }
161 
as_IntConstant()162   virtual IntConstant*      as_IntConstant()     { return NULL; }
as_LongConstant()163   virtual LongConstant*     as_LongConstant()    { return NULL; }
as_FloatConstant()164   virtual FloatConstant*    as_FloatConstant()   { return NULL; }
as_DoubleConstant()165   virtual DoubleConstant*   as_DoubleConstant()  { return NULL; }
as_ObjectConstant()166   virtual ObjectConstant*   as_ObjectConstant()  { return NULL; }
as_InstanceConstant()167   virtual InstanceConstant* as_InstanceConstant(){ return NULL; }
as_ClassConstant()168   virtual ClassConstant*    as_ClassConstant()   { return NULL; }
as_MethodConstant()169   virtual MethodConstant*   as_MethodConstant()  { return NULL; }
as_MethodDataConstant()170   virtual MethodDataConstant* as_MethodDataConstant() { return NULL; }
as_ArrayConstant()171   virtual ArrayConstant*    as_ArrayConstant()   { return NULL; }
as_StableArrayConstant()172   virtual StableArrayConstant* as_StableArrayConstant()   { return NULL; }
as_AddressConstant()173   virtual AddressConstant*  as_AddressConstant() { return NULL; }
174 
175   // type operations
176   ValueType* meet(ValueType* y) const;
177   ValueType* join(ValueType* y) const;
178 
179   // debugging
print(outputStream * s=tty)180   void print(outputStream* s = tty)              { s->print("%s", name()); }
181 };
182 
183 
184 class VoidType: public ValueType {
185  public:
VoidType()186   VoidType(): ValueType(voidTag, 0) {}
base() const187   virtual ValueType* base() const                { return voidType; }
tchar() const188   virtual const char tchar() const               { return 'v'; }
name() const189   virtual const char* name() const               { return "void"; }
as_VoidType()190   virtual VoidType* as_VoidType()                { return this; }
191 };
192 
193 
194 class IntType: public ValueType {
195  public:
IntType()196   IntType(): ValueType(intTag, 1) {}
base() const197   virtual ValueType* base() const                { return intType; }
tchar() const198   virtual const char tchar() const               { return 'i'; }
name() const199   virtual const char* name() const               { return "int"; }
as_IntType()200   virtual IntType* as_IntType()                  { return this; }
201 };
202 
203 
204 class IntConstant: public IntType {
205  private:
206   jint _value;
207 
208  public:
IntConstant(jint value)209   IntConstant(jint value)                        { _value = value; }
210 
value() const211   jint value() const                             { return _value; }
212 
is_constant() const213   virtual bool is_constant() const               { return true; }
as_IntConstant()214   virtual IntConstant* as_IntConstant()          { return this; }
215 };
216 
217 
218 class IntInterval: public IntType {
219  private:
220   jint _beg;
221   jint _end;
222 
223  public:
IntInterval(jint beg,jint end)224   IntInterval(jint beg, jint end) {
225     assert(beg <= end, "illegal interval");
226     _beg = beg;
227     _end = end;
228   }
229 
beg() const230   jint beg() const                               { return _beg; }
end() const231   jint end() const                               { return _end; }
232 
is_interval() const233   virtual bool is_interval() const               { return true; }
234 };
235 
236 
237 class LongType: public ValueType {
238  public:
LongType()239   LongType(): ValueType(longTag, 2) {}
base() const240   virtual ValueType* base() const                { return longType; }
tchar() const241   virtual const char tchar() const               { return 'l'; }
name() const242   virtual const char* name() const               { return "long"; }
as_LongType()243   virtual LongType* as_LongType()                { return this; }
244 };
245 
246 
247 class LongConstant: public LongType {
248  private:
249   jlong _value;
250 
251  public:
LongConstant(jlong value)252   LongConstant(jlong value)                      { _value = value; }
253 
value() const254   jlong value() const                            { return _value; }
255 
is_constant() const256   virtual bool is_constant() const               { return true; }
as_LongConstant()257   virtual LongConstant* as_LongConstant()        { return this; }
258 };
259 
260 
261 class FloatType: public ValueType {
262  public:
FloatType()263   FloatType(): ValueType(floatTag, 1) {}
base() const264   virtual ValueType* base() const                { return floatType; }
tchar() const265   virtual const char tchar() const               { return 'f'; }
name() const266   virtual const char* name() const               { return "float"; }
as_FloatType()267   virtual FloatType* as_FloatType()              { return this; }
268 };
269 
270 
271 class FloatConstant: public FloatType {
272  private:
273   jfloat _value;
274 
275  public:
FloatConstant(jfloat value)276   FloatConstant(jfloat value)                    { _value = value; }
277 
value() const278   jfloat value() const                           { return _value; }
279 
is_constant() const280   virtual bool is_constant() const               { return true; }
as_FloatConstant()281   virtual FloatConstant* as_FloatConstant()      { return this; }
282 };
283 
284 
285 class DoubleType: public ValueType {
286  public:
DoubleType()287   DoubleType(): ValueType(doubleTag, 2) {}
base() const288   virtual ValueType* base() const                { return doubleType; }
tchar() const289   virtual const char tchar() const               { return 'd'; }
name() const290   virtual const char* name() const               { return "double"; }
as_DoubleType()291   virtual DoubleType* as_DoubleType()            { return this; }
292 };
293 
294 
295 class DoubleConstant: public DoubleType {
296  private:
297   jdouble _value;
298 
299  public:
DoubleConstant(jdouble value)300   DoubleConstant(jdouble value)                  { _value = value; }
301 
value() const302   jdouble value() const                          { return _value; }
303 
is_constant() const304   virtual bool is_constant() const               { return true; }
as_DoubleConstant()305   virtual DoubleConstant* as_DoubleConstant()    { return this; }
306 };
307 
308 
309 class ObjectType: public ValueType {
310  public:
ObjectType()311   ObjectType(): ValueType(objectTag, 1) {}
base() const312   virtual ValueType* base() const                { return objectType; }
tchar() const313   virtual const char tchar() const               { return 'a'; }
name() const314   virtual const char* name() const               { return "object"; }
as_ObjectType()315   virtual ObjectType* as_ObjectType()            { return this; }
constant_value() const316   virtual ciObject* constant_value() const       { ShouldNotReachHere(); return NULL; }
exact_type() const317   virtual ciType* exact_type() const             { return NULL; }
318   bool is_loaded() const;
319   jobject encoding() const;
320 };
321 
322 
323 class ObjectConstant: public ObjectType {
324  private:
325   ciObject* _value;
326 
327  public:
ObjectConstant(ciObject * value)328   ObjectConstant(ciObject* value)                { _value = value; }
329 
value() const330   ciObject* value() const                        { return _value; }
331 
is_constant() const332   virtual bool is_constant() const               { return true; }
as_ObjectConstant()333   virtual ObjectConstant* as_ObjectConstant()    { return this; }
334   virtual ciObject* constant_value() const;
335   virtual ciType* exact_type() const;
336 };
337 
338 
339 class ArrayType: public ObjectType {
340  public:
as_ArrayType()341   virtual ArrayType* as_ArrayType()              { return this; }
342 };
343 
344 
345 class ArrayConstant: public ArrayType {
346  private:
347   ciArray* _value;
348 
349  public:
ArrayConstant(ciArray * value)350   ArrayConstant(ciArray* value)                  { _value = value; }
351 
value() const352   ciArray* value() const                         { return _value; }
353 
is_constant() const354   virtual bool is_constant() const               { return true; }
as_ArrayConstant()355   virtual ArrayConstant* as_ArrayConstant()      { return this; }
356   virtual ciObject* constant_value() const;
357   virtual ciType* exact_type() const;
358 };
359 
360 class StableArrayConstant: public ArrayConstant {
361  private:
362   jint _dimension;
363 
364  public:
StableArrayConstant(ciArray * value,jint dimension)365   StableArrayConstant(ciArray* value, jint dimension) : ArrayConstant(value) {
366     assert(dimension > 0, "not a stable array");
367     _dimension = dimension;
368   }
369 
dimension() const370   jint dimension() const                              { return _dimension; }
371 
as_StableArrayConstant()372   virtual StableArrayConstant* as_StableArrayConstant() { return this; }
373 };
374 
375 class InstanceType: public ObjectType {
376  public:
as_InstanceType()377   virtual InstanceType* as_InstanceType()        { return this; }
378 };
379 
380 
381 class InstanceConstant: public InstanceType {
382  private:
383   ciInstance* _value;
384 
385  public:
InstanceConstant(ciInstance * value)386   InstanceConstant(ciInstance* value)            { _value = value; }
387 
value() const388   ciInstance* value() const                      { return _value; }
389 
is_constant() const390   virtual bool is_constant() const               { return true; }
as_InstanceConstant()391   virtual InstanceConstant* as_InstanceConstant(){ return this; }
392   virtual ciObject* constant_value() const;
393   virtual ciType* exact_type() const;
394 };
395 
396 
397 class MetadataType: public ValueType {
398  public:
MetadataType()399   MetadataType(): ValueType(metaDataTag, 1) {}
base() const400   virtual ValueType* base() const                       { return objectType; }
tchar() const401   virtual const char tchar() const                      { return 'a'; }
name() const402   virtual const char* name() const                      { return "object"; }
as_MetadataType()403   virtual MetadataType* as_MetadataType()               { return this; }
404   bool is_loaded() const;
405   jobject encoding() const;
constant_value() const406   virtual ciMetadata* constant_value() const            { ShouldNotReachHere(); return NULL;  }
407 };
408 
409 
410 class ClassType: public MetadataType {
411  public:
as_ClassType()412   virtual ClassType* as_ClassType()              { return this; }
413 };
414 
415 
416 class ClassConstant: public ClassType {
417  private:
418   ciInstanceKlass* _value;
419 
420  public:
ClassConstant(ciInstanceKlass * value)421   ClassConstant(ciInstanceKlass* value)          { _value = value; }
422 
value() const423   ciInstanceKlass* value() const                 { return _value; }
424 
is_constant() const425   virtual bool is_constant() const               { return true; }
as_ClassConstant()426   virtual ClassConstant* as_ClassConstant()      { return this; }
constant_value() const427   virtual ciMetadata* constant_value() const            { return _value; }
428   virtual ciType* exact_type() const;
429 };
430 
431 
432 class MethodType: public MetadataType {
433  public:
as_MethodType()434   virtual MethodType* as_MethodType()                   { return this; }
435 };
436 
437 
438 class MethodConstant: public MethodType {
439  private:
440   ciMethod* _value;
441 
442  public:
MethodConstant(ciMethod * value)443   MethodConstant(ciMethod* value)                       { _value = value; }
444 
value() const445   ciMethod* value() const                               { return _value; }
446 
is_constant() const447   virtual bool is_constant() const                      { return true; }
448 
as_MethodConstant()449   virtual MethodConstant* as_MethodConstant()           { return this; }
constant_value() const450   virtual ciMetadata* constant_value() const            { return _value; }
451 };
452 
453 
454 class MethodDataType: public MetadataType {
455  public:
as_MethodDataType()456   virtual MethodDataType* as_MethodDataType()           { return this; }
457 };
458 
459 
460 class MethodDataConstant: public MethodDataType {
461  private:
462   ciMethodData* _value;
463 
464  public:
MethodDataConstant(ciMethodData * value)465   MethodDataConstant(ciMethodData* value)               { _value = value; }
466 
value() const467   ciMethodData* value() const                           { return _value; }
468 
is_constant() const469   virtual bool is_constant() const                      { return true; }
470 
as_MethodDataConstant()471   virtual MethodDataConstant* as_MethodDataConstant()   { return this; }
constant_value() const472   virtual ciMetadata* constant_value() const            { return _value; }
473 };
474 
475 
476 class AddressType: public ValueType {
477  public:
AddressType()478   AddressType(): ValueType(addressTag, 1) {}
base() const479   virtual ValueType* base() const                { return addressType; }
tchar() const480   virtual const char tchar() const               { return 'r'; }
name() const481   virtual const char* name() const               { return "address"; }
as_AddressType()482   virtual AddressType* as_AddressType()          { return this; }
483 };
484 
485 
486 class AddressConstant: public AddressType {
487  private:
488   jint _value;
489 
490  public:
AddressConstant(jint value)491   AddressConstant(jint value)                    { _value = value; }
492 
value() const493   jint value() const                             { return _value; }
494 
is_constant() const495   virtual bool is_constant() const               { return true; }
496 
as_AddressConstant()497   virtual AddressConstant* as_AddressConstant()  { return this; }
498 };
499 
500 
501 class IllegalType: public ValueType {
502  public:
IllegalType()503   IllegalType(): ValueType(illegalTag, -1) {}
base() const504   virtual ValueType* base() const                { return illegalType; }
tchar() const505   virtual const char tchar() const               { return ' '; }
name() const506   virtual const char* name() const               { return "illegal"; }
as_IllegalType()507   virtual IllegalType* as_IllegalType()          { return this; }
508 };
509 
510 
511 // conversion between ValueTypes, BasicTypes, and ciConstants
512 ValueType* as_ValueType(BasicType type);
513 ValueType* as_ValueType(ciConstant value);
514 BasicType  as_BasicType(ValueType* type);
515 
as_ValueType(ciType * type)516 inline ValueType* as_ValueType(ciType* type) { return as_ValueType(type->basic_type()); }
517 
518 #endif // SHARE_C1_C1_VALUETYPE_HPP
519