blob: 5f86a8b9309b51e6cab8dd20084c0c9517c4e6f2 [file] [log] [blame]
/*
* Copyright (c) 1999, 2012, 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.
*
*/
#include "precompiled.hpp"
#include "c1/c1_ValueType.hpp"
#include "ci/ciArray.hpp"
#include "ci/ciInstance.hpp"
#include "ci/ciNullObject.hpp"
// predefined types
VoidType* voidType = NULL;
IntType* intType = NULL;
LongType* longType = NULL;
FloatType* floatType = NULL;
DoubleType* doubleType = NULL;
ObjectType* objectType = NULL;
ArrayType* arrayType = NULL;
InstanceType* instanceType = NULL;
ClassType* classType = NULL;
AddressType* addressType = NULL;
IllegalType* illegalType = NULL;
// predefined constants
IntConstant* intZero = NULL;
IntConstant* intOne = NULL;
ObjectConstant* objectNull = NULL;
void ValueType::initialize(Arena* arena) {
// Note: Must initialize all types for each compilation
// as they are allocated within a ResourceMark!
// types
voidType = new (arena) VoidType();
intType = new (arena) IntType();
longType = new (arena) LongType();
floatType = new (arena) FloatType();
doubleType = new (arena) DoubleType();
objectType = new (arena) ObjectType();
arrayType = new (arena) ArrayType();
instanceType = new (arena) InstanceType();
classType = new (arena) ClassType();
addressType = new (arena) AddressType();
illegalType = new (arena) IllegalType();
intZero = new (arena) IntConstant(0);
intOne = new (arena) IntConstant(1);
objectNull = new (arena) ObjectConstant(ciNullObject::make());
};
ValueType* ValueType::meet(ValueType* y) const {
// incomplete & conservative solution for now - fix this!
assert(tag() == y->tag(), "types must match");
return base();
}
ValueType* ValueType::join(ValueType* y) const {
Unimplemented();
return NULL;
}
ciType* ObjectConstant::exact_type() const {
ciObject* c = constant_value();
return (c != NULL && !c->is_null_object()) ? c->klass() : NULL;
}
ciType* ArrayConstant::exact_type() const {
ciObject* c = constant_value();
return (c != NULL && !c->is_null_object()) ? c->klass() : NULL;
}
ciType* InstanceConstant::exact_type() const {
ciObject* c = constant_value();
return (c != NULL && !c->is_null_object()) ? c->klass() : NULL;
}
ciType* ClassConstant::exact_type() const {
return Compilation::current()->env()->Class_klass();
}
jobject ObjectType::encoding() const {
assert(is_constant(), "must be");
return constant_value()->constant_encoding();
}
bool ObjectType::is_loaded() const {
assert(is_constant(), "must be");
return constant_value()->is_loaded();
}
bool MetadataType::is_loaded() const {
assert(is_constant(), "must be");
return constant_value()->is_loaded();
}
ciObject* ObjectConstant::constant_value() const { return _value; }
ciObject* ArrayConstant::constant_value() const { return _value; }
ciObject* InstanceConstant::constant_value() const { return _value; }
ValueType* as_ValueType(BasicType type) {
switch (type) {
case T_VOID : return voidType;
case T_BYTE : // fall through
case T_CHAR : // fall through
case T_SHORT : // fall through
case T_BOOLEAN: // fall through
case T_INT : return intType;
case T_LONG : return longType;
case T_FLOAT : return floatType;
case T_DOUBLE : return doubleType;
case T_ARRAY : return arrayType;
case T_OBJECT : return objectType;
case T_ADDRESS: return addressType;
case T_ILLEGAL: return illegalType;
}
ShouldNotReachHere();
return illegalType;
}
ValueType* as_ValueType(ciConstant value) {
switch (value.basic_type()) {
case T_BYTE : // fall through
case T_CHAR : // fall through
case T_SHORT : // fall through
case T_BOOLEAN: // fall through
case T_INT : return new IntConstant (value.as_int ());
case T_LONG : return new LongConstant (value.as_long ());
case T_FLOAT : return new FloatConstant (value.as_float ());
case T_DOUBLE : return new DoubleConstant(value.as_double());
case T_ARRAY : // fall through (ciConstant doesn't have an array accessor)
case T_OBJECT : {
// TODO: Common the code with GraphBuilder::load_constant?
ciObject* obj = value.as_object();
if (obj->is_null_object())
return objectNull;
if (obj->is_loaded()) {
if (obj->is_array())
return new ArrayConstant(obj->as_array());
else if (obj->is_instance())
return new InstanceConstant(obj->as_instance());
}
return new ObjectConstant(obj);
}
}
ShouldNotReachHere();
return illegalType;
}
BasicType as_BasicType(ValueType* type) {
switch (type->tag()) {
case voidTag: return T_VOID;
case intTag: return T_INT;
case longTag: return T_LONG;
case floatTag: return T_FLOAT;
case doubleTag: return T_DOUBLE;
case objectTag: return T_OBJECT;
case metaDataTag:return T_METADATA;
case addressTag: return T_ADDRESS;
case illegalTag: return T_ILLEGAL;
}
ShouldNotReachHere();
return T_ILLEGAL;
}