< prev index next >
src/share/vm/opto/type.cpp
Print this page
*** 259,269 ****
case T_ADDRESS:
assert(type->is_return_address(), "");
return TypeRawPtr::make((address)(intptr_t)type->as_return_address()->bci());
case T_VALUETYPE:
! if (type == ciEnv::current()->___Value_klass()) {
return TypeValueTypePtr::NOTNULL;
} else {
return TypeValueType::make(type->as_value_klass());
}
--- 259,269 ----
case T_ADDRESS:
assert(type->is_return_address(), "");
return TypeRawPtr::make((address)(intptr_t)type->as_return_address()->bci());
case T_VALUETYPE:
! if (type->is__Value()) {
return TypeValueTypePtr::NOTNULL;
} else {
return TypeValueType::make(type->as_value_klass());
}
*** 635,644 ****
--- 635,645 ----
// Nobody should ask _array_body_type[T_NARROWOOP]. Use NULL as assert.
TypeAryPtr::_array_body_type[T_NARROWOOP] = NULL;
TypeAryPtr::_array_body_type[T_OBJECT] = TypeAryPtr::OOPS;
TypeAryPtr::_array_body_type[T_ARRAY] = TypeAryPtr::OOPS; // arrays are stored in oop arrays
TypeAryPtr::_array_body_type[T_VALUETYPE] = TypeAryPtr::OOPS;
+ TypeAryPtr::_array_body_type[T_VALUETYPEPTR] = NULL;
TypeAryPtr::_array_body_type[T_BYTE] = TypeAryPtr::BYTES;
TypeAryPtr::_array_body_type[T_BOOLEAN] = TypeAryPtr::BYTES; // boolean[] is a byte array
TypeAryPtr::_array_body_type[T_SHORT] = TypeAryPtr::SHORTS;
TypeAryPtr::_array_body_type[T_CHAR] = TypeAryPtr::CHARS;
TypeAryPtr::_array_body_type[T_INT] = TypeAryPtr::INTS;
*** 685,694 ****
--- 686,696 ----
_const_basic_type[T_INT] = TypeInt::INT;
_const_basic_type[T_LONG] = TypeLong::LONG;
_const_basic_type[T_FLOAT] = Type::FLOAT;
_const_basic_type[T_DOUBLE] = Type::DOUBLE;
_const_basic_type[T_OBJECT] = TypeInstPtr::BOTTOM;
+ _const_basic_type[T_VALUETYPEPTR]= TypeInstPtr::BOTTOM;
_const_basic_type[T_ARRAY] = TypeInstPtr::BOTTOM; // there is no separate bottom for arrays
_const_basic_type[T_VALUETYPE] = TypeInstPtr::BOTTOM;
_const_basic_type[T_VOID] = TypePtr::NULL_PTR; // reflection represents void this way
_const_basic_type[T_ADDRESS] = TypeRawPtr::BOTTOM; // both interpreter return addresses & random raw ptrs
_const_basic_type[T_CONFLICT] = Type::BOTTOM; // why not?
*** 702,711 ****
--- 704,714 ----
_zero_type[T_INT] = TypeInt::ZERO;
_zero_type[T_LONG] = TypeLong::ZERO;
_zero_type[T_FLOAT] = TypeF::ZERO;
_zero_type[T_DOUBLE] = TypeD::ZERO;
_zero_type[T_OBJECT] = TypePtr::NULL_PTR;
+ _zero_type[T_VALUETYPEPTR]= TypePtr::NULL_PTR;
_zero_type[T_ARRAY] = TypePtr::NULL_PTR; // null array is null oop
_zero_type[T_VALUETYPE] = TypePtr::NULL_PTR;
_zero_type[T_ADDRESS] = TypePtr::NULL_PTR; // raw pointers use the same null
_zero_type[T_VOID] = Type::TOP; // the only void value is no value at all
*** 1926,1939 ****
const TypeTuple *TypeTuple::INT_CC_PAIR;
const TypeTuple *TypeTuple::LONG_CC_PAIR;
static void collect_value_fields(ciValueKlass* vk, const Type** field_array, uint& pos) {
for (int j = 0; j < vk->nof_nonstatic_fields(); j++) {
! ciField* f = vk->nonstatic_field_at(j);
! BasicType bt = f->type()->basic_type();
! assert(bt < T_VALUETYPE && bt >= T_BOOLEAN, "not yet supported");
! field_array[pos++] = Type::get_const_type(f->type());
if (bt == T_LONG || bt == T_DOUBLE) {
field_array[pos++] = Type::HALF;
}
}
}
--- 1929,1945 ----
const TypeTuple *TypeTuple::INT_CC_PAIR;
const TypeTuple *TypeTuple::LONG_CC_PAIR;
static void collect_value_fields(ciValueKlass* vk, const Type** field_array, uint& pos) {
for (int j = 0; j < vk->nof_nonstatic_fields(); j++) {
! ciField* field = vk->nonstatic_field_at(j);
! BasicType bt = field->type()->basic_type();
! const Type* ft = Type::get_const_type(field->type());
! if (bt == T_VALUETYPE) {
! ft = ft->isa_valuetypeptr()->cast_to_ptr_type(TypePtr::BotPTR);
! }
! field_array[pos++] = ft;
if (bt == T_LONG || bt == T_DOUBLE) {
field_array[pos++] = Type::HALF;
}
}
}
*** 2002,2012 ****
int vt_extra = 0;
if (vt_fields_as_args) {
for (int i = 0; i < sig->count(); i++) {
ciType* type = sig->type_at(i);
! if (type->basic_type() == T_VALUETYPE && type != ciEnv::current()->___Value_klass()) {
assert(type->is_valuetype(), "inconsistent type");
ciValueKlass* vk = (ciValueKlass*)type;
vt_extra += vk->value_arg_slots()-1;
}
}
--- 2008,2018 ----
int vt_extra = 0;
if (vt_fields_as_args) {
for (int i = 0; i < sig->count(); i++) {
ciType* type = sig->type_at(i);
! if (type->basic_type() == T_VALUETYPE && !type->is__Value()) {
assert(type->is_valuetype(), "inconsistent type");
ciValueKlass* vk = (ciValueKlass*)type;
vt_extra += vk->value_arg_slots()-1;
}
}
*** 2015,2026 ****
uint pos = TypeFunc::Parms;
const Type **field_array;
if (recv != NULL) {
arg_cnt++;
! bool vt_fields_for_recv = vt_fields_as_args && recv->is_valuetype() &&
! recv != ciEnv::current()->___Value_klass();
if (vt_fields_for_recv) {
ciValueKlass* vk = (ciValueKlass*)recv;
vt_extra += vk->value_arg_slots()-1;
}
field_array = fields(arg_cnt + vt_extra);
--- 2021,2031 ----
uint pos = TypeFunc::Parms;
const Type **field_array;
if (recv != NULL) {
arg_cnt++;
! bool vt_fields_for_recv = vt_fields_as_args && recv->is_valuetype() && !recv->is__Value();
if (vt_fields_for_recv) {
ciValueKlass* vk = (ciValueKlass*)recv;
vt_extra += vk->value_arg_slots()-1;
}
field_array = fields(arg_cnt + vt_extra);
*** 2060,2070 ****
case T_SHORT:
field_array[pos++] = TypeInt::INT;
break;
case T_VALUETYPE: {
assert(type->is_valuetype(), "inconsistent type");
! if (vt_fields_as_args && type != ciEnv::current()->___Value_klass()) {
ciValueKlass* vk = (ciValueKlass*)type;
collect_value_fields(vk, field_array, pos);
} else {
field_array[pos++] = get_const_type(type);
}
--- 2065,2075 ----
case T_SHORT:
field_array[pos++] = TypeInt::INT;
break;
case T_VALUETYPE: {
assert(type->is_valuetype(), "inconsistent type");
! if (vt_fields_as_args && !type->is__Value()) {
ciValueKlass* vk = (ciValueKlass*)type;
collect_value_fields(vk, field_array, pos);
} else {
field_array[pos++] = get_const_type(type);
}
*** 2430,2443 ****
}
//------------------------------dump2------------------------------------------
#ifndef PRODUCT
void TypeValueType::dump2(Dict &d, uint depth, outputStream* st) const {
! st->print("valuetype[%d]:{", _vk->field_count());
! st->print("%s", _vk->field_count() != 0 ? _vk->field_type_by_index(0)->name() : "empty");
! for (int i = 1; i < _vk->field_count(); ++i) {
! st->print(", %s", _vk->field_type_by_index(i)->name());
}
st->print("}");
}
#endif
--- 2435,2449 ----
}
//------------------------------dump2------------------------------------------
#ifndef PRODUCT
void TypeValueType::dump2(Dict &d, uint depth, outputStream* st) const {
! int count = _vk->nof_declared_nonstatic_fields();
! st->print("valuetype[%d]:{", count);
! st->print("%s", count != 0 ? _vk->declared_nonstatic_field_at(0)->type()->name() : "empty");
! for (int i = 1; i < count; ++i) {
! st->print(", %s", _vk->declared_nonstatic_field_at(i)->type()->name());
}
st->print("}");
}
#endif
*** 3175,3186 ****
ciValueKlass* vk = klass()->as_value_array_klass()->element_klass()->as_value_klass();
int foffset = field_offset.get() + vk->first_field_offset();
ciField* field = vk->get_field_by_offset(foffset, false);
assert(field != NULL, "missing field");
BasicType bt = field->layout_type();
! assert(bt != T_VALUETYPE, "should be flattened");
! _is_ptr_to_narrowoop = (bt == T_OBJECT || bt == T_ARRAY);
}
} else if (klass()->is_instance_klass()) {
ciInstanceKlass* ik = klass()->as_instance_klass();
ciField* field = NULL;
if (this->isa_klassptr()) {
--- 3181,3192 ----
ciValueKlass* vk = klass()->as_value_array_klass()->element_klass()->as_value_klass();
int foffset = field_offset.get() + vk->first_field_offset();
ciField* field = vk->get_field_by_offset(foffset, false);
assert(field != NULL, "missing field");
BasicType bt = field->layout_type();
! assert(bt != T_VALUETYPEPTR, "unexpected type");
! _is_ptr_to_narrowoop = (bt == T_OBJECT || bt == T_ARRAY || T_VALUETYPE);
}
} else if (klass()->is_instance_klass()) {
ciInstanceKlass* ik = klass()->as_instance_klass();
ciField* field = NULL;
if (this->isa_klassptr()) {
*** 3211,3221 ****
--- 3217,3229 ----
// Instance fields which contains a compressed oop references.
field = ik->get_field_by_offset(this->offset(), false);
if (field != NULL) {
BasicType basic_elem_type = field->layout_type();
_is_ptr_to_narrowoop = UseCompressedOops && (basic_elem_type == T_OBJECT ||
+ basic_elem_type == T_VALUETYPE ||
basic_elem_type == T_ARRAY);
+ assert(basic_elem_type != T_VALUETYPEPTR, "unexpected type");
} else if (klass()->equals(ciEnv::current()->Object_klass())) {
// Compile::find_alias_type() cast exactness on all types to verify
// that it does not affect alias type.
_is_ptr_to_narrowoop = UseCompressedOops;
} else {
*** 4746,4775 ****
if (offset != Type::OffsetBot) {
const Type* elemtype = elem();
if (elemtype->isa_valuetype()) {
uint header = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
if (offset >= (intptr_t)header) {
ciKlass* arytype_klass = klass();
ciValueArrayKlass* vak = arytype_klass->as_value_array_klass();
int shift = vak->log2_element_size();
! intptr_t field_offset = ((offset - header) & ((1 << shift) - 1));
!
return with_field_offset(field_offset)->add_offset(offset - field_offset);
}
}
}
return add_offset(offset);
}
//=============================================================================
//=============================================================================
const TypeValueTypePtr* TypeValueTypePtr::NOTNULL;
//------------------------------make-------------------------------------------
! const TypeValueTypePtr* TypeValueTypePtr::make(const TypeValueType* vt, PTR ptr, ciObject* o, Offset offset, int instance_id, const TypePtr* speculative, int inline_depth) {
return (TypeValueTypePtr*)(new TypeValueTypePtr(vt, ptr, o, offset, instance_id, speculative, inline_depth))->hashcons();
}
const TypePtr* TypeValueTypePtr::add_offset(intptr_t offset) const {
return make(_vt, _ptr, _const_oop, Offset(offset), _instance_id, _speculative, _inline_depth);
--- 4754,4792 ----
if (offset != Type::OffsetBot) {
const Type* elemtype = elem();
if (elemtype->isa_valuetype()) {
uint header = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
if (offset >= (intptr_t)header) {
+ // Try to get the field of the value type array element we are pointing to
ciKlass* arytype_klass = klass();
ciValueArrayKlass* vak = arytype_klass->as_value_array_klass();
+ ciValueKlass* vk = vak->element_klass()->as_value_klass();
int shift = vak->log2_element_size();
! int mask = (1 << shift) - 1;
! intptr_t field_offset = ((offset - header) & mask);
! ciField* field = vk->get_field_by_offset(field_offset + vk->first_field_offset(), false);
! if (field == NULL) {
! // This may happen with nested AddP(base, AddP(base, base, offset), longcon(16))
! return add_offset(offset);
! } else {
! assert(_field_offset.get() <= 0, "should not have field_offset");
return with_field_offset(field_offset)->add_offset(offset - field_offset);
}
}
}
+ }
return add_offset(offset);
}
//=============================================================================
//=============================================================================
const TypeValueTypePtr* TypeValueTypePtr::NOTNULL;
//------------------------------make-------------------------------------------
! const TypeValueTypePtr* TypeValueTypePtr::make(const TypeValueType* vt, PTR ptr, ciObject* o, Offset offset, int instance_id, const TypePtr* speculative, int inline_depth, bool narrow) {
return (TypeValueTypePtr*)(new TypeValueTypePtr(vt, ptr, o, offset, instance_id, speculative, inline_depth))->hashcons();
}
const TypePtr* TypeValueTypePtr::add_offset(intptr_t offset) const {
return make(_vt, _ptr, _const_oop, Offset(offset), _instance_id, _speculative, _inline_depth);
*** 4876,4895 ****
ciObject* o = NULL;
ciObject* this_oop = const_oop();
ciObject* tp_oop = tp->const_oop();
const TypeValueType* vt = NULL;
if (_vt != tp->_vt) {
! ciKlass* __value_klass = ciEnv::current()->___Value_klass();
! assert(klass() == __value_klass || tp->klass() == __value_klass, "impossible meet");
if (above_centerline(ptr)) {
! vt = klass() == __value_klass ? tp->_vt : _vt;
} else if (above_centerline(this->_ptr) && !above_centerline(tp->_ptr)) {
vt = tp->_vt;
} else if (above_centerline(tp->_ptr) && !above_centerline(this->_ptr)) {
vt = _vt;
} else {
! vt = klass() == __value_klass ? _vt : tp->_vt;
}
} else {
vt = _vt;
}
if (ptr == Constant) {
--- 4893,4911 ----
ciObject* o = NULL;
ciObject* this_oop = const_oop();
ciObject* tp_oop = tp->const_oop();
const TypeValueType* vt = NULL;
if (_vt != tp->_vt) {
! assert(is__Value() || tp->is__Value(), "impossible meet");
if (above_centerline(ptr)) {
! vt = is__Value() ? tp->_vt : _vt;
} else if (above_centerline(this->_ptr) && !above_centerline(tp->_ptr)) {
vt = tp->_vt;
} else if (above_centerline(tp->_ptr) && !above_centerline(this->_ptr)) {
vt = _vt;
} else {
! vt = is__Value() ? _vt : tp->_vt;
}
} else {
vt = _vt;
}
if (ptr == Constant) {
*** 4925,4939 ****
// Type-specific hashing function.
int TypeValueTypePtr::hash(void) const {
return java_add(_vt->hash(), TypeOopPtr::hash());
}
! //------------------------------empty------------------------------------------
! // TRUE if Type is a type with no values, FALSE otherwise.
! bool TypeValueTypePtr::empty(void) const {
! // FIXME
! return false;
}
//------------------------------dump2------------------------------------------
#ifndef PRODUCT
void TypeValueTypePtr::dump2(Dict &d, uint depth, outputStream *st) const {
--- 4941,4953 ----
// Type-specific hashing function.
int TypeValueTypePtr::hash(void) const {
return java_add(_vt->hash(), TypeOopPtr::hash());
}
! //------------------------------is__Value--------------------------------------
! bool TypeValueTypePtr::is__Value() const {
! return klass()->equals(TypeKlassPtr::VALUE->klass());
}
//------------------------------dump2------------------------------------------
#ifndef PRODUCT
void TypeValueTypePtr::dump2(Dict &d, uint depth, outputStream *st) const {
*** 5711,5722 ****
} else {
domain_sig = TypeTuple::make_domain(method->holder(), method->signature(), false);
domain_cc = TypeTuple::make_domain(method->holder(), method->signature(), ValueTypePassFieldsAsArgs);
}
const TypeTuple *range_sig = TypeTuple::make_range(method->signature(), false);
! bool as_fields = ValueTypeReturnedAsFields;
! const TypeTuple *range_cc = TypeTuple::make_range(method->signature(), as_fields);
tf = TypeFunc::make(domain_sig, domain_cc, range_sig, range_cc);
C->set_last_tf(method, tf); // fill cache
return tf;
}
--- 5725,5735 ----
} else {
domain_sig = TypeTuple::make_domain(method->holder(), method->signature(), false);
domain_cc = TypeTuple::make_domain(method->holder(), method->signature(), ValueTypePassFieldsAsArgs);
}
const TypeTuple *range_sig = TypeTuple::make_range(method->signature(), false);
! const TypeTuple *range_cc = TypeTuple::make_range(method->signature(), ValueTypeReturnedAsFields);
tf = TypeFunc::make(domain_sig, domain_cc, range_sig, range_cc);
C->set_last_tf(method, tf); // fill cache
return tf;
}
< prev index next >