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