From e3e81d85bb3c9d23461972b5690a054ba2a7e321 Mon Sep 17 00:00:00 2001 From: "rossberg@chromium.org" Date: Wed, 16 Apr 2014 15:59:39 +0000 Subject: [PATCH] Revert "Implement structural function and array types" TBR=jarin@chromium.org BUG= Review URL: https://codereview.chromium.org/237963016 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20816 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/accessors.cc | 2 +- src/arm/stub-cache-arm.cc | 8 +- src/arm64/stub-cache-arm64.cc | 6 +- src/hydrogen.cc | 8 +- src/hydrogen.h | 2 +- src/ia32/stub-cache-ia32.cc | 9 +- src/ic.cc | 12 +- src/objects-debug.cc | 2 +- src/objects-inl.h | 7 + src/stub-cache.cc | 2 +- src/types-inl.h | 74 ++----- src/types.cc | 374 +++++++++++++-------------------- src/types.h | 382 +++++++++------------------------- src/x64/stub-cache-x64.cc | 10 +- test/cctest/test-types.cc | 323 +++------------------------- 15 files changed, 314 insertions(+), 907 deletions(-) diff --git a/src/accessors.cc b/src/accessors.cc index 32c501a85..2e3bfb80a 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -126,7 +126,7 @@ bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type, } if (!type->IsClass()) return false; - Handle map = type->AsClass()->Map(); + Handle map = type->AsClass(); switch (map->instance_type()) { case JS_ARRAY_TYPE: diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index 6875dcf5a..ebbfce683 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -432,7 +432,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, } else if (representation.IsHeapObject()) { HeapType* field_type = descriptors->GetFieldType(descriptor); if (field_type->IsClass()) { - __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(), + __ CheckMap(value_reg, scratch1, field_type->AsClass(), miss_label, DO_SMI_CHECK); } else { ASSERT(HeapType::Any()->Is(field_type)); @@ -601,7 +601,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, } else if (representation.IsHeapObject()) { HeapType* field_type = lookup->GetFieldType(); if (field_type->IsClass()) { - __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(), + __ CheckMap(value_reg, scratch1, field_type->AsClass(), miss_label, DO_SMI_CHECK); } else { ASSERT(HeapType::Any()->Is(field_type)); @@ -850,9 +850,7 @@ Register StubCompiler::CheckPrototypes(Handle type, int depth = 0; Handle current = Handle::null(); - if (type->IsConstant()) { - current = Handle::cast(type->AsConstant()->Value()); - } + if (type->IsConstant()) current = Handle::cast(type->AsConstant()); Handle prototype = Handle::null(); Handle current_map = receiver_map; Handle holder_map(holder->map()); diff --git a/src/arm64/stub-cache-arm64.cc b/src/arm64/stub-cache-arm64.cc index bf1284098..e5383f166 100644 --- a/src/arm64/stub-cache-arm64.cc +++ b/src/arm64/stub-cache-arm64.cc @@ -394,7 +394,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, } else if (representation.IsHeapObject()) { HeapType* field_type = descriptors->GetFieldType(descriptor); if (field_type->IsClass()) { - __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(), + __ CheckMap(value_reg, scratch1, field_type->AsClass(), miss_label, DO_SMI_CHECK); } else { ASSERT(HeapType::Any()->Is(field_type)); @@ -550,7 +550,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, } else if (representation.IsHeapObject()) { HeapType* field_type = lookup->GetFieldType(); if (field_type->IsClass()) { - __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(), + __ CheckMap(value_reg, scratch1, field_type->AsClass(), miss_label, DO_SMI_CHECK); } else { ASSERT(HeapType::Any()->Is(field_type)); @@ -802,7 +802,7 @@ Register StubCompiler::CheckPrototypes(Handle type, Handle current = Handle::null(); if (type->IsConstant()) { - current = Handle::cast(type->AsConstant()->Value()); + current = Handle::cast(type->AsConstant()); } Handle prototype = Handle::null(); Handle current_map = receiver_map; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 833dc5186..7a9dc90cc 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -4926,7 +4926,7 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { Handle cell(global->GetPropertyCell(&lookup)); if (cell->type()->IsConstant()) { PropertyCell::AddDependentCompilationInfo(cell, top_info()); - Handle constant_object = cell->type()->AsConstant()->Value(); + Handle constant_object = cell->type()->AsConstant(); if (constant_object->IsConsString()) { constant_object = String::Flatten(Handle::cast(constant_object)); @@ -4999,7 +4999,7 @@ void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { static bool CanInlinePropertyAccess(Type* type) { if (type->Is(Type::NumberOrString())) return true; if (!type->IsClass()) return false; - Handle map = type->AsClass()->Map(); + Handle map = type->AsClass(); return map->IsJSObjectMap() && !map->is_dictionary_map() && !map->has_named_interceptor(); @@ -5991,7 +5991,7 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( Handle global(current_info()->global_object()); Handle cell(global->GetPropertyCell(&lookup)); if (cell->type()->IsConstant()) { - Handle constant = cell->type()->AsConstant()->Value(); + Handle constant = cell->type()->AsConstant(); if (value->IsConstant()) { HConstant* c_value = HConstant::cast(value); if (!constant.is_identical_to(c_value->handle(isolate()))) { @@ -9943,7 +9943,7 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( HValue* operand_to_check = left->block()->block_id() < right->block()->block_id() ? left : right; if (combined_type->IsClass()) { - Handle map = combined_type->AsClass()->Map(); + Handle map = combined_type->AsClass(); AddCheckMap(operand_to_check, map); HCompareObjectEqAndBranch* result = New(left, right); diff --git a/src/hydrogen.h b/src/hydrogen.h index c561ab119..b7915e695 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -2380,7 +2380,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { context = context->native_context(); return handle(context->string_function()->initial_map()); } else { - return type_->AsClass()->Map(); + return type_->AsClass(); } } Type* type() const { return type_; } diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 9c8269259..209bfa6d8 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -530,8 +530,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, } else if (representation.IsHeapObject()) { HeapType* field_type = descriptors->GetFieldType(descriptor); if (field_type->IsClass()) { - __ CheckMap(value_reg, field_type->AsClass()->Map(), - miss_label, DO_SMI_CHECK); + __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK); } else { ASSERT(HeapType::Any()->Is(field_type)); __ JumpIfSmi(value_reg, miss_label); @@ -707,8 +706,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, } else if (representation.IsHeapObject()) { HeapType* field_type = lookup->GetFieldType(); if (field_type->IsClass()) { - __ CheckMap(value_reg, field_type->AsClass()->Map(), - miss_label, DO_SMI_CHECK); + __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK); } else { ASSERT(HeapType::Any()->Is(field_type)); __ JumpIfSmi(value_reg, miss_label); @@ -838,8 +836,7 @@ Register StubCompiler::CheckPrototypes(Handle type, int depth = 0; Handle current = Handle::null(); - if (type->IsConstant()) current = - Handle::cast(type->AsConstant()->Value()); + if (type->IsConstant()) current = Handle::cast(type->AsConstant()); Handle prototype = Handle::null(); Handle current_map = receiver_map; Handle holder_map(holder->map()); diff --git a/src/ic.cc b/src/ic.cc index 86bef05e2..ecf0e9a8d 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -680,8 +680,7 @@ bool IC::UpdatePolymorphicIC(Handle type, for (int i = 0; i < number_of_types; i++) { Handle current_type = types.at(i); - if (current_type->IsClass() && - current_type->AsClass()->Map()->is_deprecated()) { + if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { // Filter out deprecated maps to ensure their instances get migrated. ++deprecated_types; } else if (type->NowIs(current_type)) { @@ -692,8 +691,8 @@ bool IC::UpdatePolymorphicIC(Handle type, } else if (handler_to_overwrite == -1 && current_type->IsClass() && type->IsClass() && - IsTransitionOfMonomorphicTarget(*current_type->AsClass()->Map(), - *type->AsClass()->Map())) { + IsTransitionOfMonomorphicTarget(*current_type->AsClass(), + *type->AsClass())) { handler_to_overwrite = i; } } @@ -735,11 +734,10 @@ Handle IC::TypeToMap(HeapType* type, Isolate* isolate) { return isolate->factory()->heap_number_map(); if (type->Is(HeapType::Boolean())) return isolate->factory()->boolean_map(); if (type->IsConstant()) { - return handle( - Handle::cast(type->AsConstant()->Value())->map()); + return handle(Handle::cast(type->AsConstant())->map()); } ASSERT(type->IsClass()); - return type->AsClass()->Map(); + return type->AsClass(); } diff --git a/src/objects-debug.cc b/src/objects-debug.cc index 40132cbf6..2ff70586e 100644 --- a/src/objects-debug.cc +++ b/src/objects-debug.cc @@ -301,7 +301,7 @@ void JSObject::JSObjectVerify() { if (r.IsHeapObject()) ASSERT(value->IsHeapObject()); HeapType* field_type = descriptors->GetFieldType(i); if (field_type->IsClass()) { - Map* map = *field_type->AsClass()->Map(); + Map* map = *field_type->AsClass(); CHECK(!map->is_stable() || HeapObject::cast(value)->map() == map); } else if (r.IsNone()) { CHECK(field_type->Is(HeapType::None())); diff --git a/src/objects-inl.h b/src/objects-inl.h index 023caa5dd..96433eae3 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -87,6 +87,13 @@ PropertyDetails PropertyDetails::AsDeleted() const { } +#define FIXED_TYPED_ARRAY_CAST_ACCESSOR(type) \ + template<> \ + type* type::cast(Object* object) { \ + SLOW_ASSERT(object->Is##type()); \ + return reinterpret_cast(object); \ + } + #define INT_ACCESSORS(holder, name, offset) \ int holder::name() { return READ_INT_FIELD(this, offset); } \ void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 91d31ea30..e7bf06922 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -901,7 +901,7 @@ void LoadStubCompiler::NonexistentHandlerFrontend(Handle type, // check that the global property cell is empty. if (last_map->IsJSGlobalObjectMap()) { Handle global = last.is_null() - ? Handle::cast(type->AsConstant()->Value()) + ? Handle::cast(type->AsConstant()) : Handle::cast(last); GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); } diff --git a/src/types-inl.h b/src/types-inl.h index 6f3f6704b..ad1107b68 100644 --- a/src/types-inl.h +++ b/src/types-inl.h @@ -13,34 +13,6 @@ namespace v8 { namespace internal { -// -------------------------------------------------------------------------- // -// TypeImpl - -template -typename TypeImpl::template Iterator -TypeImpl::Classes() { - if (this->IsBitset()) return Iterator(); - return Iterator(Config::handle(this)); -} - - -template -typename TypeImpl::template Iterator -TypeImpl::Constants() { - if (this->IsBitset()) return Iterator(); - return Iterator(Config::handle(this)); -} - - -template -TypeImpl* TypeImpl::cast(typename Config::Base* object) { - TypeImpl* t = static_cast(object); - ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || - t->IsUnion() || t->IsArray() || t->IsFunction()); - return t; -} - - template bool TypeImpl::NowContains(i::Object* value) { DisallowHeapAllocation no_allocation; @@ -55,23 +27,12 @@ bool TypeImpl::NowContains(i::Object* value) { } -// -------------------------------------------------------------------------- // -// ZoneTypeConfig - // static -template -T* ZoneTypeConfig::handle(T* type) { +Type* ZoneTypeConfig::handle(Type* type) { return type; } -// static -template -T* ZoneTypeConfig::cast(Type* type) { - return static_cast(type); -} - - // static bool ZoneTypeConfig::is_bitset(Type* type) { return reinterpret_cast(type) & 1; @@ -79,20 +40,20 @@ bool ZoneTypeConfig::is_bitset(Type* type) { // static -bool ZoneTypeConfig::is_struct(Type* type, int tag) { - return !is_bitset(type) && struct_tag(as_struct(type)) == tag; +bool ZoneTypeConfig::is_struct(Type* type) { + return !is_bitset(type); } // static bool ZoneTypeConfig::is_class(Type* type) { - return is_struct(type, Type::StructuralType::kClassTag); + return is_struct(type) && struct_tag(as_struct(type)) == Type::kClassTag; } // static bool ZoneTypeConfig::is_constant(Type* type) { - return is_struct(type, Type::StructuralType::kConstantTag); + return is_struct(type) && struct_tag(as_struct(type)) == Type::kConstantTag; } @@ -105,7 +66,7 @@ int ZoneTypeConfig::as_bitset(Type* type) { // static ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) { - ASSERT(!is_bitset(type)); + ASSERT(is_struct(type)); return reinterpret_cast(type); } @@ -146,7 +107,7 @@ ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structured) { // static ZoneTypeConfig::Type* ZoneTypeConfig::from_class( i::Handle map, int lub, Zone* zone) { - Struct* structured = struct_create(Type::StructuralType::kClassTag, 2, zone); + Struct* structured = struct_create(Type::kClassTag, 2, zone); structured[2] = from_bitset(lub); structured[3] = map.location(); return from_struct(structured); @@ -156,8 +117,7 @@ ZoneTypeConfig::Type* ZoneTypeConfig::from_class( // static ZoneTypeConfig::Type* ZoneTypeConfig::from_constant( i::Handle value, int lub, Zone* zone) { - Struct* structured = - struct_create(Type::StructuralType::kConstantTag, 2, zone); + Struct* structured = struct_create(Type::kConstantTag, 2, zone); structured[2] = from_bitset(lub); structured[3] = value.location(); return from_struct(structured); @@ -214,24 +174,14 @@ int ZoneTypeConfig::lub_bitset(Type* type) { return as_bitset(struct_get(as_struct(type), 0)); } - // -------------------------------------------------------------------------- // -// HeapTypeConfig // static -template -i::Handle HeapTypeConfig::handle(T* type) { +i::Handle HeapTypeConfig::handle(Type* type) { return i::handle(type, i::HeapObject::cast(type)->GetIsolate()); } -// static -template -i::Handle HeapTypeConfig::cast(i::Handle type) { - return i::Handle::cast(type); -} - - // static bool HeapTypeConfig::is_bitset(Type* type) { return type->IsSmi(); @@ -251,14 +201,14 @@ bool HeapTypeConfig::is_constant(Type* type) { // static -bool HeapTypeConfig::is_struct(Type* type, int tag) { - return type->IsFixedArray() && struct_tag(as_struct(type)) == tag; +bool HeapTypeConfig::is_struct(Type* type) { + return type->IsFixedArray(); } // static int HeapTypeConfig::as_bitset(Type* type) { - return i::Smi::cast(type)->value(); + return Smi::cast(type)->value(); } diff --git a/src/types.cc b/src/types.cc index f35936211..4ddc14bb3 100644 --- a/src/types.cc +++ b/src/types.cc @@ -12,14 +12,13 @@ namespace internal { template int TypeImpl::NumClasses() { - DisallowHeapAllocation no_allocation; if (this->IsClass()) { return 1; } else if (this->IsUnion()) { - UnionHandle unioned = handle(this->AsUnion()); + StructHandle unioned = this->AsUnion(); int result = 0; - for (int i = 0; i < unioned->Length(); ++i) { - if (unioned->Get(i)->IsClass()) ++result; + for (int i = 0; i < Config::struct_length(unioned); ++i) { + if (Config::struct_get(unioned, i)->IsClass()) ++result; } return result; } else { @@ -30,14 +29,13 @@ int TypeImpl::NumClasses() { template int TypeImpl::NumConstants() { - DisallowHeapAllocation no_allocation; if (this->IsConstant()) { return 1; } else if (this->IsUnion()) { - UnionHandle unioned = handle(this->AsUnion()); + StructHandle unioned = this->AsUnion(); int result = 0; - for (int i = 0; i < unioned->Length(); ++i) { - if (unioned->Get(i)->IsConstant()) ++result; + for (int i = 0; i < Config::struct_length(unioned); ++i) { + if (Config::struct_get(unioned, i)->IsConstant()) ++result; } return result; } else { @@ -50,7 +48,8 @@ template template typename TypeImpl::TypeHandle TypeImpl::Iterator::get_type() { ASSERT(!Done()); - return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_; + return type_->IsUnion() + ? Config::struct_get(type_->AsUnion(), index_) : type_; } @@ -68,7 +67,7 @@ struct TypeImplIteratorAux { return type->IsClass(); } static i::Handle current(typename TypeImpl::TypeHandle type) { - return type->AsClass()->Map(); + return type->AsClass(); } }; @@ -79,7 +78,7 @@ struct TypeImplIteratorAux { } static i::Handle current( typename TypeImpl::TypeHandle type) { - return type->AsConstant()->Value(); + return type->AsConstant(); } }; @@ -96,12 +95,11 @@ i::Handle TypeImpl::Iterator::Current() { template template void TypeImpl::Iterator::Advance() { - DisallowHeapAllocation no_allocation; ++index_; if (type_->IsUnion()) { - UnionHandle unioned = handle(type_->AsUnion()); - for (; index_ < unioned->Length(); ++index_) { - if (matches(unioned->Get(index_))) return; + StructHandle unioned = type_->AsUnion(); + for (; index_ < Config::struct_length(unioned); ++index_) { + if (matches(Config::struct_get(unioned, index_))) return; } } else if (index_ == 0 && matches(type_)) { return; @@ -110,54 +108,30 @@ void TypeImpl::Iterator::Advance() { } -// Get the largest bitset subsumed by this type. -template -int TypeImpl::BitsetType::Glb(TypeImpl* type) { - DisallowHeapAllocation no_allocation; - if (type->IsBitset()) { - return type->AsBitset(); - } else if (type->IsUnion()) { - // All but the first are non-bitsets and thus would yield kNone anyway. - return type->AsUnion()->Get(0)->BitsetGlb(); - } else { - return kNone; - } -} - - // Get the smallest bitset subsuming this type. template -int TypeImpl::BitsetType::Lub(TypeImpl* type) { - DisallowHeapAllocation no_allocation; - if (type->IsBitset()) { - return type->AsBitset(); - } else if (type->IsUnion()) { - UnionHandle unioned = handle(type->AsUnion()); +int TypeImpl::LubBitset() { + if (this->IsBitset()) { + return this->AsBitset(); + } else if (this->IsUnion()) { + StructHandle unioned = this->AsUnion(); int bitset = kNone; - for (int i = 0; i < unioned->Length(); ++i) { - bitset |= unioned->Get(i)->BitsetLub(); + for (int i = 0; i < Config::struct_length(unioned); ++i) { + bitset |= Config::struct_get(unioned, i)->LubBitset(); } return bitset; - } else if (type->IsClass()) { - int bitset = Config::lub_bitset(type); - return bitset ? bitset : Lub(*type->AsClass()->Map()); - } else if (type->IsConstant()) { - int bitset = Config::lub_bitset(type); - return bitset ? bitset : Lub(*type->AsConstant()->Value()); - } else if (type->IsArray()) { - return kArray; - } else if (type->IsFunction()) { - return kFunction; + } else if (this->IsClass()) { + int bitset = Config::lub_bitset(this); + return bitset ? bitset : LubBitset(*this->AsClass()); } else { - UNREACHABLE(); - return kNone; + int bitset = Config::lub_bitset(this); + return bitset ? bitset : LubBitset(*this->AsConstant()); } } template -int TypeImpl::BitsetType::Lub(i::Object* value) { - DisallowHeapAllocation no_allocation; +int TypeImpl::LubBitset(i::Object* value) { if (value->IsSmi()) return kSignedSmall & kTaggedInt; i::Map* map = i::HeapObject::cast(value)->map(); if (map->instance_type() == HEAP_NUMBER_TYPE) { @@ -167,13 +141,12 @@ int TypeImpl::BitsetType::Lub(i::Object* value) { value->ToInt32(&i) ? (Smi::IsValid(i) ? kSignedSmall : kOtherSigned32) : value->ToUint32(&u) ? kUnsigned32 : kFloat); } - return Lub(map); + return LubBitset(map); } template -int TypeImpl::BitsetType::Lub(i::Map* map) { - DisallowHeapAllocation no_allocation; +int TypeImpl::LubBitset(i::Map* map) { switch (map->instance_type()) { case STRING_TYPE: case ASCII_STRING_TYPE: @@ -262,6 +235,20 @@ int TypeImpl::BitsetType::Lub(i::Map* map) { } +// Get the largest bitset subsumed by this type. +template +int TypeImpl::GlbBitset() { + if (this->IsBitset()) { + return this->AsBitset(); + } else if (this->IsUnion()) { + // All but the first are non-bitsets and thus would yield kNone anyway. + return Config::struct_get(this->AsUnion(), 0)->GlbBitset(); + } else { + return kNone; + } +} + + // Most precise _current_ type of a value (usually its class). template typename TypeImpl::TypeHandle TypeImpl::NowOf( @@ -277,48 +264,25 @@ typename TypeImpl::TypeHandle TypeImpl::NowOf( // Check this <= that. template bool TypeImpl::SlowIs(TypeImpl* that) { - DisallowHeapAllocation no_allocation; - // Fast path for bitsets. if (this->IsNone()) return true; if (that->IsBitset()) { - return (BitsetType::Lub(this) | that->AsBitset()) == that->AsBitset(); + return (this->LubBitset() | that->AsBitset()) == that->AsBitset(); } if (that->IsClass()) { - return this->IsClass() - && *this->AsClass()->Map() == *that->AsClass()->Map(); + return this->IsClass() && *this->AsClass() == *that->AsClass(); } if (that->IsConstant()) { - return this->IsConstant() - && *this->AsConstant()->Value() == *that->AsConstant()->Value(); - } - if (that->IsArray()) { - return this->IsArray() - && this->AsArray()->Element()->Equals(that->AsArray()->Element()); - } - if (that->IsFunction()) { - // We currently do not allow for any variance here, in order to keep - // Union and Intersect operations simple. - if (!this->IsFunction()) return false; - FunctionType* this_fun = this->AsFunction(); - FunctionType* that_fun = that->AsFunction(); - if (this_fun->Arity() != that_fun->Arity() || - !this_fun->Result()->Equals(that_fun->Result()) || - !that_fun->Receiver()->Equals(this_fun->Receiver())) { - return false; - } - for (int i = 0; i < this_fun->Arity(); ++i) { - if (!that_fun->Parameter(i)->Equals(this_fun->Parameter(i))) return false; - } - return true; + return this->IsConstant() && *this->AsConstant() == *that->AsConstant(); } // (T1 \/ ... \/ Tn) <= T <=> (T1 <= T) /\ ... /\ (Tn <= T) if (this->IsUnion()) { - UnionHandle unioned = handle(this->AsUnion()); - for (int i = 0; i < unioned->Length(); ++i) { - if (!unioned->Get(i)->Is(that)) return false; + StructHandle unioned = this->AsUnion(); + for (int i = 0; i < Config::struct_length(unioned); ++i) { + TypeHandle this_i = Config::struct_get(unioned, i); + if (!this_i->Is(that)) return false; } return true; } @@ -327,9 +291,10 @@ bool TypeImpl::SlowIs(TypeImpl* that) { // (iff T is not a union) ASSERT(!this->IsUnion()); if (that->IsUnion()) { - UnionHandle unioned = handle(that->AsUnion()); - for (int i = 0; i < unioned->Length(); ++i) { - if (this->Is(unioned->Get(i))) return true; + StructHandle unioned = that->AsUnion(); + for (int i = 0; i < Config::struct_length(unioned); ++i) { + TypeHandle that_i = Config::struct_get(unioned, i); + if (this->Is(that_i)) return true; if (this->IsBitset()) break; // Fast fail, only first field is a bitset. } return false; @@ -341,13 +306,12 @@ bool TypeImpl::SlowIs(TypeImpl* that) { template bool TypeImpl::NowIs(TypeImpl* that) { - DisallowHeapAllocation no_allocation; - // TODO(rossberg): this is incorrect for // Union(Constant(V), T)->NowIs(Class(M)) // but fuzzing does not cover that! + DisallowHeapAllocation no_allocation; if (this->IsConstant()) { - i::Object* object = *this->AsConstant()->Value(); + i::Object* object = *this->AsConstant(); if (object->IsHeapObject()) { i::Map* map = i::HeapObject::cast(object)->map(); for (Iterator it = that->Classes(); !it.Done(); it.Advance()) { @@ -362,48 +326,39 @@ bool TypeImpl::NowIs(TypeImpl* that) { // Check this overlaps that. template bool TypeImpl::Maybe(TypeImpl* that) { - DisallowHeapAllocation no_allocation; - // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T) if (this->IsUnion()) { - UnionHandle unioned = handle(this->AsUnion()); - for (int i = 0; i < unioned->Length(); ++i) { - if (unioned->Get(i)->Maybe(that)) return true; + StructHandle unioned = this->AsUnion(); + for (int i = 0; i < Config::struct_length(unioned); ++i) { + TypeHandle this_i = Config::struct_get(unioned, i); + if (this_i->Maybe(that)) return true; } return false; } // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn) if (that->IsUnion()) { - UnionHandle unioned = handle(that->AsUnion()); - for (int i = 0; i < unioned->Length(); ++i) { - if (this->Maybe(unioned->Get(i))) return true; + StructHandle unioned = that->AsUnion(); + for (int i = 0; i < Config::struct_length(unioned); ++i) { + TypeHandle that_i = Config::struct_get(unioned, i); + if (this->Maybe(that_i)) return true; } return false; } ASSERT(!this->IsUnion() && !that->IsUnion()); if (this->IsBitset()) { - return BitsetType::IsInhabited(this->AsBitset() & that->BitsetLub()); + return IsInhabited(this->AsBitset() & that->LubBitset()); } if (that->IsBitset()) { - return BitsetType::IsInhabited(this->BitsetLub() & that->AsBitset()); + return IsInhabited(this->LubBitset() & that->AsBitset()); } + if (this->IsClass()) { - return that->IsClass() - && *this->AsClass()->Map() == *that->AsClass()->Map(); + return that->IsClass() && *this->AsClass() == *that->AsClass(); } if (this->IsConstant()) { - return that->IsConstant() - && *this->AsConstant()->Value() == *that->AsConstant()->Value(); - } - if (this->IsArray()) { - // There is no variance! - return this->Equals(that); - } - if (this->IsFunction()) { - // There is no variance! - return this->Equals(that); + return that->IsConstant() && *this->AsConstant() == *that->AsConstant(); } return false; @@ -412,20 +367,19 @@ bool TypeImpl::Maybe(TypeImpl* that) { template bool TypeImpl::Contains(i::Object* value) { - DisallowHeapAllocation no_allocation; - for (Iterator it = this->Constants(); !it.Done(); it.Advance()) { if (*it.Current() == value) return true; } - return BitsetType::New(BitsetType::Lub(value))->Is(this); + return Config::from_bitset(LubBitset(value))->Is(this); } template -bool TypeImpl::InUnion(UnionHandle unioned, int current_size) { +bool TypeImpl::InUnion(StructHandle unioned, int current_size) { ASSERT(!this->IsUnion()); for (int i = 0; i < current_size; ++i) { - if (this->Is(unioned->Get(i))) return true; + TypeHandle type = Config::struct_get(unioned, i); + if (this->Is(type)) return true; } return false; } @@ -435,24 +389,22 @@ bool TypeImpl::InUnion(UnionHandle unioned, int current_size) { // starting at index. Returns updated index. template int TypeImpl::ExtendUnion( - UnionHandle result, TypeHandle type, int current_size) { + StructHandle result, TypeHandle type, int current_size) { int old_size = current_size; - if (type->IsUnion()) { - UnionHandle unioned = handle(type->AsUnion()); - for (int i = 0; i < unioned->Length(); ++i) { - TypeHandle type = unioned->Get(i); - ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0)))); + if (type->IsClass() || type->IsConstant()) { + if (!type->InUnion(result, old_size)) { + Config::struct_set(result, current_size++, type); + } + } else if (type->IsUnion()) { + StructHandle unioned = type->AsUnion(); + for (int i = 0; i < Config::struct_length(unioned); ++i) { + TypeHandle type = Config::struct_get(unioned, i); + ASSERT(i == 0 || + !(type->IsBitset() || type->Is(Config::struct_get(unioned, 0)))); if (!type->IsBitset() && !type->InUnion(result, old_size)) { - result->Set(current_size++, type); + Config::struct_set(result, current_size++, type); } } - } else if (!type->IsBitset()) { - // For all structural types, subtyping implies equivalence. - ASSERT(type->IsClass() || type->IsConstant() || - type->IsArray() || type->IsFunction()); - if (!type->InUnion(result, old_size)) { - result->Set(current_size++, type); - } } return current_size; } @@ -464,7 +416,7 @@ typename TypeImpl::TypeHandle TypeImpl::Union( TypeHandle type1, TypeHandle type2, Region* region) { // Fast case: bit sets. if (type1->IsBitset() && type2->IsBitset()) { - return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region); + return Config::from_bitset(type1->AsBitset() | type2->AsBitset(), region); } // Fast case: top or bottom types. @@ -480,28 +432,28 @@ typename TypeImpl::TypeHandle TypeImpl::Union( // Slow case: may need to produce a Unioned object. int size = 0; if (!type1->IsBitset()) { - size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1); + size += (type1->IsUnion() ? Config::struct_length(type1->AsUnion()) : 1); } if (!type2->IsBitset()) { - size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); + size += (type2->IsUnion() ? Config::struct_length(type2->AsUnion()) : 1); } - int bitset = type1->BitsetGlb() | type2->BitsetGlb(); - if (bitset != BitsetType::kNone) ++size; + int bitset = type1->GlbBitset() | type2->GlbBitset(); + if (bitset != kNone) ++size; ASSERT(size >= 1); + StructHandle unioned = Config::struct_create(kUnionTag, size, region); - UnionHandle unioned = UnionType::New(size, region); size = 0; - if (bitset != BitsetType::kNone) { - unioned->Set(size++, BitsetType::New(bitset, region)); + if (bitset != kNone) { + Config::struct_set(unioned, size++, Config::from_bitset(bitset, region)); } size = ExtendUnion(unioned, type1, size); size = ExtendUnion(unioned, type2, size); if (size == 1) { - return unioned->Get(0); + return Config::struct_get(unioned, 0); } else { - unioned->Shrink(size); - return unioned; + Config::struct_shrink(unioned, size); + return Config::from_struct(unioned); } } @@ -510,37 +462,36 @@ typename TypeImpl::TypeHandle TypeImpl::Union( // starting at index. Returns updated index. template int TypeImpl::ExtendIntersection( - UnionHandle result, TypeHandle type, TypeHandle other, int current_size) { + StructHandle result, TypeHandle type, TypeHandle other, int current_size) { int old_size = current_size; - if (type->IsUnion()) { - UnionHandle unioned = handle(type->AsUnion()); - for (int i = 0; i < unioned->Length(); ++i) { - TypeHandle type = unioned->Get(i); - ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0)))); + if (type->IsClass() || type->IsConstant()) { + if (type->Is(other) && !type->InUnion(result, old_size)) { + Config::struct_set(result, current_size++, type); + } + } else if (type->IsUnion()) { + StructHandle unioned = type->AsUnion(); + for (int i = 0; i < Config::struct_length(unioned); ++i) { + TypeHandle type = Config::struct_get(unioned, i); + ASSERT(i == 0 || + !(type->IsBitset() || type->Is(Config::struct_get(unioned, 0)))); if (!type->IsBitset() && type->Is(other) && !type->InUnion(result, old_size)) { - result->Set(current_size++, type); + Config::struct_set(result, current_size++, type); } } - } else if (!type->IsBitset()) { - // For all structural types, subtyping implies equivalence. - ASSERT(type->IsClass() || type->IsConstant() || - type->IsArray() || type->IsFunction()); - if (type->Is(other) && !type->InUnion(result, old_size)) { - result->Set(current_size++, type); - } } return current_size; } // Intersection is O(1) on simple bit unions, but O(n*m) on structured unions. +// TODO(rossberg): Should we use object sets somehow? Is it worth it? template typename TypeImpl::TypeHandle TypeImpl::Intersect( TypeHandle type1, TypeHandle type2, Region* region) { // Fast case: bit sets. if (type1->IsBitset() && type2->IsBitset()) { - return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region); + return Config::from_bitset(type1->AsBitset() & type2->AsBitset(), region); } // Fast case: top or bottom types. @@ -556,19 +507,19 @@ typename TypeImpl::TypeHandle TypeImpl::Intersect( // Slow case: may need to produce a Unioned object. int size = 0; if (!type1->IsBitset()) { - size += (type1->IsUnion() ? type1->AsUnion()->Length() : 1); + size += (type1->IsUnion() ? Config::struct_length(type1->AsUnion()) : 1); } if (!type2->IsBitset()) { - size += (type2->IsUnion() ? type2->AsUnion()->Length() : 1); + size += (type2->IsUnion() ? Config::struct_length(type2->AsUnion()) : 1); } - int bitset = type1->BitsetGlb() & type2->BitsetGlb(); - if (bitset != BitsetType::kNone) ++size; + int bitset = type1->GlbBitset() & type2->GlbBitset(); + if (bitset != kNone) ++size; ASSERT(size >= 1); + StructHandle unioned = Config::struct_create(kUnionTag, size, region); - UnionHandle unioned = UnionType::New(size, region); size = 0; - if (bitset != BitsetType::kNone) { - unioned->Set(size++, BitsetType::New(bitset, region)); + if (bitset != kNone) { + Config::struct_set(unioned, size++, Config::from_bitset(bitset, region)); } size = ExtendIntersection(unioned, type1, type2, size); size = ExtendIntersection(unioned, type2, type1, size); @@ -576,10 +527,10 @@ typename TypeImpl::TypeHandle TypeImpl::Intersect( if (size == 0) { return None(region); } else if (size == 1) { - return unioned->Get(0); + return Config::struct_get(unioned, 0); } else { - unioned->Shrink(size); - return unioned; + Config::struct_shrink(unioned, size); + return Config::from_struct(unioned); } } @@ -589,41 +540,27 @@ template typename TypeImpl::TypeHandle TypeImpl::Convert( typename OtherType::TypeHandle type, Region* region) { if (type->IsBitset()) { - return BitsetType::New(type->AsBitset(), region); + return Config::from_bitset(type->AsBitset(), region); } else if (type->IsClass()) { - return ClassType::New(type->AsClass()->Map(), region); + return Config::from_class(type->AsClass(), type->LubBitset(), region); } else if (type->IsConstant()) { - return ConstantType::New(type->AsConstant()->Value(), region); - } else if (type->IsUnion()) { - int length = type->AsUnion()->Length(); - UnionHandle unioned = UnionType::New(length, region); + return Config::from_constant(type->AsConstant(), type->LubBitset(), region); + } else { + ASSERT(type->IsUnion()); + typename OtherType::StructHandle unioned = type->AsUnion(); + int length = OtherType::StructLength(unioned); + StructHandle new_unioned = Config::struct_create(kUnionTag, length, region); for (int i = 0; i < length; ++i) { - unioned->Set(i, Convert(type->AsUnion()->Get(i), region)); - } - return unioned; - } else if (type->IsArray()) { - return ArrayType::New( - Convert(type->AsArray()->Element(), region), region); - } else if (type->IsFunction()) { - FunctionHandle function = FunctionType::New( - Convert(type->AsFunction()->Result(), region), - Convert(type->AsFunction()->Receiver(), region), - type->AsFunction()->Arity(), region); - for (int i = 0; i < function->Arity(); ++i) { - function->InitParameter(i, - Convert(type->AsFunction()->Parameter(i), region)); + Config::struct_set(new_unioned, i, + Convert(OtherType::StructGet(unioned, i), region)); } - return function; - } else { - UNREACHABLE(); - return None(region); + return Config::from_struct(new_unioned); } } // TODO(rossberg): this does not belong here. Representation Representation::FromType(Type* type) { - DisallowHeapAllocation no_allocation; if (type->Is(Type::None())) return Representation::None(); if (type->Is(Type::SignedSmall())) return Representation::Smi(); if (type->Is(Type::Signed32())) return Representation::Integer32(); @@ -641,7 +578,7 @@ void TypeImpl::TypePrint(PrintDimension dim) { template -const char* TypeImpl::BitsetType::Name(int bitset) { +const char* TypeImpl::bitset_name(int bitset) { switch (bitset) { case kAny & kRepresentation: return "Any"; #define PRINT_COMPOSED_TYPE(type, value) \ @@ -661,9 +598,8 @@ const char* TypeImpl::BitsetType::Name(int bitset) { template -void TypeImpl::BitsetType::BitsetTypePrint(FILE* out, int bitset) { - DisallowHeapAllocation no_allocation; - const char* name = Name(bitset); +void TypeImpl::BitsetTypePrint(FILE* out, int bitset) { + const char* name = bitset_name(bitset); if (name != NULL) { PrintF(out, "%s", name); } else { @@ -684,7 +620,7 @@ void TypeImpl::BitsetType::BitsetTypePrint(FILE* out, int bitset) { if ((bitset & subset) == subset) { if (!is_first) PrintF(out, " | "); is_first = false; - PrintF(out, "%s", Name(subset)); + PrintF(out, "%s", bitset_name(subset)); bitset -= subset; } } @@ -696,58 +632,38 @@ void TypeImpl::BitsetType::BitsetTypePrint(FILE* out, int bitset) { template void TypeImpl::TypePrint(FILE* out, PrintDimension dim) { - DisallowHeapAllocation no_allocation; if (this->IsBitset()) { int bitset = this->AsBitset(); switch (dim) { case BOTH_DIMS: - BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic); + BitsetTypePrint(out, bitset & kSemantic); PrintF(out, "/"); - BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation); + BitsetTypePrint(out, bitset & kRepresentation); break; case SEMANTIC_DIM: - BitsetType::BitsetTypePrint(out, bitset & BitsetType::kSemantic); + BitsetTypePrint(out, bitset & kSemantic); break; case REPRESENTATION_DIM: - BitsetType::BitsetTypePrint(out, bitset & BitsetType::kRepresentation); + BitsetTypePrint(out, bitset & kRepresentation); break; } } else if (this->IsConstant()) { - PrintF(out, "Constant(%p : ", - static_cast(*this->AsConstant()->Value())); - BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim); + PrintF(out, "Constant(%p : ", static_cast(*this->AsConstant())); + Config::from_bitset(this->LubBitset())->TypePrint(out, dim); PrintF(out, ")"); } else if (this->IsClass()) { - PrintF(out, "Class(%p < ", static_cast(*this->AsClass()->Map())); - BitsetType::New(BitsetType::Lub(this))->TypePrint(out, dim); + PrintF(out, "Class(%p < ", static_cast(*this->AsClass())); + Config::from_bitset(this->LubBitset())->TypePrint(out, dim); PrintF(out, ")"); } else if (this->IsUnion()) { PrintF(out, "("); - UnionHandle unioned = handle(this->AsUnion()); - for (int i = 0; i < unioned->Length(); ++i) { - TypeHandle type_i = unioned->Get(i); + StructHandle unioned = this->AsUnion(); + for (int i = 0; i < Config::struct_length(unioned); ++i) { + TypeHandle type_i = Config::struct_get(unioned, i); if (i > 0) PrintF(out, " | "); type_i->TypePrint(out, dim); } PrintF(out, ")"); - } else if (this->IsArray()) { - PrintF(out, "["); - AsArray()->Element()->TypePrint(out, dim); - PrintF(out, "]"); - } else if (this->IsFunction()) { - if (!this->AsFunction()->Receiver()->IsAny()) { - this->AsFunction()->Receiver()->TypePrint(out, dim); - PrintF(out, "."); - } - PrintF(out, "("); - for (int i = 0; i < this->AsFunction()->Arity(); ++i) { - if (i > 0) PrintF(out, ", "); - this->AsFunction()->Parameter(i)->TypePrint(out, dim); - } - PrintF(out, ")->"); - this->AsFunction()->Result()->TypePrint(out, dim); - } else { - UNREACHABLE(); } } diff --git a/src/types.h b/src/types.h index 363d45f41..3a3bc3bd0 100644 --- a/src/types.h +++ b/src/types.h @@ -43,11 +43,7 @@ namespace internal { // // Class(map) < T iff instance_type(map) < T // Constant(x) < T iff instance_type(map(x)) < T -// Array(T) < Array -// Function(R, S, T0, T1, ...) < Function // -// Both structural Array and Function types are invariant in all parameters. -// Relaxing this would make Union and Intersect operations more involved. // Note that Constant(x) < Class(map(x)) does _not_ hold, since x's map can // change! (Its instance type cannot, however.) // TODO(rossberg): the latter is not currently true for proxies, because of fix, @@ -96,7 +92,7 @@ namespace internal { // lattice. That is intentional. It should always be possible to refine the // lattice (e.g., splitting up number types further) without invalidating any // existing assumptions or tests. -// Consequently, do not normally use Equals for type tests, always use Is! +// Consequently, do not use pointer equality for type tests, always use Is! // // The NowIs operator implements state-sensitive subtying, as described above. // Any compilation decision based on such temporary properties requires runtime @@ -193,17 +189,15 @@ namespace internal { // struct Config { -// typedef TypeImpl Type; // typedef Base; // typedef Struct; // typedef Region; // template struct Handle { typedef type; } // No template typedefs... -// template static Handle::type handle(T* t); // !is_bitset(t) -// template static Handle::type cast(Handle::type); +// static Handle::type handle(Type* type); // !is_bitset(type) // static bool is_bitset(Type*); // static bool is_class(Type*); // static bool is_constant(Type*); -// static bool is_struct(Type*, int tag); +// static bool is_struct(Type*); // static int as_bitset(Type*); // static i::Handle as_class(Type*); // static i::Handle as_constant(Type*); @@ -212,7 +206,7 @@ namespace internal { // static Handle::type from_bitset(int bitset, Region*); // static Handle::type from_class(i::Handle, int lub, Region*); // static Handle::type from_constant(i::Handle, int, Region*); -// static Handle::type from_struct(Handle::type, int tag); +// static Handle::type from_struct(Handle::type); // static Handle::type struct_create(int tag, int length, Region*); // static void struct_shrink(Handle::type, int length); // static int struct_tag(Handle::type); @@ -224,73 +218,36 @@ namespace internal { template class TypeImpl : public Config::Base { public: - class BitsetType; // Internal - class StructuralType; // Internal - class UnionType; // Internal - - class ClassType; - class ConstantType; - class ArrayType; - class FunctionType; - typedef typename Config::template Handle::type TypeHandle; - typedef typename Config::template Handle::type ClassHandle; - typedef typename Config::template Handle::type ConstantHandle; - typedef typename Config::template Handle::type ArrayHandle; - typedef typename Config::template Handle::type FunctionHandle; - typedef typename Config::template Handle::type UnionHandle; typedef typename Config::Region Region; - #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ - static TypeImpl* type() { return BitsetType::New(BitsetType::k##type); } \ - static TypeHandle type(Region* region) { \ - return BitsetType::New(BitsetType::k##type, region); \ + #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ + static TypeImpl* type() { return Config::from_bitset(k##type); } \ + static TypeHandle type(Region* region) { \ + return Config::from_bitset(k##type, region); \ } BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) #undef DEFINE_TYPE_CONSTRUCTOR static TypeHandle Class(i::Handle map, Region* region) { - return ClassType::New(map, region); + return Config::from_class(map, LubBitset(*map), region); } static TypeHandle Constant(i::Handle value, Region* region) { - return ConstantType::New(value, region); - } - static TypeHandle Array(TypeHandle element, Region* region) { - return ArrayType::New(element, region); - } - static FunctionHandle Function( - TypeHandle result, TypeHandle receiver, int arity, Region* region) { - return FunctionType::New(result, receiver, arity, region); - } - static TypeHandle Function(TypeHandle result, Region* region) { - return Function(result, Any(region), 0, region); - } - static TypeHandle Function( - TypeHandle result, TypeHandle param0, Region* region) { - FunctionHandle function = Function(result, Any(region), 1, region); - function->InitParameter(0, param0); - return function; - } - static TypeHandle Function( - TypeHandle result, TypeHandle param0, TypeHandle param1, Region* region) { - FunctionHandle function = Function(result, Any(region), 2, region); - function->InitParameter(0, param0); - function->InitParameter(1, param1); - return function; + return Config::from_constant(value, LubBitset(*value), region); } static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg); static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg); static TypeHandle Of(i::Object* value, Region* region) { - return Config::from_bitset(BitsetType::Lub(value), region); + return Config::from_bitset(LubBitset(value), region); } static TypeHandle Of(i::Handle value, Region* region) { return Of(*value, region); } bool IsInhabited() { - return !this->IsBitset() || BitsetType::IsInhabited(this->AsBitset()); + return !this->IsBitset() || IsInhabited(this->AsBitset()); } bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); } @@ -301,10 +258,6 @@ class TypeImpl : public Config::Base { template bool Maybe(TypeHandle that) { return this->Maybe(*that); } - bool Equals(TypeImpl* that) { return this->Is(that) && that->Is(this); } - template - bool Equals(TypeHandle that) { return this->Equals(*that); } - // Equivalent to Constant(value)->Is(this), but avoiding allocation. bool Contains(i::Object* val); bool Contains(i::Handle val) { return this->Contains(*val); } @@ -323,256 +276,127 @@ class TypeImpl : public Config::Base { bool IsClass() { return Config::is_class(this); } bool IsConstant() { return Config::is_constant(this); } - bool IsArray() { return Config::is_struct(this, StructuralType::kArrayTag); } - bool IsFunction() { - return Config::is_struct(this, StructuralType::kFunctionTag); - } - - ClassType* AsClass() { return ClassType::cast(this); } - ConstantType* AsConstant() { return ConstantType::cast(this); } - ArrayType* AsArray() { return ArrayType::cast(this); } - FunctionType* AsFunction() { return FunctionType::cast(this); } + i::Handle AsClass() { return Config::as_class(this); } + i::Handle AsConstant() { return Config::as_constant(this); } int NumClasses(); int NumConstants(); - template class Iterator; - inline Iterator Classes(); - inline Iterator Constants(); - - static inline TypeImpl* cast(typename Config::Base* object); - - template - static TypeHandle Convert( - typename OtherTypeImpl::TypeHandle type, Region* region); - - enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM }; - void TypePrint(PrintDimension = BOTH_DIMS); - void TypePrint(FILE* out, PrintDimension = BOTH_DIMS); - - protected: - template friend class Iterator; - template friend class TypeImpl; - template - static typename Config::template Handle::type handle(T* type) { - return Config::handle(type); - } - - bool IsNone() { return this == None(); } - bool IsAny() { return this == Any(); } - bool IsBitset() { return Config::is_bitset(this); } - bool IsUnion() { return Config::is_struct(this, StructuralType::kUnionTag); } - - int AsBitset() { - ASSERT(this->IsBitset()); - return static_cast(this)->Bitset(); - } - UnionType* AsUnion() { return UnionType::cast(this); } - - bool SlowIs(TypeImpl* that); - - bool InUnion(UnionHandle unioned, int current_size); - static int ExtendUnion( - UnionHandle unioned, TypeHandle t, int current_size); - static int ExtendIntersection( - UnionHandle unioned, TypeHandle t, TypeHandle other, int current_size); - - int BitsetGlb() { return BitsetType::Glb(this); } - int BitsetLub() { return BitsetType::Lub(this); } -}; - + class Iterator { + public: + bool Done() const { return index_ < 0; } + i::Handle Current(); + void Advance(); + + private: + template friend class TypeImpl; + + Iterator() : index_(-1) {} + explicit Iterator(TypeHandle type) : type_(type), index_(-1) { + Advance(); + } -template -class TypeImpl::BitsetType : public TypeImpl { - private: - friend class TypeImpl; + inline bool matches(TypeHandle type); + inline TypeHandle get_type(); - enum { - #define DECLARE_TYPE(type, value) k##type = (value), - BITSET_TYPE_LIST(DECLARE_TYPE) - #undef DECLARE_TYPE - kUnusedEOL = 0 + TypeHandle type_; + int index_; }; - int Bitset() { return Config::as_bitset(this); } - - static BitsetType* New(int bitset) { - return static_cast(Config::from_bitset(bitset)); + Iterator Classes() { + if (this->IsBitset()) return Iterator(); + return Iterator(Config::handle(this)); } - static TypeHandle New(int bitset, Region* region) { - return Config::from_bitset(bitset, region); + Iterator Constants() { + if (this->IsBitset()) return Iterator(); + return Iterator(Config::handle(this)); } - static bool IsInhabited(int bitset) { - return (bitset & kRepresentation) && (bitset & kSemantic); + static TypeImpl* cast(typename Config::Base* object) { + TypeImpl* t = static_cast(object); + ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion()); + return t; } - static int Glb(TypeImpl* type); // greatest lower bound that's a bitset - static int Lub(TypeImpl* type); // least upper bound that's a bitset - static int Lub(i::Object* value); - static int Lub(i::Map* map); - - static const char* Name(int bitset); - static void BitsetTypePrint(FILE* out, int bitset); -}; + template + static TypeHandle Convert( + typename OtherTypeImpl::TypeHandle type, Region* region); + enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM }; + void TypePrint(PrintDimension = BOTH_DIMS); + void TypePrint(FILE* out, PrintDimension = BOTH_DIMS); -// Internal -// A structured type contains a tag and a variable number of type fields. -template -class TypeImpl::StructuralType : public TypeImpl { - protected: + private: + template friend class Iterator; template friend class TypeImpl; - friend struct ZoneTypeConfig; // For tags. + friend struct ZoneTypeConfig; friend struct HeapTypeConfig; enum Tag { kClassTag, kConstantTag, - kArrayTag, - kFunctionTag, kUnionTag }; - int Length() { - return Config::struct_length(Config::as_struct(this)); - } - TypeHandle Get(int i) { - return Config::struct_get(Config::as_struct(this), i); - } - void Set(int i, TypeHandle type) { - Config::struct_set(Config::as_struct(this), i, type); - } - void Shrink(int length) { - Config::struct_shrink(Config::as_struct(this), length); - } - - static TypeHandle New(Tag tag, int length, Region* region) { - return Config::from_struct(Config::struct_create(tag, length, region)); - } -}; - - -template -class TypeImpl::ClassType : public TypeImpl { - public: - i::Handle Map() { return Config::as_class(this); } - - static ClassHandle New(i::Handle map, Region* region) { - return Config::template cast( - Config::from_class(map, BitsetType::Lub(*map), region)); - } - - static ClassType* cast(TypeImpl* type) { - ASSERT(type->IsClass()); - return static_cast(type); - } -}; - - -template -class TypeImpl::ConstantType : public TypeImpl { - public: - i::Handle Value() { return Config::as_constant(this); } - - static ConstantHandle New(i::Handle value, Region* region) { - return Config::template cast( - Config::from_constant(value, BitsetType::Lub(*value), region)); - } - - static ConstantType* cast(TypeImpl* type) { - ASSERT(type->IsConstant()); - return static_cast(type); - } -}; + // A structured type contains a tag an a variable number of type fields. + // A union is a structured type with the following invariants: + // - its length is at least 2 + // - at most one field is a bitset, and it must go into index 0 + // - no field is a union + typedef typename Config::Struct Struct; + typedef typename Config::template Handle::type StructHandle; + enum { + #define DECLARE_TYPE(type, value) k##type = (value), + BITSET_TYPE_LIST(DECLARE_TYPE) + #undef DECLARE_TYPE + kUnusedEOL = 0 + }; -// Internal -// A union is a structured type with the following invariants: -// - its length is at least 2 -// - at most one field is a bitset, and it must go into index 0 -// - no field is a union -template -class TypeImpl::UnionType : public StructuralType { - public: - static UnionHandle New(int length, Region* region) { - return Config::template cast( - StructuralType::New(StructuralType::kUnionTag, length, region)); + bool IsNone() { return this == None(); } + bool IsAny() { return this == Any(); } + bool IsBitset() { return Config::is_bitset(this); } + bool IsStruct(Tag tag) { + return Config::is_struct(this) + && Config::struct_tag(Config::as_struct(this)) == tag; } + bool IsUnion() { return IsStruct(kUnionTag); } - static UnionType* cast(TypeImpl* type) { - ASSERT(type->IsUnion()); - return static_cast(type); + int AsBitset() { return Config::as_bitset(this); } + StructHandle AsStruct(Tag tag) { + ASSERT(IsStruct(tag)); + return Config::as_struct(this); } -}; + StructHandle AsUnion() { return AsStruct(kUnionTag); } - -template -class TypeImpl::ArrayType : public StructuralType { - public: - TypeHandle Element() { return this->Get(0); } - - static ArrayHandle New(TypeHandle element, Region* region) { - ArrayHandle type = Config::template cast( - StructuralType::New(StructuralType::kArrayTag, 1, region)); - type->Set(0, element); - return type; + static int StructLength(StructHandle structured) { + return Config::struct_length(structured); } - - static ArrayType* cast(TypeImpl* type) { - ASSERT(type->IsArray()); - return static_cast(type); + static TypeHandle StructGet(StructHandle structured, int i) { + return Config::struct_get(structured, i); } -}; - -template -class TypeImpl::FunctionType : public StructuralType { - public: - int Arity() { return this->Length() - 2; } - TypeHandle Result() { return this->Get(0); } - TypeHandle Receiver() { return this->Get(1); } - TypeHandle Parameter(int i) { return this->Get(2 + i); } - - void InitParameter(int i, TypeHandle type) { this->Set(2 + i, type); } - - static FunctionHandle New( - TypeHandle result, TypeHandle receiver, int arity, Region* region) { - FunctionHandle type = Config::template cast( - StructuralType::New(StructuralType::kFunctionTag, 2 + arity, region)); - type->Set(0, result); - type->Set(1, receiver); - return type; - } + bool SlowIs(TypeImpl* that); - static FunctionType* cast(TypeImpl* type) { - ASSERT(type->IsFunction()); - return static_cast(type); + static bool IsInhabited(int bitset) { + return (bitset & kRepresentation) && (bitset & kSemantic); } -}; + int LubBitset(); // least upper bound that's a bitset + int GlbBitset(); // greatest lower bound that's a bitset -template template -class TypeImpl::Iterator { - public: - bool Done() const { return index_ < 0; } - i::Handle Current(); - void Advance(); + static int LubBitset(i::Object* value); + static int LubBitset(i::Map* map); - private: - template friend class TypeImpl; - - Iterator() : index_(-1) {} - explicit Iterator(TypeHandle type) : type_(type), index_(-1) { - Advance(); - } - - inline bool matches(TypeHandle type); - inline TypeHandle get_type(); + bool InUnion(StructHandle unioned, int current_size); + static int ExtendUnion( + StructHandle unioned, TypeHandle t, int current_size); + static int ExtendIntersection( + StructHandle unioned, TypeHandle t, TypeHandle other, int current_size); - TypeHandle type_; - int index_; + static const char* bitset_name(int bitset); + static void BitsetTypePrint(FILE* out, int bitset); }; @@ -585,33 +409,27 @@ struct ZoneTypeConfig { typedef i::Zone Region; template struct Handle { typedef T* type; }; - template static inline T* handle(T* type); - template static inline T* cast(Type* type); - + static inline Type* handle(Type* type); static inline bool is_bitset(Type* type); static inline bool is_class(Type* type); static inline bool is_constant(Type* type); - static inline bool is_struct(Type* type, int tag); - + static inline bool is_struct(Type* type); static inline int as_bitset(Type* type); static inline Struct* as_struct(Type* type); static inline i::Handle as_class(Type* type); static inline i::Handle as_constant(Type* type); - static inline Type* from_bitset(int bitset); static inline Type* from_bitset(int bitset, Zone* zone); static inline Type* from_struct(Struct* structured); static inline Type* from_class(i::Handle map, int lub, Zone* zone); static inline Type* from_constant( i::Handle value, int lub, Zone* zone); - static inline Struct* struct_create(int tag, int length, Zone* zone); static inline void struct_shrink(Struct* structured, int length); static inline int struct_tag(Struct* structured); static inline int struct_length(Struct* structured); static inline Type* struct_get(Struct* structured, int i); static inline void struct_set(Struct* structured, int i, Type* type); - static inline int lub_bitset(Type* type); }; @@ -627,19 +445,15 @@ struct HeapTypeConfig { typedef i::Isolate Region; template struct Handle { typedef i::Handle type; }; - template static inline i::Handle handle(T* type); - template static inline i::Handle cast(i::Handle type); - + static inline i::Handle handle(Type* type); static inline bool is_bitset(Type* type); static inline bool is_class(Type* type); static inline bool is_constant(Type* type); - static inline bool is_struct(Type* type, int tag); - + static inline bool is_struct(Type* type); static inline int as_bitset(Type* type); static inline i::Handle as_class(Type* type); static inline i::Handle as_constant(Type* type); static inline i::Handle as_struct(Type* type); - static inline Type* from_bitset(int bitset); static inline i::Handle from_bitset(int bitset, Isolate* isolate); static inline i::Handle from_class( @@ -647,7 +461,6 @@ struct HeapTypeConfig { static inline i::Handle from_constant( i::Handle value, int lub, Isolate* isolate); static inline i::Handle from_struct(i::Handle structured); - static inline i::Handle struct_create( int tag, int length, Isolate* isolate); static inline void struct_shrink(i::Handle structured, int length); @@ -656,7 +469,6 @@ struct HeapTypeConfig { static inline i::Handle struct_get(i::Handle structured, int i); static inline void struct_set( i::Handle structured, int i, i::Handle type); - static inline int lub_bitset(Type* type); }; diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index 0981114ec..88e7f38c4 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -496,8 +496,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, } else if (representation.IsHeapObject()) { HeapType* field_type = descriptors->GetFieldType(descriptor); if (field_type->IsClass()) { - __ CheckMap(value_reg, field_type->AsClass()->Map(), - miss_label, DO_SMI_CHECK); + __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK); } else { ASSERT(HeapType::Any()->Is(field_type)); __ JumpIfSmi(value_reg, miss_label); @@ -647,8 +646,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, } else if (representation.IsHeapObject()) { HeapType* field_type = lookup->GetFieldType(); if (field_type->IsClass()) { - __ CheckMap(value_reg, field_type->AsClass()->Map(), - miss_label, DO_SMI_CHECK); + __ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK); } else { ASSERT(HeapType::Any()->Is(field_type)); __ JumpIfSmi(value_reg, miss_label); @@ -755,9 +753,7 @@ Register StubCompiler::CheckPrototypes(Handle type, int depth = 0; Handle current = Handle::null(); - if (type->IsConstant()) { - current = Handle::cast(type->AsConstant()->Value()); - } + if (type->IsConstant()) current = Handle::cast(type->AsConstant()); Handle prototype = Handle::null(); Handle current_map = receiver_map; Handle holder_map(holder->map()); diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc index 59a8f0851..62ec698ec 100644 --- a/test/cctest/test-types.cc +++ b/test/cctest/test-types.cc @@ -43,9 +43,7 @@ struct ZoneRep { static bool IsBitset(Type* t) { return reinterpret_cast(t) & 1; } static bool IsClass(Type* t) { return IsStruct(t, 0); } static bool IsConstant(Type* t) { return IsStruct(t, 1); } - static bool IsArray(Type* t) { return IsStruct(t, 2); } - static bool IsFunction(Type* t) { return IsStruct(t, 3); } - static bool IsUnion(Type* t) { return IsStruct(t, 4); } + static bool IsUnion(Type* t) { return IsStruct(t, 2); } static Struct* AsStruct(Type* t) { return reinterpret_cast(t); @@ -79,9 +77,7 @@ struct HeapRep { static bool IsBitset(Handle t) { return t->IsSmi(); } static bool IsClass(Handle t) { return t->IsMap(); } static bool IsConstant(Handle t) { return t->IsBox(); } - static bool IsArray(Handle t) { return IsStruct(t, 2); } - static bool IsFunction(Handle t) { return IsStruct(t, 3); } - static bool IsUnion(Handle t) { return IsStruct(t, 4); } + static bool IsUnion(Handle t) { return IsStruct(t, 2); } static Struct* AsStruct(Handle t) { return FixedArray::cast(*t); } static int AsBitset(Handle t) { return Smi::cast(*t)->value(); } @@ -143,31 +139,11 @@ class Types { types.push_back(Type::Constant(*it, region)); } - FloatArray = Type::Array(Float, region); - StringArray = Type::Array(String, region); - AnyArray = Type::Array(Any, region); - - SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region); - NumberFunction1 = Type::Function(Number, Number, region); - NumberFunction2 = Type::Function(Number, Number, Number, region); - MethodFunction = Type::Function(String, Object, 0, region); - for (int i = 0; i < 50; ++i) { types.push_back(Fuzz()); } } - Handle object_map; - Handle array_map; - Handle uninitialized_map; - - Handle smi; - Handle signed32; - Handle object1; - Handle object2; - Handle array; - Handle uninitialized; - #define DECLARE_TYPE(name, value) TypeHandle name; BITSET_TYPE_LIST(DECLARE_TYPE) #undef DECLARE_TYPE @@ -183,14 +159,16 @@ class Types { TypeHandle ArrayConstant; TypeHandle UninitializedConstant; - TypeHandle FloatArray; - TypeHandle StringArray; - TypeHandle AnyArray; + Handle object_map; + Handle array_map; + Handle uninitialized_map; - TypeHandle SignedFunction1; - TypeHandle NumberFunction1; - TypeHandle NumberFunction2; - TypeHandle MethodFunction; + Handle smi; + Handle signed32; + Handle object1; + Handle object2; + Handle array; + Handle uninitialized; typedef std::vector TypeVector; typedef std::vector > MapVector; @@ -215,24 +193,6 @@ class Types { return Type::Class(map, region_); } - TypeHandle Array1(TypeHandle element) { - return Type::Array(element, region_); - } - - TypeHandle Function0(TypeHandle result, TypeHandle receiver) { - return Type::Function(result, receiver, 0, region_); - } - - TypeHandle Function1(TypeHandle result, TypeHandle receiver, TypeHandle arg) { - TypeHandle type = Type::Function(result, receiver, 1, region_); - type->AsFunction()->InitParameter(0, arg); - return type; - } - - TypeHandle Function2(TypeHandle result, TypeHandle arg1, TypeHandle arg2) { - return Type::Function(result, arg1, arg2, region_); - } - TypeHandle Union(TypeHandle t1, TypeHandle t2) { return Type::Union(t1, t2, region_); } @@ -245,10 +205,6 @@ class Types { return Type::template Convert(t, region_); } - TypeHandle Random() { - return types[rng_.NextInt(static_cast(types.size()))]; - } - TypeHandle Fuzz(int depth = 5) { switch (rng_.NextInt(depth == 0 ? 3 : 20)) { case 0: { // bitset @@ -272,17 +228,6 @@ class Types { int i = rng_.NextInt(static_cast(values.size())); return Type::Constant(values[i], region_); } - case 3: // array - return Type::Array(Fuzz(depth / 2), region_); - case 4: - case 5: - case 6: { // function - TypeHandle type = Type::Function( - Fuzz(depth / 2), Fuzz(depth / 2), rand() % 3, region_); - for (int i = 0; i < type->AsFunction()->Arity(); ++i) { - type->AsFunction()->InitParameter(i, Fuzz(depth - 1)); - } - } default: { // union int n = rng_.NextInt(10); TypeHandle type = None; @@ -461,7 +406,7 @@ struct Tests : Rep { for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { Handle map = *mt; TypeHandle type = T.Class(map); - CHECK(*map == *type->AsClass()->Map()); + CHECK(*map == *type->AsClass()); } // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 @@ -488,10 +433,10 @@ struct Tests : Rep { for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { Handle value = *vt; TypeHandle type = T.Constant(value); - CHECK(*value == *type->AsConstant()->Value()); + CHECK(*value == *type->AsConstant()); } - // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 + // Functionality & Injectivity: Constant(V1) = Constant(v2) iff V1 = V2 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { Handle value1 = *vt1; @@ -503,102 +448,6 @@ struct Tests : Rep { } } - void Array() { - // Constructor - for (int i = 0; i < 20; ++i) { - TypeHandle type = T.Random(); - TypeHandle array = T.Array1(type); - CHECK(this->IsArray(array)); - } - - // Attributes - for (int i = 0; i < 20; ++i) { - TypeHandle type = T.Random(); - TypeHandle array = T.Array1(type); - CheckEqual(type, array->AsArray()->Element()); - } - - // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2 - for (int i = 0; i < 20; ++i) { - for (int j = 0; j < 20; ++j) { - TypeHandle type1 = T.Random(); - TypeHandle type2 = T.Random(); - TypeHandle array1 = T.Array1(type1); - TypeHandle array2 = T.Array1(type2); - CHECK(Equal(array1, array2) == Equal(type1, type2)); - } - } - } - - void Function() { - // Constructors - for (int i = 0; i < 20; ++i) { - for (int j = 0; j < 20; ++j) { - for (int k = 0; k < 20; ++k) { - TypeHandle type1 = T.Random(); - TypeHandle type2 = T.Random(); - TypeHandle type3 = T.Random(); - TypeHandle function0 = T.Function0(type1, type2); - TypeHandle function1 = T.Function1(type1, type2, type3); - TypeHandle function2 = T.Function2(type1, type2, type3); - CHECK(function0->IsFunction()); - CHECK(function1->IsFunction()); - CHECK(function2->IsFunction()); - } - } - } - - // Attributes - for (int i = 0; i < 20; ++i) { - for (int j = 0; j < 20; ++j) { - for (int k = 0; k < 20; ++k) { - TypeHandle type1 = T.Random(); - TypeHandle type2 = T.Random(); - TypeHandle type3 = T.Random(); - TypeHandle function0 = T.Function0(type1, type2); - TypeHandle function1 = T.Function1(type1, type2, type3); - TypeHandle function2 = T.Function2(type1, type2, type3); - CHECK_EQ(0, function0->AsFunction()->Arity()); - CHECK_EQ(1, function1->AsFunction()->Arity()); - CHECK_EQ(2, function2->AsFunction()->Arity()); - CheckEqual(type1, function0->AsFunction()->Result()); - CheckEqual(type1, function1->AsFunction()->Result()); - CheckEqual(type1, function2->AsFunction()->Result()); - CheckEqual(type2, function0->AsFunction()->Receiver()); - CheckEqual(type2, function1->AsFunction()->Receiver()); - CheckEqual(T.Any, function2->AsFunction()->Receiver()); - CheckEqual(type3, function1->AsFunction()->Parameter(0)); - CheckEqual(type2, function2->AsFunction()->Parameter(0)); - CheckEqual(type3, function2->AsFunction()->Parameter(1)); - } - } - } - - // Functionality & Injectivity: Function(Ts1) = Function(Ts2) iff Ts1 = Ts2 - for (int i = 0; i < 20; ++i) { - for (int j = 0; j < 20; ++j) { - for (int k = 0; k < 20; ++k) { - TypeHandle type1 = T.Random(); - TypeHandle type2 = T.Random(); - TypeHandle type3 = T.Random(); - TypeHandle function01 = T.Function0(type1, type2); - TypeHandle function02 = T.Function0(type1, type3); - TypeHandle function03 = T.Function0(type3, type2); - TypeHandle function11 = T.Function1(type1, type2, type2); - TypeHandle function12 = T.Function1(type1, type2, type3); - TypeHandle function21 = T.Function2(type1, type2, type2); - TypeHandle function22 = T.Function2(type1, type2, type3); - TypeHandle function23 = T.Function2(type1, type3, type2); - CHECK(Equal(function01, function02) == Equal(type2, type3)); - CHECK(Equal(function01, function03) == Equal(type1, type3)); - CHECK(Equal(function11, function12) == Equal(type2, type3)); - CHECK(Equal(function21, function22) == Equal(type2, type3)); - CHECK(Equal(function21, function23) == Equal(type2, type3)); - } - } - } - } - void Of() { // Constant(V)->Is(Of(V)) for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { @@ -792,7 +641,6 @@ struct Tests : Rep { // Structural types CheckSub(T.ObjectClass, T.Object); CheckSub(T.ArrayClass, T.Object); - CheckSub(T.ArrayClass, T.Array); CheckSub(T.UninitializedClass, T.Internal); CheckUnordered(T.ObjectClass, T.ArrayClass); CheckUnordered(T.UninitializedClass, T.Null); @@ -816,15 +664,6 @@ struct Tests : Rep { CheckUnordered(T.ObjectConstant1, T.ArrayClass); CheckUnordered(T.ObjectConstant2, T.ArrayClass); CheckUnordered(T.ArrayConstant, T.ObjectClass); - - CheckSub(T.FloatArray, T.Array); - CheckSub(T.FloatArray, T.Object); - CheckUnordered(T.StringArray, T.AnyArray); - - CheckSub(T.MethodFunction, T.Function); - CheckSub(T.NumberFunction1, T.Object); - CheckUnordered(T.SignedFunction1, T.NumberFunction1); - CheckUnordered(T.NumberFunction1, T.NumberFunction2); } void NowIs() { @@ -1153,19 +992,9 @@ struct Tests : Rep { CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic); CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic); CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic); - - CheckOverlap(T.FloatArray, T.Array, T.Semantic); - CheckDisjoint(T.FloatArray, T.AnyArray, T.Semantic); - CheckDisjoint(T.FloatArray, T.StringArray, T.Semantic); - - CheckOverlap(T.MethodFunction, T.Function, T.Semantic); - CheckDisjoint(T.SignedFunction1, T.NumberFunction1, T.Semantic); - CheckDisjoint(T.SignedFunction1, T.NumberFunction2, T.Semantic); - CheckDisjoint(T.NumberFunction1, T.NumberFunction2, T.Semantic); - CheckDisjoint(T.SignedFunction1, T.MethodFunction, T.Semantic); } - void Union1() { + void Union() { // Identity: Union(T, None) = T for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { TypeHandle type = *it; @@ -1234,9 +1063,7 @@ struct Tests : Rep { if (type1->Is(type2)) CheckEqual(union12, type2); } } - } - void Union2() { // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3)) for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { @@ -1295,28 +1122,6 @@ struct Tests : Rep { CheckDisjoint( T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, T.Semantic); - // Bitset-array - CHECK(this->IsBitset(T.Union(T.AnyArray, T.Array))); - CHECK(this->IsUnion(T.Union(T.FloatArray, T.Number))); - - CheckEqual(T.Union(T.AnyArray, T.Array), T.Array); - CheckSub(T.None, T.Union(T.FloatArray, T.Number)); - CheckSub(T.Union(T.FloatArray, T.Number), T.Any); - CheckUnordered(T.Union(T.AnyArray, T.String), T.Array); - CheckOverlap(T.Union(T.FloatArray, T.String), T.Object, T.Semantic); - CheckDisjoint(T.Union(T.FloatArray, T.String), T.Number, T.Semantic); - - // Bitset-function - CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Function))); - CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number))); - - CheckEqual(T.Union(T.MethodFunction, T.Function), T.Function); - CheckSub(T.None, T.Union(T.MethodFunction, T.Number)); - CheckSub(T.Union(T.MethodFunction, T.Number), T.Any); - CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Function); - CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object, T.Semantic); - CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number, T.Semantic); - // Bitset-class CheckSub( T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number)); @@ -1372,18 +1177,6 @@ struct Tests : Rep { T.Union( T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1))); - // Array-union - CheckEqual( - T.Union(T.AnyArray, T.Union(T.FloatArray, T.AnyArray)), - T.Union(T.AnyArray, T.FloatArray)); - CheckSub(T.Union(T.AnyArray, T.FloatArray), T.Array); - - // Function-union - CheckEqual( - T.Union(T.NumberFunction1, T.NumberFunction2), - T.Union(T.NumberFunction2, T.NumberFunction1)); - CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Function); - // Union-union CheckEqual( T.Union( @@ -1397,7 +1190,7 @@ struct Tests : Rep { T.Union(T.Number, T.Array)); } - void Intersect1() { + void Intersect() { // Identity: Intersect(T, Any) = T for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { TypeHandle type = *it; @@ -1467,9 +1260,7 @@ struct Tests : Rep { if (type1->Is(type2)) CheckEqual(intersect12, type1); } } - } - void Intersect2() { // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3)) for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { @@ -1517,13 +1308,9 @@ struct Tests : Rep { CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation); CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation); - // Bitset-array - CheckEqual(T.Intersect(T.FloatArray, T.Object), T.FloatArray); - CheckSub(T.Intersect(T.AnyArray, T.Function), T.Representation); - - // Bitset-function - CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction); - CheckSub(T.Intersect(T.NumberFunction1, T.Array), T.Representation); + // Class-constant + CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); + CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); // Bitset-union CheckEqual( @@ -1533,32 +1320,6 @@ struct Tests : Rep { T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), T.None); - // Class-constant - CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); - CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); - - // Array-union - CheckEqual( - T.Intersect(T.FloatArray, T.Union(T.FloatArray, T.ArrayClass)), - T.FloatArray); - CheckEqual( - T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)), - T.AnyArray); - CheckEqual( - T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.FloatArray), - T.None); - - // Function-union - CheckEqual( - T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)), - T.MethodFunction); - CheckEqual( - T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)), - T.NumberFunction1); - CheckEqual( - T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2), - T.None); - // Class-union CheckEqual( T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), @@ -1626,41 +1387,27 @@ typedef Tests ZoneTests; typedef Tests, Isolate, HeapRep> HeapTests; -TEST(BitsetType) { +TEST(Bitset) { CcTest::InitializeVM(); ZoneTests().Bitset(); HeapTests().Bitset(); } -TEST(ClassType) { +TEST(Class) { CcTest::InitializeVM(); ZoneTests().Class(); HeapTests().Class(); } -TEST(ConstantType) { +TEST(Constant) { CcTest::InitializeVM(); ZoneTests().Constant(); HeapTests().Constant(); } -TEST(ArrayType) { - CcTest::InitializeVM(); - ZoneTests().Array(); - HeapTests().Array(); -} - - -TEST(FunctionType) { - CcTest::InitializeVM(); - ZoneTests().Function(); - HeapTests().Function(); -} - - TEST(Of) { CcTest::InitializeVM(); ZoneTests().Of(); @@ -1710,31 +1457,17 @@ TEST(Maybe) { } -TEST(Union1) { - CcTest::InitializeVM(); - ZoneTests().Union1(); - HeapTests().Union1(); -} - - -TEST(Union2) { - CcTest::InitializeVM(); - ZoneTests().Union2(); - HeapTests().Union2(); -} - - -TEST(Intersect1) { +TEST(Union) { CcTest::InitializeVM(); - ZoneTests().Intersect1(); - HeapTests().Intersect1(); + ZoneTests().Union(); + HeapTests().Union(); } -TEST(Intersect2) { +TEST(Intersect) { CcTest::InitializeVM(); - ZoneTests().Intersect2(); - HeapTests().Intersect2(); + ZoneTests().Intersect(); + HeapTests().Intersect(); } -- 2.34.1