< prev index next >
src/share/vm/opto/type.cpp
Print this page
*** 589,598 ****
--- 589,600 ----
TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR );
TypeNarrowOop::BOTTOM = TypeNarrowOop::make( TypeInstPtr::BOTTOM );
TypeNarrowKlass::NULL_PTR = TypeNarrowKlass::make( TypePtr::NULL_PTR );
+ TypeValueTypePtr::NOTNULL = EnableValhalla ? TypeValueTypePtr::make(TypePtr::NotNull, current->env()->___Value_klass()->as_value_klass()) : NULL;
+
mreg2type[Op_Node] = Type::BOTTOM;
mreg2type[Op_Set ] = 0;
mreg2type[Op_RegN] = TypeNarrowOop::BOTTOM;
mreg2type[Op_RegI] = TypeInt::INT;
mreg2type[Op_RegP] = TypePtr::BOTTOM;
*** 1912,1927 ****
const TypeTuple *TypeTuple::INT_PAIR;
const TypeTuple *TypeTuple::LONG_PAIR;
const TypeTuple *TypeTuple::INT_CC_PAIR;
const TypeTuple *TypeTuple::LONG_CC_PAIR;
//------------------------------make-------------------------------------------
// Make a TypeTuple from the range of a method signature
! const TypeTuple *TypeTuple::make_range(ciSignature* sig) {
ciType* return_type = sig->return_type();
! uint arg_cnt = return_type->size();
const Type **field_array = fields(arg_cnt);
switch (return_type->basic_type()) {
case T_LONG:
field_array[TypeFunc::Parms] = TypeLong::LONG;
field_array[TypeFunc::Parms+1] = Type::HALF;
--- 1914,1983 ----
const TypeTuple *TypeTuple::INT_PAIR;
const TypeTuple *TypeTuple::LONG_PAIR;
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;
+ }
+ }
+ }
+
+ // Can a value type instance of this type be returned as multiple
+ // returned values?
+ static bool vt_can_be_returned_as_fields(ciValueKlass* vk) {
+ if (vk == ciEnv::current()->___Value_klass()) {
+ return false;
+ }
+
+ ResourceMark rm;
+ uint args = vk->value_arg_slots() + 1 /* return vk as well */;
+
+ BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, args);
+ VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, args);
+
+ sig_bt[0] = T_METADATA;
+ for (uint i = 0, j = 1; i < (uint)vk->nof_nonstatic_fields(); i++) {
+ BasicType bt = vk->nonstatic_field_at(i)->layout_type();
+ assert(i+j < args, "out of bounds access");
+ sig_bt[i+j] = bt;
+ if (bt == T_LONG || bt == T_DOUBLE) {
+ j++;
+ assert(i+j < args, "out of bounds access");
+ sig_bt[i+j] = T_VOID;
+ }
+ }
+
+ if (SharedRuntime::java_return_convention(sig_bt, regs, args) <= 0) {
+ return false;
+ }
+
+ return true;
+ }
+
//------------------------------make-------------------------------------------
// Make a TypeTuple from the range of a method signature
! const TypeTuple *TypeTuple::make_range(ciSignature* sig, bool ret_vt_fields) {
ciType* return_type = sig->return_type();
! uint arg_cnt = 0;
! if (ret_vt_fields) {
! ret_vt_fields = return_type->is_valuetype() && vt_can_be_returned_as_fields((ciValueKlass*)return_type);
! }
! if (ret_vt_fields) {
! ciValueKlass* vk = (ciValueKlass*)return_type;
! arg_cnt = vk->value_arg_slots()+1;
! } else {
! arg_cnt = return_type->size();
! }
!
const Type **field_array = fields(arg_cnt);
switch (return_type->basic_type()) {
case T_LONG:
field_array[TypeFunc::Parms] = TypeLong::LONG;
field_array[TypeFunc::Parms+1] = Type::HALF;
*** 1929,1968 ****
case T_DOUBLE:
field_array[TypeFunc::Parms] = Type::DOUBLE;
field_array[TypeFunc::Parms+1] = Type::HALF;
break;
case T_OBJECT:
- case T_VALUETYPE:
case T_ARRAY:
case T_BOOLEAN:
case T_CHAR:
case T_FLOAT:
case T_BYTE:
case T_SHORT:
case T_INT:
field_array[TypeFunc::Parms] = get_const_type(return_type);
break;
case T_VOID:
break;
default:
ShouldNotReachHere();
}
return (TypeTuple*)(new TypeTuple(TypeFunc::Parms + arg_cnt, field_array))->hashcons();
}
- 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;
- }
- }
- }
-
// Make a TypeTuple from the domain of a method signature
const TypeTuple *TypeTuple::make_domain(ciInstanceKlass* recv, ciSignature* sig, bool vt_fields_as_args) {
uint arg_cnt = sig->size();
int vt_extra = 0;
--- 1985,2022 ----
case T_DOUBLE:
field_array[TypeFunc::Parms] = Type::DOUBLE;
field_array[TypeFunc::Parms+1] = Type::HALF;
break;
case T_OBJECT:
case T_ARRAY:
case T_BOOLEAN:
case T_CHAR:
case T_FLOAT:
case T_BYTE:
case T_SHORT:
case T_INT:
field_array[TypeFunc::Parms] = get_const_type(return_type);
break;
+ case T_VALUETYPE:
+ if (ret_vt_fields) {
+ ciValueKlass* vk = (ciValueKlass*)return_type;
+ uint pos = TypeFunc::Parms;
+ field_array[pos] = TypeKlassPtr::make(vk);
+ pos++;
+ collect_value_fields(vk, field_array, pos);
+ } else {
+ field_array[TypeFunc::Parms] = get_const_type(return_type);
+ }
+ break;
case T_VOID:
break;
default:
ShouldNotReachHere();
}
return (TypeTuple*)(new TypeTuple(TypeFunc::Parms + arg_cnt, field_array))->hashcons();
}
// Make a TypeTuple from the domain of a method signature
const TypeTuple *TypeTuple::make_domain(ciInstanceKlass* recv, ciSignature* sig, bool vt_fields_as_args) {
uint arg_cnt = sig->size();
int vt_extra = 0;
*** 4699,4708 ****
--- 4753,4763 ----
//=============================================================================
//=============================================================================
+ 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();
}
*** 4806,4815 ****
--- 4861,4886 ----
int depth = meet_inline_depth(tp->inline_depth());
// Compute constant oop
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) {
if (this_oop != NULL && tp_oop != NULL &&
this_oop->equals(tp_oop) ) {
o = this_oop;
} else if (above_centerline(this ->_ptr)) {
*** 4818,4828 ****
o = this_oop;
} else {
ptr = NotNull;
}
}
! return make(_vt, ptr, o, offset, instance_id, speculative, depth);
}
}
}
// Dual: compute field-by-field dual
--- 4889,4899 ----
o = this_oop;
} else {
ptr = NotNull;
}
}
! return make(vt, ptr, o, offset, instance_id, speculative, depth);
}
}
}
// Dual: compute field-by-field dual
*** 5591,5606 ****
//=============================================================================
// Convenience common pre-built types.
//------------------------------make-------------------------------------------
! const TypeFunc *TypeFunc::make( const TypeTuple *domain_sig, const TypeTuple* domain_cc, const TypeTuple *range ) {
! return (TypeFunc*)(new TypeFunc(domain_sig, domain_cc, range))->hashcons();
}
! const TypeFunc *TypeFunc::make( const TypeTuple *domain, const TypeTuple *range ) {
! return make(domain, domain, range);
}
//------------------------------make-------------------------------------------
const TypeFunc *TypeFunc::make(ciMethod* method) {
Compile* C = Compile::current();
--- 5662,5678 ----
//=============================================================================
// Convenience common pre-built types.
//------------------------------make-------------------------------------------
! const TypeFunc *TypeFunc::make(const TypeTuple *domain_sig, const TypeTuple* domain_cc,
! const TypeTuple *range_sig, const TypeTuple *range_cc) {
! return (TypeFunc*)(new TypeFunc(domain_sig, domain_cc, range_sig, range_cc))->hashcons();
}
! const TypeFunc *TypeFunc::make(const TypeTuple *domain, const TypeTuple *range) {
! return make(domain, domain, range, range);
}
//------------------------------make-------------------------------------------
const TypeFunc *TypeFunc::make(ciMethod* method) {
Compile* C = Compile::current();
*** 5618,5629 ****
domain_cc = TypeTuple::make_domain(NULL, method->signature(), ValueTypePassFieldsAsArgs);
} else {
domain_sig = TypeTuple::make_domain(method->holder(), method->signature(), false);
domain_cc = TypeTuple::make_domain(method->holder(), method->signature(), ValueTypePassFieldsAsArgs);
}
! const TypeTuple *range = TypeTuple::make_range(method->signature());
! tf = TypeFunc::make(domain_sig, domain_cc, range);
C->set_last_tf(method, tf); // fill cache
return tf;
}
//------------------------------meet-------------------------------------------
--- 5690,5702 ----
domain_cc = TypeTuple::make_domain(NULL, method->signature(), ValueTypePassFieldsAsArgs);
} 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;
}
//------------------------------meet-------------------------------------------
*** 5657,5688 ****
// Structural equality check for Type representations
bool TypeFunc::eq( const Type *t ) const {
const TypeFunc *a = (const TypeFunc*)t;
return _domain_sig == a->_domain_sig &&
_domain_cc == a->_domain_cc &&
! _range == a->_range;
}
//------------------------------hash-------------------------------------------
// Type-specific hashing function.
int TypeFunc::hash(void) const {
! return (intptr_t)_domain_sig + (intptr_t)_domain_cc + (intptr_t)_range;
}
//------------------------------dump2------------------------------------------
// Dump Function Type
#ifndef PRODUCT
void TypeFunc::dump2( Dict &d, uint depth, outputStream *st ) const {
! if( _range->cnt() <= Parms )
st->print("void");
else {
uint i;
! for (i = Parms; i < _range->cnt()-1; i++) {
! _range->field_at(i)->dump2(d,depth,st);
st->print("/");
}
! _range->field_at(i)->dump2(d,depth,st);
}
st->print(" ");
st->print("( ");
if( !depth || d[this] ) { // Check for recursive dump
st->print("...)");
--- 5730,5762 ----
// Structural equality check for Type representations
bool TypeFunc::eq( const Type *t ) const {
const TypeFunc *a = (const TypeFunc*)t;
return _domain_sig == a->_domain_sig &&
_domain_cc == a->_domain_cc &&
! _range_sig == a->_range_sig &&
! _range_cc == a->_range_cc;
}
//------------------------------hash-------------------------------------------
// Type-specific hashing function.
int TypeFunc::hash(void) const {
! return (intptr_t)_domain_sig + (intptr_t)_domain_cc + (intptr_t)_range_sig + (intptr_t)_range_cc;
}
//------------------------------dump2------------------------------------------
// Dump Function Type
#ifndef PRODUCT
void TypeFunc::dump2( Dict &d, uint depth, outputStream *st ) const {
! if( _range_sig->cnt() <= Parms )
st->print("void");
else {
uint i;
! for (i = Parms; i < _range_sig->cnt()-1; i++) {
! _range_sig->field_at(i)->dump2(d,depth,st);
st->print("/");
}
! _range_sig->field_at(i)->dump2(d,depth,st);
}
st->print(" ");
st->print("( ");
if( !depth || d[this] ) { // Check for recursive dump
st->print("...)");
*** 5711,5720 ****
return false; // Never empty
}
BasicType TypeFunc::return_type() const{
! if (range()->cnt() == TypeFunc::Parms) {
return T_VOID;
}
! return range()->field_at(TypeFunc::Parms)->basic_type();
}
--- 5785,5794 ----
return false; // Never empty
}
BasicType TypeFunc::return_type() const{
! if (range_sig()->cnt() == TypeFunc::Parms) {
return T_VOID;
}
! return range_sig()->field_at(TypeFunc::Parms)->basic_type();
}
< prev index next >