From: machenbach@chromium.org Date: Thu, 9 Jan 2014 19:52:15 +0000 (+0000) Subject: [Sheriff] Revert "Templatise type representation" and "Fix Mac warnings". X-Git-Tag: upstream/4.7.83~11211 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8ffcd2a28176981fbdda9664bbdb86de55fe43ab;p=platform%2Fupstream%2Fv8.git [Sheriff] Revert "Templatise type representation" and "Fix Mac warnings". This reverts commit r18521 and r18522 for breaking mac and win builders. BUG= TBR=rossberg@chromium.org Review URL: https://codereview.chromium.org/132493002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18524 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/ast.cc b/src/ast.cc index 6c0ef7c5a..21ea50bf1 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -1141,7 +1141,7 @@ CaseClause::CaseClause(Isolate* isolate, : Expression(isolate, pos), label_(label), statements_(statements), - compare_type_(Type::None(isolate)), + compare_type_(Type::None(), isolate), compare_id_(AstNode::GetNextId(isolate)), entry_id_(AstNode::GetNextId(isolate)) { } diff --git a/src/ast.h b/src/ast.h index 97ef4ff5b..64a56e9df 100644 --- a/src/ast.h +++ b/src/ast.h @@ -2068,7 +2068,7 @@ class CompareOperation V8_FINAL : public Expression { op_(op), left_(left), right_(right), - combined_type_(Type::None(isolate)) { + combined_type_(Type::None(), isolate) { ASSERT(Token::IsCompareOp(op)); } diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 67f9dc8fd..783384d45 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -323,7 +323,7 @@ template <> HValue* CodeStubGraphBuilder::BuildCodeStub() { info()->MarkAsSavesCallerDoubles(); HValue* number = GetParameter(NumberToStringStub::kNumber); - return BuildNumberToString(number, Type::Number(isolate())); + return BuildNumberToString(number, handle(Type::Number(), isolate())); } @@ -896,7 +896,7 @@ HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { { Push(BuildBinaryOperation( state.op(), left, right, - Type::String(isolate()), right_type, + handle(Type::String(), isolate()), right_type, result_type, state.fixed_right_arg(), allocation_mode)); } @@ -916,7 +916,7 @@ HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { { Push(BuildBinaryOperation( state.op(), left, right, - left_type, Type::String(isolate()), + left_type, handle(Type::String(), isolate()), result_type, state.fixed_right_arg(), allocation_mode)); } diff --git a/src/code-stubs.cc b/src/code-stubs.cc index f524bb6bf..d27a458fa 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -480,20 +480,21 @@ Handle CompareNilICStub::GetType( Isolate* isolate, Handle map) { if (state_.Contains(CompareNilICStub::GENERIC)) { - return Type::Any(isolate); + return handle(Type::Any(), isolate); } - Handle result = Type::None(isolate); + Handle result(Type::None(), isolate); if (state_.Contains(CompareNilICStub::UNDEFINED)) { - result = Type::Union(result, Type::Undefined(isolate), isolate); + result = handle(Type::Union(result, handle(Type::Undefined(), isolate)), + isolate); } if (state_.Contains(CompareNilICStub::NULL_TYPE)) { - result = Type::Union(result, Type::Null(isolate), isolate); + result = handle(Type::Union(result, handle(Type::Null(), isolate)), + isolate); } if (state_.Contains(CompareNilICStub::MONOMORPHIC_MAP)) { - Handle type = map.is_null() - ? Type::Detectable(isolate) : Type::Class(map, isolate); - result = Type::Union(result, type, isolate); + Type* type = map.is_null() ? Type::Detectable() : Type::Class(map); + result = handle(Type::Union(result, handle(type, isolate)), isolate); } return result; @@ -504,9 +505,9 @@ Handle CompareNilICStub::GetInputType( Isolate* isolate, Handle map) { Handle output_type = GetType(isolate, map); - Handle nil_type = nil_value_ == kNullValue - ? Type::Null(isolate) : Type::Undefined(isolate); - return Type::Union(output_type, nil_type, isolate); + Handle nil_type = handle(nil_value_ == kNullValue + ? Type::Null() : Type::Undefined(), isolate); + return handle(Type::Union(output_type, nil_type), isolate); } diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 98622186b..929133b8f 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -8772,7 +8772,7 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle* expected) { HConstant* constant = HConstant::cast(value); Maybe number = constant->CopyToTruncatedNumber(zone()); if (number.has_value) { - *expected = Type::Number(isolate()); + *expected = handle(Type::Number(), isolate()); return AddInstruction(number.value); } } @@ -8785,10 +8785,10 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle* expected) { Handle expected_type = *expected; // Separate the number type from the rest. - Handle expected_obj = Type::Intersect( - expected_type, Type::NonNumber(isolate()), isolate()); - Handle expected_number = Type::Intersect( - expected_type, Type::Number(isolate()), isolate()); + Handle expected_obj = handle(Type::Intersect( + expected_type, handle(Type::NonNumber(), isolate())), isolate()); + Handle expected_number = handle(Type::Intersect( + expected_type, handle(Type::Number(), isolate())), isolate()); // We expect to get a number. // (We need to check first, since Type::None->Is(Type::Any()) == true. @@ -8799,8 +8799,8 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle* expected) { if (expected_obj->Is(Type::Undefined())) { // This is already done by HChange. - *expected = Type::Union( - expected_number, Type::Double(isolate()), isolate()); + *expected = handle(Type::Union( + expected_number, handle(Type::Double(), isolate())), isolate()); return value; } @@ -8862,7 +8862,7 @@ HValue* HGraphBuilder::BuildBinaryOperation( Deoptimizer::SOFT); // TODO(rossberg): we should be able to get rid of non-continuous // defaults. - left_type = Type::Any(isolate()); + left_type = handle(Type::Any(), isolate()); } else { if (!maybe_string_add) left = TruncateToNumber(left, &left_type); left_rep = Representation::FromType(left_type); @@ -8871,7 +8871,7 @@ HValue* HGraphBuilder::BuildBinaryOperation( if (right_type->Is(Type::None())) { Add("Insufficient type feedback for RHS of binary operation", Deoptimizer::SOFT); - right_type = Type::Any(isolate()); + right_type = handle(Type::Any(), isolate()); } else { if (!maybe_string_add) right = TruncateToNumber(right, &right_type); right_rep = Representation::FromType(right_type); @@ -9369,7 +9369,7 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( Add("Insufficient type feedback for combined type " "of binary operation", Deoptimizer::SOFT); - combined_type = left_type = right_type = Type::Any(isolate()); + combined_type = left_type = right_type = handle(Type::Any(), isolate()); } Representation left_rep = Representation::FromType(left_type); @@ -9466,7 +9466,8 @@ void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, } else { ASSERT_EQ(Token::EQ, expr->op()); Handle type = expr->combined_type()->Is(Type::None()) - ? Type::Any(isolate_) : expr->combined_type(); + ? handle(Type::Any(), isolate_) + : expr->combined_type(); HIfContinuation continuation; BuildCompareNil(value, type, &continuation); return ast_context()->ReturnContinuation(&continuation, expr->id()); @@ -10239,7 +10240,8 @@ void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { ASSERT_EQ(1, call->arguments()->length()); CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); HValue* number = Pop(); - HValue* result = BuildNumberToString(number, Type::Number(isolate())); + HValue* result = BuildNumberToString( + number, handle(Type::Number(), isolate())); return ast_context()->ReturnValue(result); } diff --git a/src/ic.cc b/src/ic.cc index 23697a9c9..8e5f0ae6b 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -997,9 +997,10 @@ bool IC::UpdatePolymorphicIC(Handle type, Handle IC::CurrentTypeOf(Handle object, Isolate* isolate) { - return object->IsJSGlobalObject() - ? Type::Constant(Handle::cast(object), isolate) - : Type::OfCurrently(object, isolate); + Type* type = object->IsJSGlobalObject() + ? Type::Constant(Handle::cast(object)) + : Type::OfCurrently(object); + return handle(type, isolate); } @@ -1014,12 +1015,11 @@ Handle IC::TypeToMap(Type* type, Isolate* isolate) { } -Handle IC::MapToType(Handle map) { - Isolate* isolate = map->GetIsolate(); - if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(isolate); +Type* IC::MapToType(Handle map) { + if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(); // The only oddballs that can be recorded in ICs are booleans. - if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(isolate); - return Type::Class(map, isolate); + if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(); + return Type::Class(map); } @@ -1044,7 +1044,7 @@ void IC::CopyICToMegamorphicCache(Handle name) { } -bool IC::IsTransitionOfMonomorphicTarget(Handle type) { +bool IC::IsTransitionOfMonomorphicTarget(Type* type) { if (!type->IsClass()) return false; Map* receiver_map = *type->AsClass(); Map* current_map = target()->FindFirstMap(); @@ -1076,7 +1076,7 @@ void IC::PatchCache(Handle type, target()->is_keyed_call_stub() || !target().is_identical_to(code)); Code* old_handler = target()->FindFirstHandler(); - if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) { + if (old_handler == *code && IsTransitionOfMonomorphicTarget(*type)) { UpdateMonomorphicIC(type, code, name); break; } @@ -2620,9 +2620,10 @@ Handle BinaryOpIC::State::GetResultType(Isolate* isolate) const { if (HasSideEffects()) { result_kind = NONE; } else if (result_kind == GENERIC && op_ == Token::ADD) { - return Type::Union(Type::Number(isolate), Type::String(isolate), isolate); + return handle(Type::Union(handle(Type::Number(), isolate), + handle(Type::String(), isolate)), isolate); } else if (result_kind == NUMBER && op_ == Token::SHR) { - return Type::Unsigned32(isolate); + return handle(Type::Unsigned32(), isolate); } ASSERT_NE(GENERIC, result_kind); return KindToType(result_kind, isolate); @@ -2757,16 +2758,16 @@ const char* BinaryOpIC::State::KindToString(Kind kind) { // static Handle BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) { + Type* type = NULL; switch (kind) { - case NONE: return Type::None(isolate); - case SMI: return Type::Smi(isolate); - case INT32: return Type::Signed32(isolate); - case NUMBER: return Type::Number(isolate); - case STRING: return Type::String(isolate); - case GENERIC: return Type::Any(isolate); + case NONE: type = Type::None(); break; + case SMI: type = Type::Smi(); break; + case INT32: type = Type::Signed32(); break; + case NUMBER: type = Type::Number(); break; + case STRING: type = Type::String(); break; + case GENERIC: type = Type::Any(); break; } - UNREACHABLE(); - return Handle(); + return handle(type, isolate); } @@ -2901,18 +2902,25 @@ Handle CompareIC::StateToType( CompareIC::State state, Handle map) { switch (state) { - case CompareIC::UNINITIALIZED: return Type::None(isolate); - case CompareIC::SMI: return Type::Smi(isolate); - case CompareIC::NUMBER: return Type::Number(isolate); - case CompareIC::STRING: return Type::String(isolate); + case CompareIC::UNINITIALIZED: + return handle(Type::None(), isolate); + case CompareIC::SMI: + return handle(Type::Smi(), isolate); + case CompareIC::NUMBER: + return handle(Type::Number(), isolate); + case CompareIC::STRING: + return handle(Type::String(), isolate); case CompareIC::INTERNALIZED_STRING: - return Type::InternalizedString(isolate); - case CompareIC::UNIQUE_NAME: return Type::UniqueName(isolate); - case CompareIC::OBJECT: return Type::Receiver(isolate); + return handle(Type::InternalizedString(), isolate); + case CompareIC::UNIQUE_NAME: + return handle(Type::UniqueName(), isolate); + case CompareIC::OBJECT: + return handle(Type::Receiver(), isolate); case CompareIC::KNOWN_OBJECT: - return map.is_null() - ? Type::Receiver(isolate) : Type::Class(map, isolate); - case CompareIC::GENERIC: return Type::Any(isolate); + return handle( + map.is_null() ? Type::Receiver() : Type::Class(map), isolate); + case CompareIC::GENERIC: + return handle(Type::Any(), isolate); } UNREACHABLE(); return Handle(); diff --git a/src/ic.h b/src/ic.h index 9a42b75fc..688c22764 100644 --- a/src/ic.h +++ b/src/ic.h @@ -171,7 +171,7 @@ class IC { // well as smis. // - The oddball map is only used for booleans. static Handle TypeToMap(Type* type, Isolate* isolate); - static Handle MapToType(Handle type); + static Type* MapToType(Handle type); static Handle CurrentTypeOf(Handle object, Isolate* isolate); ContextualMode contextual_mode() const { @@ -243,7 +243,7 @@ class IC { virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code); void CopyICToMegamorphicCache(Handle name); - bool IsTransitionOfMonomorphicTarget(Handle type); + bool IsTransitionOfMonomorphicTarget(Type* type); void PatchCache(Handle type, Handle name, Handle code); diff --git a/src/list.h b/src/list.h index e498ae162..6ba55b64a 100644 --- a/src/list.h +++ b/src/list.h @@ -204,9 +204,7 @@ size_t GetMemoryUsedByList(const List& list) { class Map; -template class TypeImpl; -struct HeapTypeConfig; -typedef TypeImpl Type; +class Type; class Code; template class Handle; typedef List MapList; diff --git a/src/objects.cc b/src/objects.cc index 46be0bde3..dcbe21198 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -10543,12 +10543,13 @@ void Code::FindAllTypes(TypeHandleList* types) { ASSERT(is_inline_cache_stub()); DisallowHeapAllocation no_allocation; int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); + Isolate* isolate = GetIsolate(); for (RelocIterator it(this, mask); !it.done(); it.next()) { RelocInfo* info = it.rinfo(); Object* object = info->target_object(); if (object->IsMap()) { Handle map(Map::cast(object)); - types->Add(IC::MapToType(map)); + types->Add(handle(IC::MapToType(map), isolate)); } } } @@ -16604,8 +16605,9 @@ Handle PropertyCell::UpdatedType(Handle cell, Handle old_type(cell->type(), isolate); // TODO(2803): Do not track ConsString as constant because they cannot be // embedded into code. - Handle new_type = value->IsConsString() || value->IsTheHole() - ? Type::Any(isolate) : Type::Constant(value, isolate); + Handle new_type(value->IsConsString() || value->IsTheHole() + ? Type::Any() + : Type::Constant(value, isolate), isolate); if (new_type->Is(old_type)) { return old_type; @@ -16618,7 +16620,7 @@ Handle PropertyCell::UpdatedType(Handle cell, return new_type; } - return Type::Any(isolate); + return handle(Type::Any(), isolate); } diff --git a/src/objects.h b/src/objects.h index ebe2d861c..f98c025dd 100644 --- a/src/objects.h +++ b/src/objects.h @@ -881,10 +881,7 @@ class FixedArrayBase; class GlobalObject; class ObjectVisitor; class StringStream; -// We cannot just say "class Type;" if it is created from a template... =8-? -template class TypeImpl; -struct HeapTypeConfig; -typedef TypeImpl Type; +class Type; // A template-ized version of the IsXXX functions. diff --git a/src/property-details.h b/src/property-details.h index 5686ed074..71ac8bb6f 100644 --- a/src/property-details.h +++ b/src/property-details.h @@ -58,9 +58,7 @@ namespace v8 { namespace internal { class Smi; -template class TypeImpl; -struct HeapTypeConfig; -typedef TypeImpl Type; +class Type; class TypeInfo; // Type of properties. @@ -107,7 +105,9 @@ class Representation { static Representation Integer8() { return Representation(kInteger8); } static Representation UInteger8() { return Representation(kUInteger8); } static Representation Integer16() { return Representation(kInteger16); } - static Representation UInteger16() { return Representation(kUInteger16); } + static Representation UInteger16() { + return Representation(kUInteger16); + } static Representation Smi() { return Representation(kSmi); } static Representation Integer32() { return Representation(kInteger32); } static Representation Double() { return Representation(kDouble); } diff --git a/src/stub-cache.cc b/src/stub-cache.cc index fc0538ab5..e92d11959 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -651,7 +651,7 @@ Handle StubCache::ComputeLoadElementPolymorphic( TypeHandleList types(receiver_maps->length()); for (int i = 0; i < receiver_maps->length(); i++) { - types.Add(Type::Class(receiver_maps->at(i), isolate())); + types.Add(handle(Type::Class(receiver_maps->at(i)), isolate())); } CodeHandleList handlers(receiver_maps->length()); KeyedLoadStubCompiler compiler(isolate_); diff --git a/src/type-info.cc b/src/type-info.cc index 15e454b21..7f1d3b5ea 100644 --- a/src/type-info.cc +++ b/src/type-info.cc @@ -252,7 +252,7 @@ void TypeFeedbackOracle::CompareType(TypeFeedbackId id, Handle info = GetInfo(id); if (!info->IsCode()) { // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof. - *left_type = *right_type = *combined_type = Type::None(isolate_); + *left_type = *right_type = *combined_type = handle(Type::None(), isolate_); return; } Handle code = Handle::cast(info); @@ -291,7 +291,7 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, // operations covered by the BinaryOpIC we should always have them. ASSERT(op < BinaryOpIC::State::FIRST_TOKEN || op > BinaryOpIC::State::LAST_TOKEN); - *left = *right = *result = Type::None(isolate_); + *left = *right = *result = handle(Type::None(), isolate_); *fixed_right_arg = Maybe(); *allocation_site = Handle::null(); return; @@ -317,7 +317,7 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, Handle TypeFeedbackOracle::CountType(TypeFeedbackId id) { Handle object = GetInfo(id); - if (!object->IsCode()) return Type::None(isolate_); + if (!object->IsCode()) return handle(Type::None(), isolate_); Handle code = Handle::cast(object); ASSERT_EQ(Code::BINARY_OP_IC, code->kind()); BinaryOpIC::State state(code->extended_extra_ic_state()); diff --git a/src/types.cc b/src/types.cc index 2aa60817e..485ba8851 100644 --- a/src/types.cc +++ b/src/types.cc @@ -31,15 +31,14 @@ namespace v8 { namespace internal { -template -int TypeImpl::NumClasses() { - if (this->IsClass()) { +int Type::NumClasses() { + if (is_class()) { return 1; - } else if (this->IsUnion()) { - UnionedHandle unioned = this->AsUnion(); + } else if (is_union()) { + Handle unioned = as_union(); int result = 0; for (int i = 0; i < unioned->length(); ++i) { - if (Config::union_get(unioned, i)->IsClass()) ++result; + if (union_get(unioned, i)->is_class()) ++result; } return result; } else { @@ -48,15 +47,14 @@ int TypeImpl::NumClasses() { } -template -int TypeImpl::NumConstants() { - if (this->IsConstant()) { +int Type::NumConstants() { + if (is_constant()) { return 1; - } else if (this->IsUnion()) { - UnionedHandle unioned = this->AsUnion(); + } else if (is_union()) { + Handle unioned = as_union(); int result = 0; for (int i = 0; i < unioned->length(); ++i) { - if (Config::union_get(unioned, i)->IsConstant()) ++result; + if (union_get(unioned, i)->is_constant()) ++result; } return result; } else { @@ -65,61 +63,41 @@ int TypeImpl::NumConstants() { } -template template -typename TypeImpl::TypeHandle -TypeImpl::Iterator::get_type() { +template +Handle Type::Iterator::get_type() { ASSERT(!Done()); - return type_->IsUnion() ? Config::union_get(type_->AsUnion(), index_) : type_; + return type_->is_union() ? union_get(type_->as_union(), index_) : type_; } +template<> +Handle Type::Iterator::Current() { + return get_type()->as_class(); +} -// C++ cannot specialise nested templates, so we have to go through this -// contortion with an auxiliary template to simulate it. -template -struct TypeImplIteratorAux { - static bool matches(typename TypeImpl::TypeHandle type); - static i::Handle current(typename TypeImpl::TypeHandle type); -}; - -template -struct TypeImplIteratorAux { - static bool matches(typename TypeImpl::TypeHandle type) { - return type->IsClass(); - } - static i::Handle current(typename TypeImpl::TypeHandle type) { - return type->AsClass(); - } -}; +template<> +Handle Type::Iterator::Current() { + return get_type()->as_constant(); +} -template -struct TypeImplIteratorAux { - static bool matches(typename TypeImpl::TypeHandle type) { - return type->IsConstant(); - } - static i::Handle current( - typename TypeImpl::TypeHandle type) { - return type->AsConstant(); - } -}; -template template -bool TypeImpl::Iterator::matches(TypeHandle type) { - return TypeImplIteratorAux::matches(type); +template<> +bool Type::Iterator::matches(Handle type) { + return type->is_class(); } -template template -i::Handle TypeImpl::Iterator::Current() { - return TypeImplIteratorAux::current(get_type()); +template<> +bool Type::Iterator::matches(Handle type) { + return type->is_constant(); } -template template -void TypeImpl::Iterator::Advance() { +template +void Type::Iterator::Advance() { ++index_; - if (type_->IsUnion()) { - UnionedHandle unioned = type_->AsUnion(); + if (type_->is_union()) { + Handle unioned = type_->as_union(); for (; index_ < unioned->length(); ++index_) { - if (matches(Config::union_get(unioned, index_))) return; + if (matches(union_get(unioned, index_))) return; } } else if (index_ == 0 && matches(type_)) { return; @@ -127,29 +105,30 @@ void TypeImpl::Iterator::Advance() { index_ = -1; } +template class Type::Iterator; +template class Type::Iterator; + // Get the smallest bitset subsuming this type. -template -int TypeImpl::LubBitset() { - if (this->IsBitset()) { - return this->AsBitset(); - } else if (this->IsUnion()) { - UnionedHandle unioned = this->AsUnion(); +int Type::LubBitset() { + if (this->is_bitset()) { + return this->as_bitset(); + } else if (this->is_union()) { + Handle unioned = this->as_union(); int bitset = kNone; for (int i = 0; i < unioned->length(); ++i) { - bitset |= Config::union_get(unioned, i)->LubBitset(); + bitset |= union_get(unioned, i)->LubBitset(); } return bitset; - } else if (this->IsClass()) { - return LubBitset(*this->AsClass()); + } else if (this->is_class()) { + return LubBitset(*this->as_class()); } else { - return LubBitset(*this->AsConstant()); + return LubBitset(*this->as_constant()); } } -template -int TypeImpl::LubBitset(i::Object* value) { +int Type::LubBitset(i::Object* value) { if (value->IsSmi()) return kSmi; i::Map* map = i::HeapObject::cast(value)->map(); if (map->instance_type() == HEAP_NUMBER_TYPE) { @@ -166,12 +145,11 @@ int TypeImpl::LubBitset(i::Object* value) { if (value->IsTheHole()) return kAny; // TODO(rossberg): kNone? UNREACHABLE(); } - return LubBitset(map); + return Type::LubBitset(map); } -template -int TypeImpl::LubBitset(i::Map* map) { +int Type::LubBitset(i::Map* map) { switch (map->instance_type()) { case STRING_TYPE: case ASCII_STRING_TYPE: @@ -253,13 +231,12 @@ int TypeImpl::LubBitset(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()) { +int Type::GlbBitset() { + if (this->is_bitset()) { + return this->as_bitset(); + } else if (this->is_union()) { // All but the first are non-bitsets and thus would yield kNone anyway. - return Config::union_get(this->AsUnion(), 0)->GlbBitset(); + return union_get(this->as_union(), 0)->GlbBitset(); } else { return kNone; } @@ -267,40 +244,37 @@ int TypeImpl::GlbBitset() { // Most precise _current_ type of a value (usually its class). -template -typename TypeImpl::TypeHandle TypeImpl::OfCurrently( - i::Handle value, Region* region) { - if (value->IsSmi()) return Smi(region); +Type* Type::OfCurrently(Handle value) { + if (value->IsSmi()) return Smi(); i::Map* map = i::HeapObject::cast(*value)->map(); if (map->instance_type() == HEAP_NUMBER_TYPE || map->instance_type() == ODDBALL_TYPE) { - return Of(value, region); + return Type::Of(value); } - return Class(i::handle(map), region); + return Class(i::handle(map)); } // Check this <= that. -template -bool TypeImpl::SlowIs(TypeImpl* that) { +bool Type::SlowIs(Type* that) { // Fast path for bitsets. - if (this->IsNone()) return true; - if (that->IsBitset()) { - return (this->LubBitset() | that->AsBitset()) == that->AsBitset(); + if (this->is_none()) return true; + if (that->is_bitset()) { + return (this->LubBitset() | that->as_bitset()) == that->as_bitset(); } - if (that->IsClass()) { - return this->IsClass() && *this->AsClass() == *that->AsClass(); + if (that->is_class()) { + return this->is_class() && *this->as_class() == *that->as_class(); } - if (that->IsConstant()) { - return this->IsConstant() && *this->AsConstant() == *that->AsConstant(); + if (that->is_constant()) { + return this->is_constant() && *this->as_constant() == *that->as_constant(); } // (T1 \/ ... \/ Tn) <= T <=> (T1 <= T) /\ ... /\ (Tn <= T) - if (this->IsUnion()) { - UnionedHandle unioned = this->AsUnion(); + if (this->is_union()) { + Handle unioned = this->as_union(); for (int i = 0; i < unioned->length(); ++i) { - TypeHandle this_i = Config::union_get(unioned, i); + Handle this_i = union_get(unioned, i); if (!this_i->Is(that)) return false; } return true; @@ -308,13 +282,13 @@ bool TypeImpl::SlowIs(TypeImpl* that) { // T <= (T1 \/ ... \/ Tn) <=> (T <= T1) \/ ... \/ (T <= Tn) // (iff T is not a union) - ASSERT(!this->IsUnion()); - if (that->IsUnion()) { - UnionedHandle unioned = that->AsUnion(); + ASSERT(!this->is_union()); + if (that->is_union()) { + Handle unioned = that->as_union(); for (int i = 0; i < unioned->length(); ++i) { - TypeHandle that_i = Config::union_get(unioned, i); + Handle that_i = union_get(unioned, i); if (this->Is(that_i)) return true; - if (this->IsBitset()) break; // Fast fail, only first field is a bitset. + if (this->is_bitset()) break; // Fast fail, no other field is a bitset. } return false; } @@ -323,63 +297,60 @@ bool TypeImpl::SlowIs(TypeImpl* that) { } -template -bool TypeImpl::IsCurrently(TypeImpl* that) { +bool Type::IsCurrently(Type* that) { return this->Is(that) || - (this->IsConstant() && that->IsClass() && - this->AsConstant()->IsHeapObject() && - i::HeapObject::cast(*this->AsConstant())->map() == *that->AsClass()); + (this->is_constant() && that->is_class() && + this->as_constant()->IsHeapObject() && + i::HeapObject::cast(*this->as_constant())->map() == *that->as_class()); } // Check this overlaps that. -template -bool TypeImpl::Maybe(TypeImpl* that) { +bool Type::Maybe(Type* that) { // Fast path for bitsets. - if (this->IsBitset()) { - return (this->AsBitset() & that->LubBitset()) != 0; + if (this->is_bitset()) { + return (this->as_bitset() & that->LubBitset()) != 0; } - if (that->IsBitset()) { - return (this->LubBitset() & that->AsBitset()) != 0; + if (that->is_bitset()) { + return (this->LubBitset() & that->as_bitset()) != 0; } // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T) - if (this->IsUnion()) { - UnionedHandle unioned = this->AsUnion(); + if (this->is_union()) { + Handle unioned = this->as_union(); for (int i = 0; i < unioned->length(); ++i) { - TypeHandle this_i = Config::union_get(unioned, i); + Handle this_i = union_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()) { - UnionedHandle unioned = that->AsUnion(); + if (that->is_union()) { + Handle unioned = that->as_union(); for (int i = 0; i < unioned->length(); ++i) { - TypeHandle that_i = Config::union_get(unioned, i); + Handle that_i = union_get(unioned, i); if (this->Maybe(that_i)) return true; } return false; } - ASSERT(!this->IsUnion() && !that->IsUnion()); - if (this->IsClass()) { - return that->IsClass() && *this->AsClass() == *that->AsClass(); + ASSERT(!that->is_union()); + if (this->is_class()) { + return that->is_class() && *this->as_class() == *that->as_class(); } - if (this->IsConstant()) { - return that->IsConstant() && *this->AsConstant() == *that->AsConstant(); + if (this->is_constant()) { + return that->is_constant() && *this->as_constant() == *that->as_constant(); } return false; } -template -bool TypeImpl::InUnion(UnionedHandle unioned, int current_size) { - ASSERT(!this->IsUnion()); +bool Type::InUnion(Handle unioned, int current_size) { + ASSERT(!this->is_union()); for (int i = 0; i < current_size; ++i) { - TypeHandle type = Config::union_get(unioned, i); + Handle type = union_get(unioned, i); if (this->Is(type)) return true; } return false; @@ -388,20 +359,17 @@ bool TypeImpl::InUnion(UnionedHandle unioned, int current_size) { // Get non-bitsets from this which are not subsumed by union, store at unioned, // starting at index. Returns updated index. -template -int TypeImpl::ExtendUnion(UnionedHandle result, int current_size) { +int Type::ExtendUnion(Handle result, int current_size) { int old_size = current_size; - if (this->IsClass() || this->IsConstant()) { + if (this->is_class() || this->is_constant()) { if (!this->InUnion(result, old_size)) result->set(current_size++, this); - } else if (this->IsUnion()) { - UnionedHandle unioned = this->AsUnion(); + } else if (this->is_union()) { + Handle unioned = this->as_union(); for (int i = 0; i < unioned->length(); ++i) { - TypeHandle type = Config::union_get(unioned, i); - ASSERT(i == 0 || - !(type->IsBitset() || type->Is(Config::union_get(unioned, 0)))); - if (!type->IsBitset() && !type->InUnion(result, old_size)) { - result->set(current_size++, *type); - } + Handle type = union_get(unioned, i); + ASSERT(i == 0 || !(type->is_bitset() || type->Is(union_get(unioned, 0)))); + if (type->is_bitset()) continue; + if (!type->InUnion(result, old_size)) result->set(current_size++, *type); } } return current_size; @@ -410,75 +378,74 @@ int TypeImpl::ExtendUnion(UnionedHandle result, int current_size) { // Union 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::Union( - TypeHandle type1, TypeHandle type2, Region* region) { +Type* Type::Union(Handle type1, Handle type2) { // Fast case: bit sets. - if (type1->IsBitset() && type2->IsBitset()) { - return Config::from_bitset(type1->AsBitset() | type2->AsBitset(), region); + if (type1->is_bitset() && type2->is_bitset()) { + return from_bitset(type1->as_bitset() | type2->as_bitset()); } // Fast case: top or bottom types. - if (type1->IsAny()) return type1; - if (type2->IsAny()) return type2; - if (type1->IsNone()) return type2; - if (type2->IsNone()) return type1; + if (type1->SameValue(Type::Any())) return *type1; + if (type2->SameValue(Type::Any())) return *type2; + if (type1->SameValue(Type::None())) return *type2; + if (type2->SameValue(Type::None())) return *type1; // Semi-fast case: Unioned objects are neither involved nor produced. - if (!(type1->IsUnion() || type2->IsUnion())) { - if (type1->Is(type2)) return type2; - if (type2->Is(type1)) return type1; + if (!(type1->is_union() || type2->is_union())) { + if (type1->Is(type2)) return *type2; + if (type2->Is(type1)) return *type1; } // Slow case: may need to produce a Unioned object. - int size = type1->IsBitset() || type2->IsBitset() ? 1 : 0; - if (!type1->IsBitset()) { - size += (type1->IsUnion() ? type1->AsUnion()->length() : 1); + Isolate* isolate = NULL; + int size = type1->is_bitset() || type2->is_bitset() ? 1 : 0; + if (!type1->is_bitset()) { + isolate = i::HeapObject::cast(*type1)->GetIsolate(); + size += (type1->is_union() ? type1->as_union()->length() : 1); } - if (!type2->IsBitset()) { - size += (type2->IsUnion() ? type2->AsUnion()->length() : 1); + if (!type2->is_bitset()) { + isolate = i::HeapObject::cast(*type2)->GetIsolate(); + size += (type2->is_union() ? type2->as_union()->length() : 1); } + ASSERT(isolate != NULL); ASSERT(size >= 2); - UnionedHandle unioned = Config::union_create(size, region); + Handle unioned = isolate->factory()->NewFixedArray(size); size = 0; int bitset = type1->GlbBitset() | type2->GlbBitset(); - if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset)); + if (bitset != kNone) unioned->set(size++, from_bitset(bitset)); size = type1->ExtendUnion(unioned, size); size = type2->ExtendUnion(unioned, size); if (size == 1) { - return Config::union_get(unioned, 0); + return *union_get(unioned, 0); } else if (size == unioned->length()) { - return Config::from_union(unioned); + return from_handle(unioned); } // There was an overlap. Copy to smaller union. - UnionedHandle result = Config::union_create(size, region); + Handle result = isolate->factory()->NewFixedArray(size); for (int i = 0; i < size; ++i) result->set(i, unioned->get(i)); - return Config::from_union(result); + return from_handle(result); } // Get non-bitsets from this which are also in that, store at unioned, // starting at index. Returns updated index. -template -int TypeImpl::ExtendIntersection( - UnionedHandle result, TypeHandle that, int current_size) { +int Type::ExtendIntersection( + Handle result, Handle that, int current_size) { int old_size = current_size; - if (this->IsClass() || this->IsConstant()) { + if (this->is_class() || this->is_constant()) { if (this->Is(that) && !this->InUnion(result, old_size)) result->set(current_size++, this); - } else if (this->IsUnion()) { - UnionedHandle unioned = this->AsUnion(); + } else if (this->is_union()) { + Handle unioned = this->as_union(); for (int i = 0; i < unioned->length(); ++i) { - TypeHandle type = Config::union_get(unioned, i); - ASSERT(i == 0 || - !(type->IsBitset() || type->Is(Config::union_get(unioned, 0)))); - if (!type->IsBitset() && type->Is(that) && - !type->InUnion(result, old_size)) { + Handle type = union_get(unioned, i); + ASSERT(i == 0 || !(type->is_bitset() || type->Is(union_get(unioned, 0)))); + if (type->is_bitset()) continue; + if (type->Is(that) && !type->InUnion(result, old_size)) result->set(current_size++, *type); - } } } return current_size; @@ -487,60 +454,68 @@ int TypeImpl::ExtendIntersection( // 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) { +Type* Type::Intersect(Handle type1, Handle type2) { // Fast case: bit sets. - if (type1->IsBitset() && type2->IsBitset()) { - return Config::from_bitset(type1->AsBitset() & type2->AsBitset(), region); + if (type1->is_bitset() && type2->is_bitset()) { + return from_bitset(type1->as_bitset() & type2->as_bitset()); } // Fast case: top or bottom types. - if (type1->IsNone()) return type1; - if (type2->IsNone()) return type2; - if (type1->IsAny()) return type2; - if (type2->IsAny()) return type1; + if (type1->SameValue(Type::None())) return *type1; + if (type2->SameValue(Type::None())) return *type2; + if (type1->SameValue(Type::Any())) return *type2; + if (type2->SameValue(Type::Any())) return *type1; // Semi-fast case: Unioned objects are neither involved nor produced. - if (!(type1->IsUnion() || type2->IsUnion())) { - if (type1->Is(type2)) return type1; - if (type2->Is(type1)) return type2; + if (!(type1->is_union() || type2->is_union())) { + if (type1->Is(type2)) return *type1; + if (type2->Is(type1)) return *type2; } // Slow case: may need to produce a Unioned object. + Isolate* isolate = NULL; int size = 0; - if (!type1->IsBitset()) { - size = (type1->IsUnion() ? type1->AsUnion()->length() : 2); + if (!type1->is_bitset()) { + isolate = i::HeapObject::cast(*type1)->GetIsolate(); + size = (type1->is_union() ? type1->as_union()->length() : 2); } - if (!type2->IsBitset()) { - int size2 = (type2->IsUnion() ? type2->AsUnion()->length() : 2); + if (!type2->is_bitset()) { + isolate = i::HeapObject::cast(*type2)->GetIsolate(); + int size2 = (type2->is_union() ? type2->as_union()->length() : 2); size = (size == 0 ? size2 : Min(size, size2)); } + ASSERT(isolate != NULL); ASSERT(size >= 2); - UnionedHandle unioned = Config::union_create(size, region); + Handle unioned = isolate->factory()->NewFixedArray(size); size = 0; int bitset = type1->GlbBitset() & type2->GlbBitset(); - if (bitset != kNone) unioned->set(size++, Config::from_bitset(bitset)); + if (bitset != kNone) unioned->set(size++, from_bitset(bitset)); size = type1->ExtendIntersection(unioned, type2, size); size = type2->ExtendIntersection(unioned, type1, size); if (size == 0) { - return None(region); + return None(); } else if (size == 1) { - return Config::union_get(unioned, 0); + return *union_get(unioned, 0); } else if (size == unioned->length()) { - return Config::from_union(unioned); + return from_handle(unioned); } // There were dropped cases. Copy to smaller union. - UnionedHandle result = Config::union_create(size, region); + Handle result = isolate->factory()->NewFixedArray(size); for (int i = 0; i < size; ++i) result->set(i, unioned->get(i)); - return Config::from_union(result); + return from_handle(result); +} + + +Type* Type::Optional(Handle type) { + return type->is_bitset() + ? from_bitset(type->as_bitset() | kUndefined) + : Union(type, Undefined()->handle_via_isolate_of(*type)); } -// TODO(rossberg): this does not belong here. Representation Representation::FromType(Handle type) { if (type->Is(Type::None())) return Representation::None(); if (type->Is(Type::Smi())) return Representation::Smi(); @@ -551,16 +526,14 @@ Representation Representation::FromType(Handle type) { #ifdef OBJECT_PRINT -template -void TypeImpl::TypePrint() { +void Type::TypePrint() { TypePrint(stdout); PrintF(stdout, "\n"); Flush(stdout); } -template -const char* TypeImpl::bitset_name(int bitset) { +const char* Type::bitset_name(int bitset) { switch (bitset) { #define PRINT_COMPOSED_TYPE(type, value) case k##type: return #type; BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE) @@ -571,10 +544,9 @@ const char* TypeImpl::bitset_name(int bitset) { } -template -void TypeImpl::TypePrint(FILE* out) { - if (this->IsBitset()) { - int bitset = this->AsBitset(); +void Type::TypePrint(FILE* out) { + if (is_bitset()) { + int bitset = as_bitset(); const char* name = bitset_name(bitset); if (name != NULL) { PrintF(out, "%s", name); @@ -590,19 +562,19 @@ void TypeImpl::TypePrint(FILE* out) { } PrintF(out, ")"); } - } else if (this->IsConstant()) { - PrintF(out, "Constant(%p : ", static_cast(*this->AsConstant())); - Config::from_bitset(this->LubBitset())->TypePrint(out); + } else if (is_constant()) { + PrintF(out, "Constant(%p : ", static_cast(*as_constant())); + from_bitset(LubBitset())->TypePrint(out); PrintF(")"); - } else if (this->IsClass()) { - PrintF(out, "Class(%p < ", static_cast(*this->AsClass())); - Config::from_bitset(this->LubBitset())->TypePrint(out); + } else if (is_class()) { + PrintF(out, "Class(%p < ", static_cast(*as_class())); + from_bitset(LubBitset())->TypePrint(out); PrintF(")"); - } else if (this->IsUnion()) { + } else if (is_union()) { PrintF(out, "("); - UnionedHandle unioned = this->AsUnion(); + Handle unioned = as_union(); for (int i = 0; i < unioned->length(); ++i) { - TypeHandle type_i = Config::union_get(unioned, i); + Handle type_i = union_get(unioned, i); if (i > 0) PrintF(out, " | "); type_i->TypePrint(out); } @@ -612,9 +584,4 @@ void TypeImpl::TypePrint(FILE* out) { #endif -template class TypeImpl; -template class TypeImpl::Iterator; -template class TypeImpl::Iterator; - - } } // namespace v8::internal diff --git a/src/types.h b/src/types.h index 0e659a0cb..1dc79dd6b 100644 --- a/src/types.h +++ b/src/types.h @@ -131,72 +131,44 @@ namespace internal { V(Detectable, kAllocated - kUndetectable) -// struct Config { -// typedef Base; -// typedef Unioned; -// typedef Region; -// template struct Handle { typedef type; } // No template typedefs... -// static Handle::type handle(Type* type); // !is_bitset(type) -// static bool is_bitset(Type* type); -// static bool is_class(Type* type); -// static bool is_constant(Type* type); -// static bool is_union(Type* type); -// static int as_bitset(Type* type); -// static i::Handle as_class(Type* type); -// static i::Handle as_constant(Type* type); -// static Handle::type as_union(Type* type); -// static Type* from_bitset(int bitset); -// static Handle::type from_bitset(int bitset, Region* region); -// static Handle::type from_class(i::Handle map, Region* region) -// static Handle::type from_constant( -// i::Handle value, Region* region); -// static Handle::type from_union(Handle::T unioned); -// static Handle::type union_create(int size, Region* region); -// static Handle::type union_get(Handle::T unioned, int i); -// } -template -class TypeImpl : public Config::Base { +class Type : public Object { public: - typedef typename Config::template Handle::type TypeHandle; - typedef typename Config::Region 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); \ - } + #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ + static Type* type() { return from_bitset(k##type); } BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) #undef DEFINE_TYPE_CONSTRUCTOR - static TypeHandle Class(i::Handle map, Region* region) { - return Config::from_class(map, region); + static Type* Class(Handle map) { return from_handle(map); } + static Type* Constant(Handle value) { + return Constant(value, value->GetIsolate()); } - static TypeHandle Constant(i::Handle value, Region* region) { - return Config::from_constant(value, region); + static Type* Constant(Handle value, Isolate* isolate) { + return from_handle(isolate->factory()->NewBox(value)); } - static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg); - static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg); + static Type* Union(Handle type1, Handle type2); + static Type* Intersect(Handle type1, Handle type2); + static Type* Optional(Handle type); // type \/ Undefined - static TypeHandle Of(i::Handle value, Region* region) { - return Config::from_bitset(LubBitset(*value), region); + static Type* Of(Handle value) { + return from_bitset(LubBitset(*value)); } - bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); } - bool Is(TypeHandle that) { return this->Is(*that); } - bool Maybe(TypeImpl* that); - bool Maybe(TypeHandle that) { return this->Maybe(*that); } + bool Is(Type* that) { return this == that || SlowIs(that); } + bool Is(Handle that) { return this->Is(*that); } + bool Maybe(Type* that); + bool Maybe(Handle that) { return this->Maybe(*that); } // State-dependent versions of Of and Is that consider subtyping between // a constant and its map class. - static TypeHandle OfCurrently(i::Handle value, Region* region); - bool IsCurrently(TypeImpl* that); - bool IsCurrently(TypeHandle that) { return this->IsCurrently(*that); } + static Type* OfCurrently(Handle value); + bool IsCurrently(Type* that); + bool IsCurrently(Handle that) { return this->IsCurrently(*that); } - bool IsClass() { return Config::is_class(this); } - bool IsConstant() { return Config::is_constant(this); } - i::Handle AsClass() { return Config::as_class(this); } - i::Handle AsConstant() { return Config::as_constant(this); } + bool IsClass() { return is_class(); } + bool IsConstant() { return is_constant(); } + Handle AsClass() { return as_class(); } + Handle AsConstant() { return as_constant(); } int NumClasses(); int NumConstants(); @@ -205,36 +177,37 @@ class TypeImpl : public Config::Base { class Iterator { public: bool Done() const { return index_ < 0; } - i::Handle Current(); + Handle Current(); void Advance(); private: - template friend class TypeImpl; + friend class Type; Iterator() : index_(-1) {} - explicit Iterator(TypeHandle type) : type_(type), index_(-1) { + explicit Iterator(Handle type) : type_(type), index_(-1) { Advance(); } - inline bool matches(TypeHandle type); - inline TypeHandle get_type(); + inline bool matches(Handle type); + inline Handle get_type(); - TypeHandle type_; + Handle type_; int index_; }; Iterator Classes() { - if (this->IsBitset()) return Iterator(); - return Iterator(Config::handle(this)); + if (this->is_bitset()) return Iterator(); + return Iterator(this->handle()); } Iterator Constants() { - if (this->IsBitset()) return Iterator(); - return Iterator(Config::handle(this)); + if (this->is_bitset()) return Iterator(); + return Iterator(this->handle()); } - static TypeImpl* cast(i::Object* object) { - TypeImpl* t = static_cast(object); - ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion()); + static Type* cast(i::Object* object) { + Type* t = static_cast(object); + ASSERT(t->is_bitset() || t->is_class() || + t->is_constant() || t->is_union()); return t; } @@ -244,14 +217,11 @@ class TypeImpl : public Config::Base { #endif private: - template friend class Iterator; - // A union is a fixed array containing types. 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::Unioned Unioned; - typedef typename Config::template Handle::type UnionedHandle; + typedef FixedArray Unioned; enum { #define DECLARE_TYPE(type, value) k##type = (value), @@ -260,14 +230,40 @@ class TypeImpl : public Config::Base { kUnusedEOL = 0 }; - bool IsNone() { return this == None(); } - bool IsAny() { return this == Any(); } - bool IsBitset() { return Config::is_bitset(this); } - bool IsUnion() { return Config::is_union(this); } - int AsBitset() { return Config::as_bitset(this); } - UnionedHandle AsUnion() { return Config::as_union(this); } + bool is_none() { return this == None(); } + bool is_bitset() { return this->IsSmi(); } + bool is_class() { return this->IsMap(); } + bool is_constant() { return this->IsBox(); } + bool is_union() { return this->IsFixedArray(); } - bool SlowIs(TypeImpl* that); + bool SlowIs(Type* that); + + int as_bitset() { return Smi::cast(this)->value(); } + Handle as_class() { return Handle::cast(handle()); } + Handle as_constant() { + Handle box = Handle::cast(handle()); + return i::handle(box->value(), box->GetIsolate()); + } + Handle as_union() { return Handle::cast(handle()); } + + Handle handle() { return handle_via_isolate_of(this); } + Handle handle_via_isolate_of(Type* type) { + ASSERT(type->IsHeapObject()); + return i::handle(this, i::HeapObject::cast(type)->GetIsolate()); + } + + static Type* from_bitset(int bitset) { + return static_cast(i::Object::cast(i::Smi::FromInt(bitset))); + } + static Type* from_handle(Handle handle) { + return static_cast(i::Object::cast(*handle)); + } + + static Handle union_get(Handle unioned, int i) { + Type* type = static_cast(unioned->get(i)); + ASSERT(!type->is_union()); + return type->handle_via_isolate_of(from_handle(unioned)); + } int LubBitset(); // least upper bound that's a bitset int GlbBitset(); // greatest lower bound that's a bitset @@ -275,131 +271,67 @@ class TypeImpl : public Config::Base { static int LubBitset(i::Object* value); static int LubBitset(i::Map* map); - bool InUnion(UnionedHandle unioned, int current_size); - int ExtendUnion(UnionedHandle unioned, int current_size); + bool InUnion(Handle unioned, int current_size); + int ExtendUnion(Handle unioned, int current_size); int ExtendIntersection( - UnionedHandle unioned, TypeHandle type, int current_size); + Handle unioned, Handle type, int current_size); static const char* bitset_name(int bitset); }; -struct HeapTypeConfig { - typedef TypeImpl Type; - typedef i::Object Base; - typedef i::FixedArray Unioned; - typedef i::Isolate Region; - template struct Handle { typedef i::Handle type; }; - - static i::Handle handle(Type* type) { - return i::handle(type, i::HeapObject::cast(type)->GetIsolate()); - } - - static bool is_bitset(Type* type) { return type->IsSmi(); } - static bool is_class(Type* type) { return type->IsMap(); } - static bool is_constant(Type* type) { return type->IsBox(); } - static bool is_union(Type* type) { return type->IsFixedArray(); } - - static int as_bitset(Type* type) { - return Smi::cast(type)->value(); - } - static i::Handle as_class(Type* type) { - return i::handle(i::Map::cast(type)); - } - static i::Handle as_constant(Type* type) { - i::Box* box = i::Box::cast(type); - return i::handle(box->value(), box->GetIsolate()); - } - static i::Handle as_union(Type* type) { - return i::handle(i::FixedArray::cast(type)); - } +// A simple struct to represent a pair of lower/upper type bounds. +struct Bounds { + Handle lower; + Handle upper; - static Type* from_bitset(int bitset) { - return Type::cast(i::Smi::FromInt(bitset)); - } - static i::Handle from_bitset(int bitset, Isolate* isolate) { - return i::handle(from_bitset(bitset), isolate); - } - static i::Handle from_class(i::Handle map, Isolate* isolate) { - return i::Handle::cast(i::Handle::cast(map)); - } - static i::Handle from_constant( - i::Handle value, Isolate* isolate) { - ASSERT(isolate || value->IsHeapObject()); - if (!isolate) isolate = i::HeapObject::cast(*value)->GetIsolate(); - i::Handle box = isolate->factory()->NewBox(value); - return i::Handle::cast(i::Handle::cast(box)); - } - static i::Handle from_union(i::Handle unioned) { - return i::Handle::cast(i::Handle::cast(unioned)); + Bounds() {} + Bounds(Handle l, Handle u) : lower(l), upper(u) { + ASSERT(lower->Is(upper)); } - - static i::Handle union_create(int size, Isolate* isolate) { - return isolate->factory()->NewFixedArray(size); + Bounds(Type* l, Type* u, Isolate* isl) : lower(l, isl), upper(u, isl) { + ASSERT(lower->Is(upper)); } - static i::Handle union_get(i::Handle unioned, int i) { - Type* type = static_cast(unioned->get(i)); - ASSERT(!is_union(type)); - return i::handle(type, unioned->GetIsolate()); + explicit Bounds(Handle t) : lower(t), upper(t) { + ASSERT(lower->Is(upper)); } -}; - -typedef TypeImpl Type; - - -// A simple struct to represent a pair of lower/upper type bounds. -template -struct BoundsImpl { - typedef TypeImpl Type; - typedef typename Type::TypeHandle TypeHandle; - typedef typename Type::Region Region; - - TypeHandle lower; - TypeHandle upper; - - BoundsImpl() {} - explicit BoundsImpl(TypeHandle t) : lower(t), upper(t) {} - BoundsImpl(TypeHandle l, TypeHandle u) : lower(l), upper(u) { + Bounds(Type* t, Isolate* isl) : lower(t, isl), upper(t, isl) { ASSERT(lower->Is(upper)); } // Unrestricted bounds. - static BoundsImpl Unbounded(Region* region) { - return BoundsImpl(Type::None(region), Type::Any(region)); + static Bounds Unbounded(Isolate* isl) { + return Bounds(Type::None(), Type::Any(), isl); } // Meet: both b1 and b2 are known to hold. - static BoundsImpl Both(BoundsImpl b1, BoundsImpl b2, Region* region) { - TypeHandle lower = Type::Union(b1.lower, b2.lower, region); - TypeHandle upper = Type::Intersect(b1.upper, b2.upper, region); + static Bounds Both(Bounds b1, Bounds b2, Isolate* isl) { + Handle lower(Type::Union(b1.lower, b2.lower), isl); + Handle upper(Type::Intersect(b1.upper, b2.upper), isl); // Lower bounds are considered approximate, correct as necessary. - lower = Type::Intersect(lower, upper, region); - return BoundsImpl(lower, upper); + lower = handle(Type::Intersect(lower, upper), isl); + return Bounds(lower, upper); } // Join: either b1 or b2 is known to hold. - static BoundsImpl Either(BoundsImpl b1, BoundsImpl b2, Region* region) { - TypeHandle lower = Type::Intersect(b1.lower, b2.lower, region); - TypeHandle upper = Type::Union(b1.upper, b2.upper, region); - return BoundsImpl(lower, upper); + static Bounds Either(Bounds b1, Bounds b2, Isolate* isl) { + return Bounds( + handle(Type::Intersect(b1.lower, b2.lower), isl), + handle(Type::Union(b1.upper, b2.upper), isl)); } - static BoundsImpl NarrowLower(BoundsImpl b, TypeHandle t, Region* region) { + static Bounds NarrowLower(Bounds b, Handle t, Isolate* isl) { // Lower bounds are considered approximate, correct as necessary. - t = Type::Intersect(t, b.upper, region); - TypeHandle lower = Type::Union(b.lower, t, region); - return BoundsImpl(lower, b.upper); + t = handle(Type::Intersect(t, b.upper), isl); + return Bounds(handle(Type::Union(b.lower, t), isl), b.upper); } - static BoundsImpl NarrowUpper(BoundsImpl b, TypeHandle t, Region* region) { - TypeHandle lower = Type::Intersect(b.lower, t, region); - TypeHandle upper = Type::Intersect(b.upper, t, region); - return BoundsImpl(lower, upper); + static Bounds NarrowUpper(Bounds b, Handle t, Isolate* isl) { + return Bounds( + handle(Type::Intersect(b.lower, t), isl), + handle(Type::Intersect(b.upper, t), isl)); } }; -typedef BoundsImpl Bounds; - - } } // namespace v8::internal #endif // V8_TYPES_H_ diff --git a/src/typing.cc b/src/typing.cc index 30e0b9205..152f3c732 100644 --- a/src/typing.cc +++ b/src/typing.cc @@ -71,6 +71,12 @@ void AstTyper::Run(CompilationInfo* info) { #undef RECURSE +Effect AstTyper::ObservedOnStack(Object* value) { + Type* lower = Type::OfCurrently(Handle(value, isolate())); + return Effect(Bounds(lower, Type::Any(), isolate())); +} + + #ifdef OBJECT_PRINT static void PrintObserved(Variable* var, Object* value, Handle type) { PrintF(" observed %s ", var->IsParameter() ? "param" : "local"); @@ -83,12 +89,6 @@ void AstTyper::Run(CompilationInfo* info) { #endif // OBJECT_PRINT -Effect AstTyper::ObservedOnStack(Object* value) { - Handle lower = Type::OfCurrently(handle(value, isolate()), isolate()); - return Effect(Bounds(lower, Type::Any(isolate()))); -} - - void AstTyper::ObserveTypesAtOsrEntry(IterationStatement* stmt) { if (stmt->OsrEntryId() != info_->osr_ast_id()) return; @@ -405,13 +405,13 @@ void AstTyper::VisitVariableProxy(VariableProxy* expr) { void AstTyper::VisitLiteral(Literal* expr) { - Handle type = Type::Constant(expr->value(), isolate_); - NarrowType(expr, Bounds(type)); + Type* type = Type::Constant(expr->value(), isolate_); + NarrowType(expr, Bounds(type, isolate_)); } void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) { - NarrowType(expr, Bounds(Type::RegExp(isolate_))); + NarrowType(expr, Bounds(Type::RegExp(), isolate_)); } @@ -432,7 +432,7 @@ void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) { RECURSE(Visit(prop->value())); } - NarrowType(expr, Bounds(Type::Object(isolate_))); + NarrowType(expr, Bounds(Type::Object(), isolate_)); } @@ -443,7 +443,7 @@ void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { RECURSE(Visit(value)); } - NarrowType(expr, Bounds(Type::Array(isolate_))); + NarrowType(expr, Bounds(Type::Array(), isolate_)); } @@ -495,7 +495,7 @@ void AstTyper::VisitThrow(Throw* expr) { RECURSE(Visit(expr->exception())); // TODO(rossberg): is it worth having a non-termination effect? - NarrowType(expr, Bounds(Type::None(isolate_))); + NarrowType(expr, Bounds(Type::None(), isolate_)); } @@ -593,13 +593,13 @@ void AstTyper::VisitUnaryOperation(UnaryOperation* expr) { switch (expr->op()) { case Token::NOT: case Token::DELETE: - NarrowType(expr, Bounds(Type::Boolean(isolate_))); + NarrowType(expr, Bounds(Type::Boolean(), isolate_)); break; case Token::VOID: - NarrowType(expr, Bounds(Type::Undefined(isolate_))); + NarrowType(expr, Bounds(Type::Undefined(), isolate_)); break; case Token::TYPEOF: - NarrowType(expr, Bounds(Type::InternalizedString(isolate_))); + NarrowType(expr, Bounds(Type::InternalizedString(), isolate_)); break; default: UNREACHABLE(); @@ -617,7 +617,7 @@ void AstTyper::VisitCountOperation(CountOperation* expr) { RECURSE(Visit(expr->expression())); - NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_))); + NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); VariableProxy* proxy = expr->expression()->AsVariableProxy(); if (proxy != NULL && proxy->var()->IsStackAllocated()) { @@ -668,13 +668,14 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { case Token::BIT_AND: { RECURSE(Visit(expr->left())); RECURSE(Visit(expr->right())); - Handle upper = Type::Union( - expr->left()->bounds().upper, expr->right()->bounds().upper, + Handle upper( + Type::Union( + expr->left()->bounds().upper, expr->right()->bounds().upper), isolate_); if (!upper->Is(Type::Signed32())) - upper = Type::Signed32(isolate_); - Handle lower = - Type::Intersect(Type::Smi(isolate_), upper, isolate_); + upper = handle(Type::Signed32(), isolate_); + Handle lower(Type::Intersect( + handle(Type::Smi(), isolate_), upper), isolate_); NarrowType(expr, Bounds(lower, upper)); break; } @@ -683,7 +684,7 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { case Token::SAR: RECURSE(Visit(expr->left())); RECURSE(Visit(expr->right())); - NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Signed32(isolate_))); + NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_)); break; case Token::SHR: RECURSE(Visit(expr->left())); @@ -691,26 +692,26 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { // TODO(rossberg): The upper bound would be Unsigned32, but since there // is no 'positive Smi' type for the lower bound, we use the smallest // union of Smi and Unsigned32 as upper bound instead. - NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_))); + NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); break; case Token::ADD: { RECURSE(Visit(expr->left())); RECURSE(Visit(expr->right())); Bounds l = expr->left()->bounds(); Bounds r = expr->right()->bounds(); - Handle lower = + Type* lower = l.lower->Is(Type::None()) || r.lower->Is(Type::None()) ? - Type::None(isolate_) : + Type::None() : l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ? - Type::String(isolate_) : + Type::String() : l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ? - Type::Smi(isolate_) : Type::None(isolate_); - Handle upper = + Type::Smi() : Type::None(); + Type* upper = l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ? - Type::String(isolate_) : + Type::String() : l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ? - Type::Number(isolate_) : Type::NumberOrString(isolate_); - NarrowType(expr, Bounds(lower, upper)); + Type::Number() : Type::NumberOrString(); + NarrowType(expr, Bounds(lower, upper, isolate_)); break; } case Token::SUB: @@ -719,7 +720,7 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { case Token::MOD: RECURSE(Visit(expr->left())); RECURSE(Visit(expr->right())); - NarrowType(expr, Bounds(Type::Smi(isolate_), Type::Number(isolate_))); + NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); break; default: UNREACHABLE(); @@ -739,7 +740,7 @@ void AstTyper::VisitCompareOperation(CompareOperation* expr) { RECURSE(Visit(expr->left())); RECURSE(Visit(expr->right())); - NarrowType(expr, Bounds(Type::Boolean(isolate_))); + NarrowType(expr, Bounds(Type::Boolean(), isolate_)); } diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc index adcc15694..264d2ed88 100644 --- a/test/cctest/test-types.cc +++ b/test/cctest/test-types.cc @@ -31,32 +31,32 @@ using namespace v8::internal; // Testing auxiliaries (breaking the Type abstraction). -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 IsUnion(Handle t) { return t->IsFixedArray(); } +static bool IsBitset(Type* type) { return type->IsSmi(); } +static bool IsClass(Type* type) { return type->IsMap(); } +static bool IsConstant(Type* type) { return type->IsBox(); } +static bool IsUnion(Type* type) { return type->IsFixedArray(); } -static int AsBitset(Handle t) { return Smi::cast(*t)->value(); } -static Map* AsClass(Handle t) { return Map::cast(*t); } -static Object* AsConstant(Handle t) { return Box::cast(*t)->value(); } -static FixedArray* AsUnion(Handle t) { return FixedArray::cast(*t); } +static int AsBitset(Type* type) { return Smi::cast(type)->value(); } +static Map* AsClass(Type* type) { return Map::cast(type); } +static Object* AsConstant(Type* type) { return Box::cast(type)->value(); } +static FixedArray* AsUnion(Type* type) { return FixedArray::cast(type); } static void CheckEqual(Handle type1, Handle type2) { - CHECK_EQ(IsBitset(type1), IsBitset(type2)); - CHECK_EQ(IsClass(type1), IsClass(type2)); - CHECK_EQ(IsConstant(type1), IsConstant(type2)); - CHECK_EQ(IsUnion(type1), IsUnion(type2)); + CHECK_EQ(IsBitset(*type1), IsBitset(*type2)); + CHECK_EQ(IsClass(*type1), IsClass(*type2)); + CHECK_EQ(IsConstant(*type1), IsConstant(*type2)); + CHECK_EQ(IsUnion(*type1), IsUnion(*type2)); CHECK_EQ(type1->NumClasses(), type2->NumClasses()); CHECK_EQ(type1->NumConstants(), type2->NumConstants()); - if (IsBitset(type1)) { - CHECK_EQ(AsBitset(type1), AsBitset(type2)); - } else if (IsClass(type1)) { - CHECK_EQ(AsClass(type1), AsClass(type2)); - } else if (IsConstant(type1)) { - CHECK_EQ(AsConstant(type1), AsConstant(type2)); - } else if (IsUnion(type1)) { - CHECK_EQ(AsUnion(type1)->length(), AsUnion(type2)->length()); + if (IsBitset(*type1)) { + CHECK_EQ(AsBitset(*type1), AsBitset(*type2)); + } else if (IsClass(*type1)) { + CHECK_EQ(AsClass(*type1), AsClass(*type2)); + } else if (IsConstant(*type1)) { + CHECK_EQ(AsConstant(*type1), AsConstant(*type2)); + } else if (IsUnion(*type1)) { + CHECK_EQ(AsUnion(*type1)->length(), AsUnion(*type2)->length()); } CHECK(type1->Is(type2)); CHECK(type2->Is(type1)); @@ -66,8 +66,8 @@ static void CheckEqual(Handle type1, Handle type2) { static void CheckSub(Handle type1, Handle type2) { CHECK(type1->Is(type2)); CHECK(!type2->Is(type1)); - if (IsBitset(type1) && IsBitset(type2)) { - CHECK_NE(AsBitset(type1), AsBitset(type2)); + if (IsBitset(*type1) && IsBitset(*type2)) { + CHECK_NE(AsBitset(*type1), AsBitset(*type2)); } } @@ -75,8 +75,8 @@ static void CheckSub(Handle type1, Handle type2) { static void CheckUnordered(Handle type1, Handle type2) { CHECK(!type1->Is(type2)); CHECK(!type2->Is(type1)); - if (IsBitset(type1) && IsBitset(type2)) { - CHECK_NE(AsBitset(type1), AsBitset(type2)); + if (IsBitset(*type1) && IsBitset(*type2)) { + CHECK_NE(AsBitset(*type1), AsBitset(*type2)); } } @@ -84,8 +84,8 @@ static void CheckUnordered(Handle type1, Handle type2) { static void CheckOverlap(Handle type1, Handle type2) { CHECK(type1->Maybe(type2)); CHECK(type2->Maybe(type1)); - if (IsBitset(type1) && IsBitset(type2)) { - CHECK_NE(0, AsBitset(type1) & AsBitset(type2)); + if (IsBitset(*type1) && IsBitset(*type2)) { + CHECK_NE(0, AsBitset(*type1) & AsBitset(*type2)); } } @@ -95,8 +95,8 @@ static void CheckDisjoint(Handle type1, Handle type2) { CHECK(!type2->Is(type1)); CHECK(!type1->Maybe(type2)); CHECK(!type2->Maybe(type1)); - if (IsBitset(type1) && IsBitset(type2)) { - CHECK_EQ(0, AsBitset(type1) & AsBitset(type2)); + if (IsBitset(*type1) && IsBitset(*type2)) { + CHECK_EQ(0, AsBitset(*type1) & AsBitset(*type2)); } } @@ -104,26 +104,26 @@ static void CheckDisjoint(Handle type1, Handle type2) { class HandlifiedTypes { public: explicit HandlifiedTypes(Isolate* isolate) : - None(Type::None(isolate)), - Any(Type::Any(isolate)), - Oddball(Type::Oddball(isolate)), - Boolean(Type::Boolean(isolate)), - Null(Type::Null(isolate)), - Undefined(Type::Undefined(isolate)), - Number(Type::Number(isolate)), - Smi(Type::Smi(isolate)), - Signed32(Type::Signed32(isolate)), - Double(Type::Double(isolate)), - Name(Type::Name(isolate)), - UniqueName(Type::UniqueName(isolate)), - String(Type::String(isolate)), - InternalizedString(Type::InternalizedString(isolate)), - Symbol(Type::Symbol(isolate)), - Receiver(Type::Receiver(isolate)), - Object(Type::Object(isolate)), - Array(Type::Array(isolate)), - Function(Type::Function(isolate)), - Proxy(Type::Proxy(isolate)), + None(Type::None(), isolate), + Any(Type::Any(), isolate), + Oddball(Type::Oddball(), isolate), + Boolean(Type::Boolean(), isolate), + Null(Type::Null(), isolate), + Undefined(Type::Undefined(), isolate), + Number(Type::Number(), isolate), + Smi(Type::Smi(), isolate), + Signed32(Type::Signed32(), isolate), + Double(Type::Double(), isolate), + Name(Type::Name(), isolate), + UniqueName(Type::UniqueName(), isolate), + String(Type::String(), isolate), + InternalizedString(Type::InternalizedString(), isolate), + Symbol(Type::Symbol(), isolate), + Receiver(Type::Receiver(), isolate), + Object(Type::Object(), isolate), + Array(Type::Array(), isolate), + Function(Type::Function(), isolate), + Proxy(Type::Proxy(), isolate), object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)), array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)), isolate_(isolate) { @@ -132,14 +132,14 @@ class HandlifiedTypes { object1 = isolate->factory()->NewJSObjectFromMap(object_map); object2 = isolate->factory()->NewJSObjectFromMap(object_map); array = isolate->factory()->NewJSArray(20); - ObjectClass = Type::Class(object_map, isolate); - ArrayClass = Type::Class(array_map, isolate); - SmiConstant = Type::Constant(smi, isolate); - Signed32Constant = Type::Constant(signed32, isolate); - ObjectConstant1 = Type::Constant(object1, isolate); - ObjectConstant2 = Type::Constant(object2, isolate); - ArrayConstant1 = Type::Constant(array, isolate); - ArrayConstant2 = Type::Constant(array, isolate); + ObjectClass = Class(object_map); + ArrayClass = Class(array_map); + SmiConstant = Constant(smi); + Signed32Constant = Constant(signed32); + ObjectConstant1 = Constant(object1); + ObjectConstant2 = Constant(object2); + ArrayConstant1 = Constant(array); + ArrayConstant2 = Constant(array); } Handle None; @@ -182,11 +182,17 @@ class HandlifiedTypes { Handle object2; Handle array; - Handle Union(Handle t1, Handle t2) { - return Type::Union(t1, t2, isolate_); + Handle Class(Handle map) { + return handle(Type::Class(map), isolate_); } - Handle Intersect(Handle t1, Handle t2) { - return Type::Intersect(t1, t2, isolate_); + Handle Constant(Handle value) { + return handle(Type::Constant(value, isolate_), isolate_); + } + Handle Union(Handle type1, Handle type2) { + return handle(Type::Union(type1, type2), isolate_); + } + Handle Intersect(Handle type1, Handle type2) { + return handle(Type::Intersect(type1, type2), isolate_); } private: @@ -200,19 +206,22 @@ TEST(Bitset) { HandleScope scope(isolate); HandlifiedTypes T(isolate); - CHECK(IsBitset(T.None)); - CHECK(IsBitset(T.Any)); - CHECK(IsBitset(T.String)); - CHECK(IsBitset(T.Object)); - - CHECK(IsBitset(T.Union(T.String, T.Number))); - CHECK(IsBitset(T.Union(T.String, T.Receiver))); - - CHECK_EQ(0, AsBitset(T.None)); - CHECK_EQ(AsBitset(T.Number) | AsBitset(T.String), - AsBitset(T.Union(T.String, T.Number))); - CHECK_EQ(AsBitset(T.Receiver), - AsBitset(T.Union(T.Receiver, T.Object))); + CHECK(IsBitset(*T.None)); + CHECK(IsBitset(*T.Any)); + CHECK(IsBitset(*T.String)); + CHECK(IsBitset(*T.Object)); + + CHECK(IsBitset(Type::Union(T.String, T.Number))); + CHECK(IsBitset(Type::Union(T.String, T.Receiver))); + CHECK(IsBitset(Type::Optional(T.Object))); + + CHECK_EQ(0, AsBitset(*T.None)); + CHECK_EQ(AsBitset(*T.Number) | AsBitset(*T.String), + AsBitset(Type::Union(T.String, T.Number))); + CHECK_EQ(AsBitset(*T.Receiver), + AsBitset(Type::Union(T.Receiver, T.Object))); + CHECK_EQ(AsBitset(*T.String) | AsBitset(*T.Undefined), + AsBitset(Type::Optional(T.String))); } @@ -222,11 +231,11 @@ TEST(Class) { HandleScope scope(isolate); HandlifiedTypes T(isolate); - CHECK(IsClass(T.ObjectClass)); - CHECK(IsClass(T.ArrayClass)); + CHECK(IsClass(*T.ObjectClass)); + CHECK(IsClass(*T.ArrayClass)); - CHECK(*T.object_map == AsClass(T.ObjectClass)); - CHECK(*T.array_map == AsClass(T.ArrayClass)); + CHECK(*T.object_map == AsClass(*T.ObjectClass)); + CHECK(*T.array_map == AsClass(*T.ArrayClass)); } @@ -236,18 +245,18 @@ TEST(Constant) { HandleScope scope(isolate); HandlifiedTypes T(isolate); - CHECK(IsConstant(T.SmiConstant)); - CHECK(IsConstant(T.ObjectConstant1)); - CHECK(IsConstant(T.ObjectConstant2)); - CHECK(IsConstant(T.ArrayConstant1)); - CHECK(IsConstant(T.ArrayConstant2)); - - CHECK(*T.smi == AsConstant(T.SmiConstant)); - CHECK(*T.object1 == AsConstant(T.ObjectConstant1)); - CHECK(*T.object2 == AsConstant(T.ObjectConstant2)); - CHECK(*T.object1 != AsConstant(T.ObjectConstant2)); - CHECK(*T.array == AsConstant(T.ArrayConstant1)); - CHECK(*T.array == AsConstant(T.ArrayConstant2)); + CHECK(IsConstant(*T.SmiConstant)); + CHECK(IsConstant(*T.ObjectConstant1)); + CHECK(IsConstant(*T.ObjectConstant2)); + CHECK(IsConstant(*T.ArrayConstant1)); + CHECK(IsConstant(*T.ArrayConstant2)); + + CHECK(*T.smi == AsConstant(*T.SmiConstant)); + CHECK(*T.object1 == AsConstant(*T.ObjectConstant1)); + CHECK(*T.object2 == AsConstant(*T.ObjectConstant2)); + CHECK(*T.object1 != AsConstant(*T.ObjectConstant2)); + CHECK(*T.array == AsConstant(*T.ArrayConstant1)); + CHECK(*T.array == AsConstant(*T.ArrayConstant2)); } @@ -417,9 +426,9 @@ TEST(Union) { HandlifiedTypes T(isolate); // Bitset-bitset - CHECK(IsBitset(T.Union(T.Object, T.Number))); - CHECK(IsBitset(T.Union(T.Object, T.Object))); - CHECK(IsBitset(T.Union(T.Any, T.None))); + CHECK(IsBitset(Type::Union(T.Object, T.Number))); + CHECK(IsBitset(Type::Union(T.Object, T.Object))); + CHECK(IsBitset(Type::Union(T.Any, T.None))); CheckEqual(T.Union(T.None, T.Number), T.Number); CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver); @@ -427,8 +436,8 @@ TEST(Union) { CheckSub(T.Union(T.Number, T.String), T.Any); // Class-class - CHECK(IsClass(T.Union(T.ObjectClass, T.ObjectClass))); - CHECK(IsUnion(T.Union(T.ObjectClass, T.ArrayClass))); + CHECK(IsClass(Type::Union(T.ObjectClass, T.ObjectClass))); + CHECK(IsUnion(Type::Union(T.ObjectClass, T.ArrayClass))); CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass); CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass)); @@ -441,9 +450,9 @@ TEST(Union) { CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number); // Constant-constant - CHECK(IsConstant(T.Union(T.ObjectConstant1, T.ObjectConstant1))); - CHECK(IsConstant(T.Union(T.ArrayConstant1, T.ArrayConstant1))); - CHECK(IsUnion(T.Union(T.ObjectConstant1, T.ObjectConstant2))); + CHECK(IsConstant(Type::Union(T.ObjectConstant1, T.ObjectConstant1))); + CHECK(IsConstant(Type::Union(T.ArrayConstant1, T.ArrayConstant1))); + CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectConstant2))); CheckEqual(T.Union(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1); @@ -462,8 +471,8 @@ TEST(Union) { CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass); // Bitset-class - CHECK(IsBitset(T.Union(T.ObjectClass, T.Object))); - CHECK(IsUnion(T.Union(T.ObjectClass, T.Number))); + CHECK(IsBitset(Type::Union(T.ObjectClass, T.Object))); + CHECK(IsUnion(Type::Union(T.ObjectClass, T.Number))); CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object); CheckSub(T.None, T.Union(T.ObjectClass, T.Number)); @@ -475,9 +484,9 @@ TEST(Union) { CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number); // Bitset-constant - CHECK(IsBitset(T.Union(T.SmiConstant, T.Number))); - CHECK(IsBitset(T.Union(T.ObjectConstant1, T.Object))); - CHECK(IsUnion(T.Union(T.ObjectConstant2, T.Number))); + CHECK(IsBitset(Type::Union(T.SmiConstant, T.Number))); + CHECK(IsBitset(Type::Union(T.ObjectConstant1, T.Object))); + CHECK(IsUnion(Type::Union(T.ObjectConstant2, T.Number))); CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number); CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object); @@ -491,8 +500,8 @@ TEST(Union) { CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32); // Class-constant - CHECK(IsUnion(T.Union(T.ObjectConstant1, T.ObjectClass))); - CHECK(IsUnion(T.Union(T.ArrayClass, T.ObjectConstant2))); + CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectClass))); + CHECK(IsUnion(Type::Union(T.ArrayClass, T.ObjectConstant2))); CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass)); CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any); @@ -507,8 +516,10 @@ TEST(Union) { CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass); // Bitset-union - CHECK(IsBitset(T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); - CHECK(IsUnion(T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); + CHECK(IsBitset( + Type::Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); + CHECK(IsUnion( + Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); CheckEqual( T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), @@ -534,9 +545,9 @@ TEST(Union) { // Class-union CHECK(IsUnion( - T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); + Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); CHECK(IsUnion( - T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass))); + Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass))); CheckEqual( T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), @@ -555,11 +566,11 @@ TEST(Union) { T.Union(T.ArrayClass, T.ObjectConstant2)); // Constant-union - CHECK(IsUnion(T.Union( + CHECK(IsUnion(Type::Union( T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); - CHECK(IsUnion(T.Union( + CHECK(IsUnion(Type::Union( T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); - CHECK(IsUnion(T.Union( + CHECK(IsUnion(Type::Union( T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1))); CheckEqual( @@ -570,9 +581,9 @@ TEST(Union) { T.Union(T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1))); // Union-union - CHECK(IsBitset(T.Union( + CHECK(IsBitset(Type::Union( T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array)))); - CHECK(IsUnion(T.Union( + CHECK(IsUnion(Type::Union( T.Union(T.Number, T.ArrayClass), T.Union(T.ObjectClass, T.ArrayClass)))); CheckEqual( @@ -598,9 +609,9 @@ TEST(Intersect) { HandlifiedTypes T(isolate); // Bitset-bitset - CHECK(IsBitset(T.Intersect(T.Object, T.Number))); - CHECK(IsBitset(T.Intersect(T.Object, T.Object))); - CHECK(IsBitset(T.Intersect(T.Any, T.None))); + CHECK(IsBitset(Type::Intersect(T.Object, T.Number))); + CHECK(IsBitset(Type::Intersect(T.Object, T.Object))); + CHECK(IsBitset(Type::Intersect(T.Any, T.None))); CheckEqual(T.Intersect(T.None, T.Number), T.None); CheckEqual(T.Intersect(T.Object, T.Proxy), T.None); @@ -608,16 +619,16 @@ TEST(Intersect) { CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString); // Class-class - CHECK(IsClass(T.Intersect(T.ObjectClass, T.ObjectClass))); - CHECK(IsBitset(T.Intersect(T.ObjectClass, T.ArrayClass))); + CHECK(IsClass(Type::Intersect(T.ObjectClass, T.ObjectClass))); + CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.ArrayClass))); CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass); CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None); // Constant-constant - CHECK(IsConstant(T.Intersect(T.ObjectConstant1, T.ObjectConstant1))); - CHECK(IsConstant(T.Intersect(T.ArrayConstant1, T.ArrayConstant2))); - CHECK(IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectConstant2))); + CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.ObjectConstant1))); + CHECK(IsConstant(Type::Intersect(T.ArrayConstant1, T.ArrayConstant2))); + CHECK(IsBitset(Type::Intersect(T.ObjectConstant1, T.ObjectConstant2))); CheckEqual( T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); @@ -626,34 +637,34 @@ TEST(Intersect) { CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None); // Bitset-class - CHECK(IsClass(T.Intersect(T.ObjectClass, T.Object))); - CHECK(IsBitset(T.Intersect(T.ObjectClass, T.Number))); + CHECK(IsClass(Type::Intersect(T.ObjectClass, T.Object))); + CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.Number))); CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None); CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None); // Bitset-constant - CHECK(IsBitset(T.Intersect(T.Smi, T.Number))); - CHECK(IsConstant(T.Intersect(T.SmiConstant, T.Number))); - CHECK(IsConstant(T.Intersect(T.ObjectConstant1, T.Object))); + CHECK(IsBitset(Type::Intersect(T.Smi, T.Number))); + CHECK(IsConstant(Type::Intersect(T.SmiConstant, T.Number))); + CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.Object))); CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi); CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant); CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1); // Class-constant - CHECK(IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectClass))); - CHECK(IsBitset(T.Intersect(T.ArrayClass, T.ObjectConstant2))); + CHECK(IsBitset(Type::Intersect(T.ObjectConstant1, T.ObjectClass))); + CHECK(IsBitset(Type::Intersect(T.ArrayClass, T.ObjectConstant2))); CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); // Bitset-union CHECK(IsUnion( - T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); + Type::Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); CHECK(IsBitset( - T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); + Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); CheckEqual( T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), @@ -664,11 +675,11 @@ TEST(Intersect) { // Class-union CHECK(IsClass( - T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); + Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); CHECK(IsClass( - T.Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass))); + Type::Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass))); CHECK(IsBitset( - T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass))); + Type::Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass))); CheckEqual( T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), @@ -681,11 +692,11 @@ TEST(Intersect) { T.None); // Constant-union - CHECK(IsConstant(T.Intersect( + CHECK(IsConstant(Type::Intersect( T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); - CHECK(IsConstant(T.Intersect( + CHECK(IsConstant(Type::Intersect( T.Union(T.Number, T.ObjectClass), T.SmiConstant))); - CHECK(IsBitset(T.Intersect( + CHECK(IsBitset(Type::Intersect( T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); CheckEqual( @@ -700,9 +711,9 @@ TEST(Intersect) { T.None); // Union-union - CHECK(IsUnion(T.Intersect( + CHECK(IsUnion(Type::Intersect( T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array)))); - CHECK(IsBitset(T.Intersect( + CHECK(IsBitset(Type::Intersect( T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array)))); CheckEqual(