aoqi@0: /* aoqi@0: * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: #ifndef SHARE_VM_C1_C1_VALUETYPE_HPP aoqi@0: #define SHARE_VM_C1_C1_VALUETYPE_HPP aoqi@0: aoqi@0: #include "c1/c1_Compilation.hpp" aoqi@0: #include "ci/ciConstant.hpp" aoqi@0: #include "ci/ciMethodData.hpp" aoqi@0: aoqi@0: // type hierarchy aoqi@0: class ValueType; aoqi@0: class VoidType; aoqi@0: class IntType; aoqi@0: class IntConstant; aoqi@0: class IntInterval; aoqi@0: class LongType; aoqi@0: class LongConstant; aoqi@0: class FloatType; aoqi@0: class FloatConstant; aoqi@0: class DoubleType; aoqi@0: class DoubleConstant; aoqi@0: class ObjectType; aoqi@0: class ObjectConstant; aoqi@0: class ArrayType; aoqi@0: class ArrayConstant; aoqi@0: class InstanceType; aoqi@0: class InstanceConstant; aoqi@0: class MetadataType; aoqi@0: class ClassType; aoqi@0: class ClassConstant; aoqi@0: class MethodType; aoqi@0: class MethodConstant; aoqi@0: class MethodDataType; aoqi@0: class MethodDataConstant; aoqi@0: class AddressType; aoqi@0: class AddressConstant; aoqi@0: class IllegalType; aoqi@0: aoqi@0: aoqi@0: // predefined types aoqi@0: extern VoidType* voidType; aoqi@0: extern IntType* intType; aoqi@0: extern LongType* longType; aoqi@0: extern FloatType* floatType; aoqi@0: extern DoubleType* doubleType; aoqi@0: extern ObjectType* objectType; aoqi@0: extern ArrayType* arrayType; aoqi@0: extern InstanceType* instanceType; aoqi@0: extern ClassType* classType; aoqi@0: extern AddressType* addressType; aoqi@0: extern IllegalType* illegalType; aoqi@0: aoqi@0: aoqi@0: // predefined constants aoqi@0: extern IntConstant* intZero; aoqi@0: extern IntConstant* intOne; aoqi@0: extern ObjectConstant* objectNull; aoqi@0: aoqi@0: aoqi@0: // tags aoqi@0: enum ValueTag { aoqi@0: // all legal tags must come first aoqi@0: intTag, aoqi@0: longTag, aoqi@0: floatTag, aoqi@0: doubleTag, aoqi@0: objectTag, aoqi@0: addressTag, aoqi@0: metaDataTag, aoqi@0: number_of_legal_tags, aoqi@0: // all other tags must follow afterwards aoqi@0: voidTag = number_of_legal_tags, aoqi@0: illegalTag, aoqi@0: number_of_tags aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class ValueType: public CompilationResourceObj { aoqi@0: private: aoqi@0: const int _size; aoqi@0: const ValueTag _tag; aoqi@0: ValueType(); aoqi@0: protected: aoqi@0: ValueType(ValueTag tag, int size): _tag(tag), _size(size) {} aoqi@0: aoqi@0: public: aoqi@0: // initialization aoqi@0: static void initialize(Arena* arena); aoqi@0: aoqi@0: // accessors aoqi@0: virtual ValueType* base() const = 0; // the 'canonical' type (e.g., intType for an IntConstant) aoqi@0: ValueTag tag() const { return _tag; } // the 'canonical' tag (useful for type matching) aoqi@0: int size() const { // the size of an object of the type in words aoqi@0: assert(_size > -1, "shouldn't be asking for size"); aoqi@0: return _size; aoqi@0: } aoqi@0: virtual const char tchar() const = 0; // the type 'character' for printing aoqi@0: virtual const char* name() const = 0; // the type name for printing aoqi@0: virtual bool is_constant() const { return false; } aoqi@0: aoqi@0: // testers aoqi@0: bool is_void() { return tag() == voidTag; } aoqi@0: bool is_int() { return tag() == intTag; } aoqi@0: bool is_long() { return tag() == longTag; } aoqi@0: bool is_float() { return tag() == floatTag; } aoqi@0: bool is_double() { return tag() == doubleTag; } aoqi@0: bool is_object() { return as_ObjectType() != NULL; } aoqi@0: bool is_array() { return as_ArrayType() != NULL; } aoqi@0: bool is_instance() { return as_InstanceType() != NULL; } aoqi@0: bool is_class() { return as_ClassType() != NULL; } aoqi@0: bool is_method() { return as_MethodType() != NULL; } aoqi@0: bool is_method_data() { return as_MethodDataType() != NULL; } aoqi@0: bool is_address() { return as_AddressType() != NULL; } aoqi@0: bool is_illegal() { return tag() == illegalTag; } aoqi@0: aoqi@0: bool is_int_kind() const { return tag() == intTag || tag() == longTag; } aoqi@0: bool is_float_kind() const { return tag() == floatTag || tag() == doubleTag; } aoqi@0: bool is_object_kind() const { return tag() == objectTag; } aoqi@0: aoqi@0: bool is_single_word() const { return _size == 1; } aoqi@0: bool is_double_word() const { return _size == 2; } aoqi@0: aoqi@0: // casting aoqi@0: virtual VoidType* as_VoidType() { return NULL; } aoqi@0: virtual IntType* as_IntType() { return NULL; } aoqi@0: virtual LongType* as_LongType() { return NULL; } aoqi@0: virtual FloatType* as_FloatType() { return NULL; } aoqi@0: virtual DoubleType* as_DoubleType() { return NULL; } aoqi@0: virtual ObjectType* as_ObjectType() { return NULL; } aoqi@0: virtual ArrayType* as_ArrayType() { return NULL; } aoqi@0: virtual InstanceType* as_InstanceType() { return NULL; } aoqi@0: virtual ClassType* as_ClassType() { return NULL; } aoqi@0: virtual MetadataType* as_MetadataType() { return NULL; } aoqi@0: virtual MethodType* as_MethodType() { return NULL; } aoqi@0: virtual MethodDataType* as_MethodDataType() { return NULL; } aoqi@0: virtual AddressType* as_AddressType() { return NULL; } aoqi@0: virtual IllegalType* as_IllegalType() { return NULL; } aoqi@0: aoqi@0: virtual IntConstant* as_IntConstant() { return NULL; } aoqi@0: virtual LongConstant* as_LongConstant() { return NULL; } aoqi@0: virtual FloatConstant* as_FloatConstant() { return NULL; } aoqi@0: virtual DoubleConstant* as_DoubleConstant() { return NULL; } aoqi@0: virtual ObjectConstant* as_ObjectConstant() { return NULL; } aoqi@0: virtual InstanceConstant* as_InstanceConstant(){ return NULL; } aoqi@0: virtual ClassConstant* as_ClassConstant() { return NULL; } aoqi@0: virtual MethodConstant* as_MethodConstant() { return NULL; } aoqi@0: virtual MethodDataConstant* as_MethodDataConstant() { return NULL; } aoqi@0: virtual ArrayConstant* as_ArrayConstant() { return NULL; } aoqi@0: virtual AddressConstant* as_AddressConstant() { return NULL; } aoqi@0: aoqi@0: // type operations aoqi@0: ValueType* meet(ValueType* y) const; aoqi@0: ValueType* join(ValueType* y) const; aoqi@0: aoqi@0: // debugging aoqi@0: void print(outputStream* s = tty) { s->print("%s", name()); } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class VoidType: public ValueType { aoqi@0: public: aoqi@0: VoidType(): ValueType(voidTag, 0) {} aoqi@0: virtual ValueType* base() const { return voidType; } aoqi@0: virtual const char tchar() const { return 'v'; } aoqi@0: virtual const char* name() const { return "void"; } aoqi@0: virtual VoidType* as_VoidType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class IntType: public ValueType { aoqi@0: public: aoqi@0: IntType(): ValueType(intTag, 1) {} aoqi@0: virtual ValueType* base() const { return intType; } aoqi@0: virtual const char tchar() const { return 'i'; } aoqi@0: virtual const char* name() const { return "int"; } aoqi@0: virtual IntType* as_IntType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class IntConstant: public IntType { aoqi@0: private: aoqi@0: jint _value; aoqi@0: aoqi@0: public: aoqi@0: IntConstant(jint value) { _value = value; } aoqi@0: aoqi@0: jint value() const { return _value; } aoqi@0: aoqi@0: virtual bool is_constant() const { return true; } aoqi@0: virtual IntConstant* as_IntConstant() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class IntInterval: public IntType { aoqi@0: private: aoqi@0: jint _beg; aoqi@0: jint _end; aoqi@0: aoqi@0: public: aoqi@0: IntInterval(jint beg, jint end) { aoqi@0: assert(beg <= end, "illegal interval"); aoqi@0: _beg = beg; aoqi@0: _end = end; aoqi@0: } aoqi@0: aoqi@0: jint beg() const { return _beg; } aoqi@0: jint end() const { return _end; } aoqi@0: aoqi@0: virtual bool is_interval() const { return true; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class LongType: public ValueType { aoqi@0: public: aoqi@0: LongType(): ValueType(longTag, 2) {} aoqi@0: virtual ValueType* base() const { return longType; } aoqi@0: virtual const char tchar() const { return 'l'; } aoqi@0: virtual const char* name() const { return "long"; } aoqi@0: virtual LongType* as_LongType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class LongConstant: public LongType { aoqi@0: private: aoqi@0: jlong _value; aoqi@0: aoqi@0: public: aoqi@0: LongConstant(jlong value) { _value = value; } aoqi@0: aoqi@0: jlong value() const { return _value; } aoqi@0: aoqi@0: virtual bool is_constant() const { return true; } aoqi@0: virtual LongConstant* as_LongConstant() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class FloatType: public ValueType { aoqi@0: public: aoqi@0: FloatType(): ValueType(floatTag, 1) {} aoqi@0: virtual ValueType* base() const { return floatType; } aoqi@0: virtual const char tchar() const { return 'f'; } aoqi@0: virtual const char* name() const { return "float"; } aoqi@0: virtual FloatType* as_FloatType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class FloatConstant: public FloatType { aoqi@0: private: aoqi@0: jfloat _value; aoqi@0: aoqi@0: public: aoqi@0: FloatConstant(jfloat value) { _value = value; } aoqi@0: aoqi@0: jfloat value() const { return _value; } aoqi@0: aoqi@0: virtual bool is_constant() const { return true; } aoqi@0: virtual FloatConstant* as_FloatConstant() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class DoubleType: public ValueType { aoqi@0: public: aoqi@0: DoubleType(): ValueType(doubleTag, 2) {} aoqi@0: virtual ValueType* base() const { return doubleType; } aoqi@0: virtual const char tchar() const { return 'd'; } aoqi@0: virtual const char* name() const { return "double"; } aoqi@0: virtual DoubleType* as_DoubleType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class DoubleConstant: public DoubleType { aoqi@0: private: aoqi@0: jdouble _value; aoqi@0: aoqi@0: public: aoqi@0: DoubleConstant(jdouble value) { _value = value; } aoqi@0: aoqi@0: jdouble value() const { return _value; } aoqi@0: aoqi@0: virtual bool is_constant() const { return true; } aoqi@0: virtual DoubleConstant* as_DoubleConstant() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class ObjectType: public ValueType { aoqi@0: public: aoqi@0: ObjectType(): ValueType(objectTag, 1) {} aoqi@0: virtual ValueType* base() const { return objectType; } aoqi@0: virtual const char tchar() const { return 'a'; } aoqi@0: virtual const char* name() const { return "object"; } aoqi@0: virtual ObjectType* as_ObjectType() { return this; } aoqi@0: virtual ciObject* constant_value() const { ShouldNotReachHere(); return NULL; } aoqi@0: virtual ciType* exact_type() const { return NULL; } aoqi@0: bool is_loaded() const; aoqi@0: jobject encoding() const; aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class ObjectConstant: public ObjectType { aoqi@0: private: aoqi@0: ciObject* _value; aoqi@0: aoqi@0: public: aoqi@0: ObjectConstant(ciObject* value) { _value = value; } aoqi@0: aoqi@0: ciObject* value() const { return _value; } aoqi@0: aoqi@0: virtual bool is_constant() const { return true; } aoqi@0: virtual ObjectConstant* as_ObjectConstant() { return this; } aoqi@0: virtual ciObject* constant_value() const; aoqi@0: virtual ciType* exact_type() const; aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class ArrayType: public ObjectType { aoqi@0: public: aoqi@0: virtual ArrayType* as_ArrayType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class ArrayConstant: public ArrayType { aoqi@0: private: aoqi@0: ciArray* _value; aoqi@0: aoqi@0: public: aoqi@0: ArrayConstant(ciArray* value) { _value = value; } aoqi@0: aoqi@0: ciArray* value() const { return _value; } aoqi@0: aoqi@0: virtual bool is_constant() const { return true; } aoqi@0: virtual ArrayConstant* as_ArrayConstant() { return this; } aoqi@0: virtual ciObject* constant_value() const; aoqi@0: virtual ciType* exact_type() const; aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class InstanceType: public ObjectType { aoqi@0: public: aoqi@0: virtual InstanceType* as_InstanceType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class InstanceConstant: public InstanceType { aoqi@0: private: aoqi@0: ciInstance* _value; aoqi@0: aoqi@0: public: aoqi@0: InstanceConstant(ciInstance* value) { _value = value; } aoqi@0: aoqi@0: ciInstance* value() const { return _value; } aoqi@0: aoqi@0: virtual bool is_constant() const { return true; } aoqi@0: virtual InstanceConstant* as_InstanceConstant(){ return this; } aoqi@0: virtual ciObject* constant_value() const; aoqi@0: virtual ciType* exact_type() const; aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class MetadataType: public ValueType { aoqi@0: public: aoqi@0: MetadataType(): ValueType(metaDataTag, 1) {} aoqi@0: virtual ValueType* base() const { return objectType; } aoqi@0: virtual const char tchar() const { return 'a'; } aoqi@0: virtual const char* name() const { return "object"; } aoqi@0: virtual MetadataType* as_MetadataType() { return this; } aoqi@0: bool is_loaded() const; aoqi@0: jobject encoding() const; aoqi@0: virtual ciMetadata* constant_value() const { ShouldNotReachHere(); return NULL; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class ClassType: public MetadataType { aoqi@0: public: aoqi@0: virtual ClassType* as_ClassType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class ClassConstant: public ClassType { aoqi@0: private: aoqi@0: ciInstanceKlass* _value; aoqi@0: aoqi@0: public: aoqi@0: ClassConstant(ciInstanceKlass* value) { _value = value; } aoqi@0: aoqi@0: ciInstanceKlass* value() const { return _value; } aoqi@0: aoqi@0: virtual bool is_constant() const { return true; } aoqi@0: virtual ClassConstant* as_ClassConstant() { return this; } aoqi@0: virtual ciMetadata* constant_value() const { return _value; } aoqi@0: virtual ciType* exact_type() const; aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class MethodType: public MetadataType { aoqi@0: public: aoqi@0: virtual MethodType* as_MethodType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class MethodConstant: public MethodType { aoqi@0: private: aoqi@0: ciMethod* _value; aoqi@0: aoqi@0: public: aoqi@0: MethodConstant(ciMethod* value) { _value = value; } aoqi@0: aoqi@0: ciMethod* value() const { return _value; } aoqi@0: aoqi@0: virtual bool is_constant() const { return true; } aoqi@0: aoqi@0: virtual MethodConstant* as_MethodConstant() { return this; } aoqi@0: virtual ciMetadata* constant_value() const { return _value; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class MethodDataType: public MetadataType { aoqi@0: public: aoqi@0: virtual MethodDataType* as_MethodDataType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class MethodDataConstant: public MethodDataType { aoqi@0: private: aoqi@0: ciMethodData* _value; aoqi@0: aoqi@0: public: aoqi@0: MethodDataConstant(ciMethodData* value) { _value = value; } aoqi@0: aoqi@0: ciMethodData* value() const { return _value; } aoqi@0: aoqi@0: virtual bool is_constant() const { return true; } aoqi@0: aoqi@0: virtual MethodDataConstant* as_MethodDataConstant() { return this; } aoqi@0: virtual ciMetadata* constant_value() const { return _value; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class AddressType: public ValueType { aoqi@0: public: aoqi@0: AddressType(): ValueType(addressTag, 1) {} aoqi@0: virtual ValueType* base() const { return addressType; } aoqi@0: virtual const char tchar() const { return 'r'; } aoqi@0: virtual const char* name() const { return "address"; } aoqi@0: virtual AddressType* as_AddressType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class AddressConstant: public AddressType { aoqi@0: private: aoqi@0: jint _value; aoqi@0: aoqi@0: public: aoqi@0: AddressConstant(jint value) { _value = value; } aoqi@0: aoqi@0: jint value() const { return _value; } aoqi@0: aoqi@0: virtual bool is_constant() const { return true; } aoqi@0: aoqi@0: virtual AddressConstant* as_AddressConstant() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: class IllegalType: public ValueType { aoqi@0: public: aoqi@0: IllegalType(): ValueType(illegalTag, -1) {} aoqi@0: virtual ValueType* base() const { return illegalType; } aoqi@0: virtual const char tchar() const { return ' '; } aoqi@0: virtual const char* name() const { return "illegal"; } aoqi@0: virtual IllegalType* as_IllegalType() { return this; } aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: // conversion between ValueTypes, BasicTypes, and ciConstants aoqi@0: ValueType* as_ValueType(BasicType type); aoqi@0: ValueType* as_ValueType(ciConstant value); aoqi@0: BasicType as_BasicType(ValueType* type); aoqi@0: aoqi@0: inline ValueType* as_ValueType(ciType* type) { return as_ValueType(type->basic_type()); } aoqi@0: aoqi@0: #endif // SHARE_VM_C1_C1_VALUETYPE_HPP