From 119cb5661724006b736fcb6484258c752125e372 Mon Sep 17 00:00:00 2001 From: verwaest Date: Tue, 17 Feb 2015 07:33:26 -0800 Subject: [PATCH] Stop using HeapType in IC and Crankshaft BUG= Review URL: https://codereview.chromium.org/935603002 Cr-Commit-Position: refs/heads/master@{#26696} --- src/accessors.cc | 29 +--- src/accessors.h | 4 +- src/hydrogen.cc | 246 +++++++++++++++------------------ src/hydrogen.h | 28 ++-- src/ic/arm/handler-compiler-arm.cc | 20 ++- src/ic/arm/ic-compiler-arm.cc | 11 +- src/ic/arm64/handler-compiler-arm64.cc | 20 ++- src/ic/arm64/ic-compiler-arm64.cc | 11 +- src/ic/call-optimization.cc | 6 +- src/ic/call-optimization.h | 4 +- src/ic/handler-compiler.cc | 48 +++---- src/ic/handler-compiler.h | 45 +++--- src/ic/ia32/handler-compiler-ia32.cc | 21 ++- src/ic/ia32/ic-compiler-ia32.cc | 11 +- src/ic/ic-compiler.cc | 46 +++--- src/ic/ic-compiler.h | 15 +- src/ic/ic-inl.h | 26 ++-- src/ic/ic.cc | 210 +++++++++++----------------- src/ic/ic.h | 48 +++---- src/ic/x64/handler-compiler-x64.cc | 20 ++- src/ic/x64/ic-compiler-x64.cc | 11 +- src/objects.cc | 7 +- src/objects.h | 6 +- src/type-feedback-vector.cc | 25 ++-- src/type-feedback-vector.h | 10 +- 25 files changed, 397 insertions(+), 531 deletions(-) diff --git a/src/accessors.cc b/src/accessors.cc index 02b96ca..e08f86f 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -69,20 +69,10 @@ static V8_INLINE bool CheckForName(Handle name, // Returns true for properties that are accessors to object fields. // If true, *object_offset contains offset of object field. -template -bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type, - Handle name, +bool Accessors::IsJSObjectFieldAccessor(Handle map, Handle name, int* object_offset) { Isolate* isolate = name->GetIsolate(); - if (type->Is(T::String())) { - return CheckForName(name, isolate->factory()->length_string(), - String::kLengthOffset, object_offset); - } - - if (!type->IsClass()) return false; - Handle map = type->AsClass()->Map(); - switch (map->instance_type()) { case JS_ARRAY_TYPE: return @@ -107,23 +97,16 @@ bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type, CheckForName(name, isolate->factory()->byte_offset_string(), JSDataView::kByteOffsetOffset, object_offset); default: + if (map->instance_type() < FIRST_NONSTRING_TYPE) { + return CheckForName(name, isolate->factory()->length_string(), + String::kLengthOffset, object_offset); + } + return false; } } -template -bool Accessors::IsJSObjectFieldAccessor(Type* type, - Handle name, - int* object_offset); - - -template -bool Accessors::IsJSObjectFieldAccessor(Handle type, - Handle name, - int* object_offset); - - bool SetPropertyOnInstanceIfInherited( Isolate* isolate, const v8::PropertyCallbackInfo& info, v8::Local name, Handle value) { diff --git a/src/accessors.h b/src/accessors.h index bf0c4e4..e4ad691 100644 --- a/src/accessors.h +++ b/src/accessors.h @@ -78,9 +78,7 @@ class Accessors : public AllStatic { // Returns true for properties that are accessors to object fields. // If true, *object_offset contains offset of object field. - template - static bool IsJSObjectFieldAccessor(typename T::TypeHandle type, - Handle name, + static bool IsJSObjectFieldAccessor(Handle map, Handle name, int* object_offset); static Handle MakeAccessor( diff --git a/src/hydrogen.cc b/src/hydrogen.cc index c8fbbc7..84d0c7c 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -4472,11 +4472,6 @@ void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { } -Type* HOptimizedGraphBuilder::ToType(Handle map) { - return IC::MapToType(map, zone()); -} - - void HOptimizedGraphBuilder::VisitStatements(ZoneList* statements) { for (int i = 0; i < statements->length(); i++) { Statement* stmt = statements->at(i); @@ -5445,10 +5440,9 @@ 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(); +static bool CanInlinePropertyAccess(Handle map) { + if (map->instance_type() == HEAP_NUMBER_TYPE) return true; + if (map->instance_type() < FIRST_NONSTRING_TYPE) return true; return map->IsJSObjectMap() && !map->is_dictionary_map() && !map->has_named_interceptor(); @@ -5618,7 +5612,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { CHECK_ALIVE(store = BuildNamedGeneric( STORE, NULL, literal, name, value)); } else { - PropertyAccessInfo info(this, STORE, ToType(map), name); + PropertyAccessInfo info(this, STORE, map, name); if (info.CanAccessMonomorphic()) { HValue* checked_literal = Add(literal, map); DCHECK(!info.IsAccessorConstant()); @@ -5907,20 +5901,16 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( PropertyAccessInfo* info) { - if (!CanInlinePropertyAccess(type_)) return false; + if (!CanInlinePropertyAccess(map_)) return false; // Currently only handle Type::Number as a polymorphic case. // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber // instruction. - if (type_->Is(Type::Number())) return false; + if (IsNumberType()) return false; // Values are only compatible for monomorphic load if they all behave the same // regarding value wrappers. - if (type_->Is(Type::NumberOrString())) { - if (!info->type_->Is(Type::NumberOrString())) return false; - } else { - if (info->type_->Is(Type::NumberOrString())) return false; - } + if (IsValueWrapped() != info->IsValueWrapped()) return false; if (!LookupDescriptor()) return false; @@ -5979,9 +5969,9 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupDescriptor() { - if (!type_->IsClass()) return true; - map()->LookupDescriptor(NULL, *name_, &lookup_); - return LoadResult(map()); + if (!map_->IsJSObjectMap()) return true; + map_->LookupDescriptor(NULL, *name_, &lookup_); + return LoadResult(map_); } @@ -6009,9 +5999,8 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle map) { CallOptimization call_optimization(accessor); if (call_optimization.is_simple_api_call()) { CallOptimization::HolderLookup holder_lookup; - Handle receiver_map = this->map(); - api_holder_ = call_optimization.LookupHolderOfExpectedType( - receiver_map, &holder_lookup); + api_holder_ = + call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup); } } accessor_ = accessor; @@ -6069,7 +6058,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { JSObject::TryMigrateInstance(holder_); } map = Handle(holder_->map()); - if (!CanInlinePropertyAccess(ToType(map))) { + if (!CanInlinePropertyAccess(map)) { lookup_.NotFound(); return false; } @@ -6082,10 +6071,9 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { - if (!CanInlinePropertyAccess(type_)) return false; + if (!CanInlinePropertyAccess(map_)) return false; if (IsJSObjectFieldAccessor()) return IsLoad(); - if (this->map()->function_with_prototype() && - !this->map()->has_non_instance_prototype() && + if (map_->function_with_prototype() && !map_->has_non_instance_prototype() && name_.is_identical_to(isolate()->factory()->prototype_string())) { return IsLoad(); } @@ -6095,18 +6083,17 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { if (IsLoad()) return true; if (IsAccessorConstant()) return true; - Handle map = this->map(); - map->LookupTransition(NULL, *name_, NONE, &lookup_); - if (lookup_.IsTransitionToData() && map->unused_property_fields() > 0) { + map_->LookupTransition(NULL, *name_, NONE, &lookup_); + if (lookup_.IsTransitionToData() && map_->unused_property_fields() > 0) { // Construct the object field access. int descriptor = transition()->LastAdded(); int index = transition()->instance_descriptors()->GetFieldIndex(descriptor) - - map->inobject_properties(); + map_->inobject_properties(); PropertyDetails details = transition()->instance_descriptors()->GetDetails(descriptor); Representation representation = details.representation(); - access_ = HObjectAccess::ForField(map, index, representation, name_); + access_ = HObjectAccess::ForField(map_, index, representation, name_); // Load field map for heap objects. LoadFieldMaps(transition()); @@ -6117,17 +6104,16 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( - SmallMapList* types) { - DCHECK(type_->Is(ToType(types->first()))); + SmallMapList* maps) { + DCHECK(map_.is_identical_to(maps->first())); if (!CanAccessMonomorphic()) return false; STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); - if (types->length() > kMaxLoadPolymorphism) return false; + if (maps->length() > kMaxLoadPolymorphism) return false; HObjectAccess access = HObjectAccess::ForMap(); // bogus default if (GetJSObjectFieldAccess(&access)) { - for (int i = 1; i < types->length(); ++i) { - PropertyAccessInfo test_info( - builder_, access_type_, ToType(types->at(i)), name_); + for (int i = 1; i < maps->length(); ++i) { + PropertyAccessInfo test_info(builder_, access_type_, maps->at(i), name_); HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default if (!test_info.GetJSObjectFieldAccess(&test_access)) return false; if (!access.Equals(test_access)) return false; @@ -6135,18 +6121,17 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( return true; } - // Currently only handle Type::Number as a polymorphic case. + // Currently only handle numbers as a polymorphic case. // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber // instruction. - if (type_->Is(Type::Number())) return false; + if (IsNumberType()) return false; // Multiple maps cannot transition to the same target map. DCHECK(!IsLoad() || !IsTransition()); - if (IsTransition() && types->length() > 1) return false; + if (IsTransition() && maps->length() > 1) return false; - for (int i = 1; i < types->length(); ++i) { - PropertyAccessInfo test_info( - builder_, access_type_, ToType(types->at(i)), name_); + for (int i = 1; i < maps->length(); ++i) { + PropertyAccessInfo test_info(builder_, access_type_, maps->at(i), name_); if (!test_info.IsCompatible(this)) return false; } @@ -6156,19 +6141,25 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( Handle HOptimizedGraphBuilder::PropertyAccessInfo::map() { JSFunction* ctor = IC::GetRootConstructor( - type_, current_info()->closure()->context()->native_context()); + *map_, current_info()->closure()->context()->native_context()); if (ctor != NULL) return handle(ctor->initial_map()); - return type_->AsClass()->Map(); + return map_; } -static bool NeedsWrappingFor(Type* type, Handle target) { - return type->Is(Type::NumberOrString()) && +static bool NeedsWrapping(Handle map, Handle target) { + return !map->IsJSObjectMap() && is_sloppy(target->shared()->language_mode()) && !target->shared()->native(); } +bool HOptimizedGraphBuilder::PropertyAccessInfo::NeedsWrappingFor( + Handle target) const { + return NeedsWrapping(map_, target); +} + + HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess( PropertyAccessInfo* info, HValue* object, @@ -6222,7 +6213,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess( Push(value); } - if (NeedsWrappingFor(info->type(), info->accessor())) { + if (info->NeedsWrappingFor(info->accessor())) { HValue* function = Add(info->accessor()); PushArgumentsFromEnvironment(argument_count); return New(function, argument_count, WRAP_AND_CALL); @@ -6248,13 +6239,8 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess( void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( - PropertyAccessType access_type, - Expression* expr, - BailoutId ast_id, - BailoutId return_id, - HValue* object, - HValue* value, - SmallMapList* types, + PropertyAccessType access_type, Expression* expr, BailoutId ast_id, + BailoutId return_id, HValue* object, HValue* value, SmallMapList* maps, Handle name) { // Something did not match; must use a polymorphic load. int count = 0; @@ -6265,33 +6251,33 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( bool handle_smi = false; STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); int i; - for (i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { - PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name); - if (info.type()->Is(Type::String())) { + for (i = 0; i < maps->length() && count < kMaxLoadPolymorphism; ++i) { + PropertyAccessInfo info(this, access_type, maps->at(i), name); + if (info.IsStringType()) { if (handled_string) continue; handled_string = true; } if (info.CanAccessMonomorphic()) { count++; - if (info.type()->Is(Type::Number())) { + if (info.IsNumberType()) { handle_smi = true; break; } } } - if (i < types->length()) { + if (i < maps->length()) { count = -1; - types->Clear(); + maps->Clear(); } else { count = 0; } HControlInstruction* smi_check = NULL; handled_string = false; - for (i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { - PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name); - if (info.type()->Is(Type::String())) { + for (i = 0; i < maps->length() && count < kMaxLoadPolymorphism; ++i) { + PropertyAccessInfo info(this, access_type, maps->at(i), name); + if (info.IsStringType()) { if (handled_string) continue; handled_string = true; } @@ -6318,11 +6304,11 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( HUnaryControlInstruction* compare; HValue* dependency; - if (info.type()->Is(Type::Number())) { + if (info.IsNumberType()) { Handle heap_number_map = isolate()->factory()->heap_number_map(); compare = New(object, heap_number_map, if_true, if_false); dependency = smi_check; - } else if (info.type()->Is(Type::String())) { + } else if (info.IsStringType()) { compare = New(object, if_true, if_false); dependency = compare; } else { @@ -6331,7 +6317,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( } FinishCurrentBlock(compare); - if (info.type()->Is(Type::Number())) { + if (info.IsNumberType()) { GotoNoSimulate(if_true, number_block); if_true = number_block; } @@ -6366,7 +6352,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( // Finish up. Unconditionally deoptimize if we've handled all the maps we // know about and do not want to handle ones we've never seen. Otherwise // use a generic IC. - if (count == types->length() && FLAG_deoptimize_uncommon_cases) { + if (count == maps->length() && FLAG_deoptimize_uncommon_cases) { FinishExitWithHardDeoptimization( Deoptimizer::kUnknownMapInPolymorphicAccess); } else { @@ -6399,22 +6385,21 @@ static bool ComputeReceiverTypes(Expression* expr, HValue* receiver, SmallMapList** t, Zone* zone) { - SmallMapList* types = expr->GetReceiverTypes(); - *t = types; + SmallMapList* maps = expr->GetReceiverTypes(); + *t = maps; bool monomorphic = expr->IsMonomorphic(); - if (types != NULL && receiver->HasMonomorphicJSObjectType()) { + if (maps != NULL && receiver->HasMonomorphicJSObjectType()) { Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); - types->FilterForPossibleTransitions(root_map); - monomorphic = types->length() == 1; + maps->FilterForPossibleTransitions(root_map); + monomorphic = maps->length() == 1; } - return monomorphic && - CanInlinePropertyAccess(IC::MapToType(types->first(), zone)); + return monomorphic && CanInlinePropertyAccess(maps->first()); } -static bool AreStringTypes(SmallMapList* types) { - for (int i = 0; i < types->length(); i++) { - if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; +static bool AreStringTypes(SmallMapList* maps) { + for (int i = 0; i < maps->length(); i++) { + if (maps->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; } return true; } @@ -7191,8 +7176,8 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( DCHECK(!expr->IsPropertyName()); HInstruction* instr = NULL; - SmallMapList* types; - bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone()); + SmallMapList* maps; + bool monomorphic = ComputeReceiverTypes(expr, obj, &maps, zone()); bool force_generic = false; if (expr->GetKeyType() == PROPERTY) { @@ -7202,13 +7187,13 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( force_generic = true; monomorphic = false; } else if (access_type == STORE && - (monomorphic || (types != NULL && !types->is_empty()))) { + (monomorphic || (maps != NULL && !maps->is_empty()))) { // Stores can't be mono/polymorphic if their prototype chain has dictionary // elements. However a receiver map that has dictionary elements itself // should be left to normal mono/poly behavior (the other maps may benefit // from highly optimized stores). - for (int i = 0; i < types->length(); i++) { - Handle current_map = types->at(i); + for (int i = 0; i < maps->length(); i++) { + Handle current_map = maps->at(i); if (current_map->DictionaryElementsInPrototypeChainOnly()) { force_generic = true; monomorphic = false; @@ -7216,13 +7201,13 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( } } } else if (access_type == LOAD && !monomorphic && - (types != NULL && !types->is_empty())) { + (maps != NULL && !maps->is_empty())) { // Polymorphic loads have to go generic if any of the maps are strings. // If some, but not all of the maps are strings, we should go generic // because polymorphic access wants to key on ElementsKind and isn't // compatible with strings. - for (int i = 0; i < types->length(); i++) { - Handle current_map = types->at(i); + for (int i = 0; i < maps->length(); i++) { + Handle current_map = maps->at(i); if (current_map->IsStringMap()) { force_generic = true; break; @@ -7231,7 +7216,7 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( } if (monomorphic) { - Handle map = types->first(); + Handle map = maps->first(); if (!CanInlineElementAccess(map)) { instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key, val)); @@ -7240,10 +7225,10 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( instr = BuildMonomorphicElementAccess( obj, key, val, NULL, map, access_type, expr->GetStoreMode()); } - } else if (!force_generic && (types != NULL && !types->is_empty())) { - return HandlePolymorphicElementAccess( - expr, obj, key, val, types, access_type, - expr->GetStoreMode(), has_side_effects); + } else if (!force_generic && (maps != NULL && !maps->is_empty())) { + return HandlePolymorphicElementAccess(expr, obj, key, val, maps, + access_type, expr->GetStoreMode(), + has_side_effects); } else { if (access_type == STORE) { if (expr->IsAssignment() && @@ -7352,27 +7337,27 @@ HInstruction* HOptimizedGraphBuilder::BuildNamedAccess( Handle name, HValue* value, bool is_uninitialized) { - SmallMapList* types; - ComputeReceiverTypes(expr, object, &types, zone()); - DCHECK(types != NULL); - - if (types->length() > 0) { - PropertyAccessInfo info(this, access, ToType(types->first()), name); - if (!info.CanAccessAsMonomorphic(types)) { - HandlePolymorphicNamedFieldAccess( - access, expr, ast_id, return_id, object, value, types, name); + SmallMapList* maps; + ComputeReceiverTypes(expr, object, &maps, zone()); + DCHECK(maps != NULL); + + if (maps->length() > 0) { + PropertyAccessInfo info(this, access, maps->first(), name); + if (!info.CanAccessAsMonomorphic(maps)) { + HandlePolymorphicNamedFieldAccess(access, expr, ast_id, return_id, object, + value, maps, name); return NULL; } HValue* checked_object; // Type::Number() is only supported by polymorphic load/call handling. - DCHECK(!info.type()->Is(Type::Number())); + DCHECK(!info.IsNumberType()); BuildCheckHeapObject(object); - if (AreStringTypes(types)) { + if (AreStringTypes(maps)) { checked_object = Add(object, HCheckInstanceType::IS_STRING); } else { - checked_object = Add(object, types); + checked_object = Add(object, maps); } return BuildMonomorphicAccess( &info, object, checked_object, value, ast_id, return_id); @@ -7562,11 +7547,10 @@ inline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) { } -void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( - Call* expr, - HValue* receiver, - SmallMapList* types, - Handle name) { +void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(Call* expr, + HValue* receiver, + SmallMapList* maps, + Handle name) { int argument_count = expr->arguments()->length() + 1; // Includes receiver. FunctionSorter order[kMaxCallPolymorphism]; @@ -7575,17 +7559,17 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( int ordered_functions = 0; int i; - for (i = 0; i < types->length() && ordered_functions < kMaxCallPolymorphism; + for (i = 0; i < maps->length() && ordered_functions < kMaxCallPolymorphism; ++i) { - PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); + PropertyAccessInfo info(this, LOAD, maps->at(i), name); if (info.CanAccessMonomorphic() && info.IsDataConstant() && info.constant()->IsJSFunction()) { - if (info.type()->Is(Type::String())) { + if (info.IsStringType()) { if (handled_string) continue; handled_string = true; } Handle target = Handle::cast(info.constant()); - if (info.type()->Is(Type::Number())) { + if (info.IsNumberType()) { handle_smi = true; } expr->set_target(target); @@ -7596,8 +7580,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( std::sort(order, order + ordered_functions); - if (i < types->length()) { - types->Clear(); + if (i < maps->length()) { + maps->Clear(); ordered_functions = -1; } @@ -7608,8 +7592,8 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( for (int fn = 0; fn < ordered_functions; ++fn) { int i = order[fn].index(); - PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); - if (info.type()->Is(Type::String())) { + PropertyAccessInfo info(this, LOAD, maps->at(i), name); + if (info.IsStringType()) { if (handled_string) continue; handled_string = true; } @@ -7639,17 +7623,17 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( HUnaryControlInstruction* compare; Handle map = info.map(); - if (info.type()->Is(Type::Number())) { + if (info.IsNumberType()) { Handle heap_number_map = isolate()->factory()->heap_number_map(); compare = New(receiver, heap_number_map, if_true, if_false); - } else if (info.type()->Is(Type::String())) { + } else if (info.IsStringType()) { compare = New(receiver, if_true, if_false); } else { compare = New(receiver, map, if_true, if_false); } FinishCurrentBlock(compare); - if (info.type()->Is(Type::Number())) { + if (info.IsNumberType()) { GotoNoSimulate(if_true, number_block); if_true = number_block; } @@ -7662,7 +7646,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( environment()->SetExpressionStackAt(0, function); Push(receiver); CHECK_ALIVE(VisitExpressions(expr->arguments())); - bool needs_wrapping = NeedsWrappingFor(info.type(), target); + bool needs_wrapping = info.NeedsWrappingFor(target); bool try_inline = FLAG_polymorphic_inlining && !needs_wrapping; if (FLAG_trace_inlining && try_inline) { Handle caller = current_info()->closure(); @@ -7698,7 +7682,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( // Finish up. Unconditionally deoptimize if we've handled all the maps we // know about and do not want to handle ones we've never seen. Otherwise // use a generic IC. - if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { + if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); } else { Property* prop = expr->expression()->AsProperty(); @@ -9135,14 +9119,14 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { CHECK_ALIVE(VisitForValue(prop->obj())); HValue* receiver = Top(); - SmallMapList* types; - ComputeReceiverTypes(expr, receiver, &types, zone()); + SmallMapList* maps; + ComputeReceiverTypes(expr, receiver, &maps, zone()); - if (prop->key()->IsPropertyName() && types->length() > 0) { + if (prop->key()->IsPropertyName() && maps->length() > 0) { Handle name = prop->key()->AsLiteral()->AsPropertyName(); - PropertyAccessInfo info(this, LOAD, ToType(types->first()), name); - if (!info.CanAccessAsMonomorphic(types)) { - HandlePolymorphicCallNamed(expr, receiver, types, name); + PropertyAccessInfo info(this, LOAD, maps->first(), name); + if (!info.CanAccessAsMonomorphic(maps)) { + HandlePolymorphicCallNamed(expr, receiver, maps, name); return; } } @@ -9171,7 +9155,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { if (TryIndirectCall(expr)) return; CHECK_ALIVE(VisitExpressions(expr->arguments())); - Handle map = types->length() == 1 ? types->first() : Handle(); + Handle map = maps->length() == 1 ? maps->first() : Handle(); if (TryInlineBuiltinMethodCall(expr, known_function, map, expr->arguments()->length())) { if (FLAG_trace_inlining) { @@ -9181,10 +9165,10 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { } return; } - if (TryInlineApiMethodCall(expr, receiver, types)) return; + if (TryInlineApiMethodCall(expr, receiver, maps)) return; // Wrap the receiver if necessary. - if (NeedsWrappingFor(ToType(types->first()), known_function)) { + if (NeedsWrapping(maps->first(), known_function)) { // Since HWrapReceiver currently cannot actually wrap numbers and // strings, use the regular CallFunctionStub for method calls to wrap // the receiver. diff --git a/src/hydrogen.h b/src/hydrogen.h index cf53d26..8b1ba1c 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -2282,8 +2282,6 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { AST_NODE_LIST(DECLARE_VISIT) #undef DECLARE_VISIT - Type* ToType(Handle map); - private: // Helpers for flow graph construction. enum GlobalPropertyAccess { @@ -2434,16 +2432,15 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { class PropertyAccessInfo { public: PropertyAccessInfo(HOptimizedGraphBuilder* builder, - PropertyAccessType access_type, - Type* type, + PropertyAccessType access_type, Handle map, Handle name) : lookup_(builder->isolate()), builder_(builder), access_type_(access_type), - type_(type), + map_(map), name_(name), field_type_(HType::Tagged()), - access_(HObjectAccess::ForMap()) { } + access_(HObjectAccess::ForMap()) {} // Checkes whether this PropertyAccessInfo can be handled as a monomorphic // load named. It additionally fills in the fields necessary to generate the @@ -2458,22 +2455,23 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { // PropertyAccessInfo is built for types->first(). bool CanAccessAsMonomorphic(SmallMapList* types); + bool NeedsWrappingFor(Handle target) const; + Handle map(); - Type* type() const { return type_; } Handle name() const { return name_; } bool IsJSObjectFieldAccessor() { int offset; // unused - return Accessors::IsJSObjectFieldAccessor(type_, name_, &offset); + return Accessors::IsJSObjectFieldAccessor(map(), name_, &offset); } bool GetJSObjectFieldAccess(HObjectAccess* access) { int offset; - if (Accessors::IsJSObjectFieldAccessor(type_, name_, &offset)) { - if (type_->Is(Type::String())) { + if (Accessors::IsJSObjectFieldAccessor(map(), name_, &offset)) { + if (IsStringType()) { DCHECK(String::Equals(isolate()->factory()->length_string(), name_)); *access = HObjectAccess::ForStringLength(); - } else if (type_->Is(Type::Array())) { + } else if (IsArrayType()) { DCHECK(String::Equals(isolate()->factory()->length_string(), name_)); *access = HObjectAccess::ForArrayLength(map()->elements_kind()); } else { @@ -2506,6 +2504,11 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { bool IsConfigurable() const { return lookup_.IsConfigurable(); } bool IsReadOnly() const { return lookup_.IsReadOnly(); } + bool IsStringType() { return map_->instance_type() < FIRST_NONSTRING_TYPE; } + bool IsNumberType() { return map_->instance_type() == HEAP_NUMBER_TYPE; } + bool IsValueWrapped() { return IsStringType() || IsNumberType(); } + bool IsArrayType() { return map_->instance_type() == JS_ARRAY_TYPE; } + private: Handle GetAccessorsFromMap(Handle map) const { return handle(lookup_.GetValueFromMap(*map), isolate()); @@ -2524,7 +2527,6 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { } Representation representation() const { return lookup_.representation(); } - Type* ToType(Handle map) { return builder_->ToType(map); } Zone* zone() { return builder_->zone(); } CompilationInfo* top_info() { return builder_->top_info(); } CompilationInfo* current_info() { return builder_->current_info(); } @@ -2543,7 +2545,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { LookupResult lookup_; HOptimizedGraphBuilder* builder_; PropertyAccessType access_type_; - Type* type_; + Handle map_; Handle name_; Handle holder_; Handle accessor_; diff --git a/src/ic/arm/handler-compiler-arm.cc b/src/ic/arm/handler-compiler-arm.cc index 908f6f0..c0a808c 100644 --- a/src/ic/arm/handler-compiler-arm.cc +++ b/src/ic/arm/handler-compiler-arm.cc @@ -17,9 +17,8 @@ namespace internal { void NamedLoadHandlerCompiler::GenerateLoadViaGetter( - MacroAssembler* masm, Handle type, Register receiver, - Register holder, int accessor_index, int expected_arguments, - Register scratch) { + MacroAssembler* masm, Handle map, Register receiver, Register holder, + int accessor_index, int expected_arguments, Register scratch) { // ----------- S t a t e ------------- // -- r0 : receiver // -- r2 : name @@ -32,7 +31,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter( DCHECK(!holder.is(scratch)); DCHECK(!receiver.is(scratch)); // Call the JavaScript getter with the receiver on the stack. - if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + if (map->IsJSGlobalObjectMap()) { // Swap in the global receiver. __ ldr(scratch, FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); @@ -57,9 +56,8 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter( void NamedStoreHandlerCompiler::GenerateStoreViaSetter( - MacroAssembler* masm, Handle type, Register receiver, - Register holder, int accessor_index, int expected_arguments, - Register scratch) { + MacroAssembler* masm, Handle map, Register receiver, Register holder, + int accessor_index, int expected_arguments, Register scratch) { // ----------- S t a t e ------------- // -- lr : return address // ----------------------------------- @@ -74,7 +72,7 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( DCHECK(!receiver.is(scratch)); DCHECK(!value().is(scratch)); // Call the JavaScript setter with receiver and value on the stack. - if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + if (map->IsJSGlobalObjectMap()) { // Swap in the global receiver. __ ldr(scratch, FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); @@ -415,7 +413,7 @@ Register PropertyHandlerCompiler::CheckPrototypes( Register object_reg, Register holder_reg, Register scratch1, Register scratch2, Handle name, Label* miss, PrototypeCheckType check) { - Handle receiver_map(IC::TypeToMap(*type(), isolate())); + Handle receiver_map = map(); // Make sure there's no overlap between holder and object registers. DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); @@ -427,8 +425,8 @@ Register PropertyHandlerCompiler::CheckPrototypes( int depth = 0; Handle current = Handle::null(); - if (type()->IsConstant()) { - current = Handle::cast(type()->AsConstant()->Value()); + if (receiver_map->IsJSGlobalObjectMap()) { + current = isolate()->global_object(); } Handle prototype = Handle::null(); Handle current_map = receiver_map; diff --git a/src/ic/arm/ic-compiler-arm.cc b/src/ic/arm/ic-compiler-arm.cc index 75c1654..c5c0b70 100644 --- a/src/ic/arm/ic-compiler-arm.cc +++ b/src/ic/arm/ic-compiler-arm.cc @@ -32,7 +32,7 @@ void PropertyICCompiler::GenerateRuntimeSetProperty( #define __ ACCESS_MASM(masm()) -Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, +Handle PropertyICCompiler::CompilePolymorphic(MapHandleList* maps, CodeHandleList* handlers, Handle name, Code::StubType type, @@ -59,7 +59,7 @@ Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, } Label number_case; - Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; + Label* smi_target = IncludesNumberMap(maps) ? &number_case : &miss; __ JumpIfSmi(receiver(), smi_target); // Polymorphic keyed stores may use the map register @@ -67,17 +67,16 @@ Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, DCHECK(kind() != Code::KEYED_STORE_IC || map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister())); - int receiver_count = types->length(); + int receiver_count = maps->length(); int number_of_handled_maps = 0; __ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); for (int current = 0; current < receiver_count; ++current) { - Handle type = types->at(current); - Handle map = IC::TypeToMap(*type, isolate()); + Handle map = maps->at(current); if (!map->is_deprecated()) { number_of_handled_maps++; Handle cell = Map::WeakCellForMap(map); __ CmpWeakValue(map_reg, cell, scratch2()); - if (type->Is(HeapType::Number())) { + if (map->instance_type() == HEAP_NUMBER_TYPE) { DCHECK(!number_case.is_unused()); __ bind(&number_case); } diff --git a/src/ic/arm64/handler-compiler-arm64.cc b/src/ic/arm64/handler-compiler-arm64.cc index 4ec1a57..7b3fdec 100644 --- a/src/ic/arm64/handler-compiler-arm64.cc +++ b/src/ic/arm64/handler-compiler-arm64.cc @@ -223,9 +223,8 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( void NamedStoreHandlerCompiler::GenerateStoreViaSetter( - MacroAssembler* masm, Handle type, Register receiver, - Register holder, int accessor_index, int expected_arguments, - Register scratch) { + MacroAssembler* masm, Handle map, Register receiver, Register holder, + int accessor_index, int expected_arguments, Register scratch) { // ----------- S t a t e ------------- // -- lr : return address // ----------------------------------- @@ -241,7 +240,7 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( DCHECK(!AreAliased(receiver, scratch)); DCHECK(!AreAliased(value(), scratch)); // Call the JavaScript setter with receiver and value on the stack. - if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + if (map->IsJSGlobalObjectMap()) { // Swap in the global receiver. __ Ldr(scratch, FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); @@ -269,9 +268,8 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( void NamedLoadHandlerCompiler::GenerateLoadViaGetter( - MacroAssembler* masm, Handle type, Register receiver, - Register holder, int accessor_index, int expected_arguments, - Register scratch) { + MacroAssembler* masm, Handle map, Register receiver, Register holder, + int accessor_index, int expected_arguments, Register scratch) { { FrameScope scope(masm, StackFrame::INTERNAL); @@ -279,7 +277,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter( DCHECK(!AreAliased(holder, scratch)); DCHECK(!AreAliased(receiver, scratch)); // Call the JavaScript getter with the receiver on the stack. - if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + if (map->IsJSGlobalObjectMap()) { // Swap in the global receiver. __ Ldr(scratch, FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); @@ -465,7 +463,7 @@ Register PropertyHandlerCompiler::CheckPrototypes( Register object_reg, Register holder_reg, Register scratch1, Register scratch2, Handle name, Label* miss, PrototypeCheckType check) { - Handle receiver_map(IC::TypeToMap(*type(), isolate())); + Handle receiver_map = map(); // object_reg and holder_reg registers can alias. DCHECK(!AreAliased(object_reg, scratch1, scratch2)); @@ -476,8 +474,8 @@ Register PropertyHandlerCompiler::CheckPrototypes( int depth = 0; Handle current = Handle::null(); - if (type()->IsConstant()) { - current = Handle::cast(type()->AsConstant()->Value()); + if (receiver_map->IsJSGlobalObjectMap()) { + current = isolate()->global_object(); } Handle prototype = Handle::null(); Handle current_map = receiver_map; diff --git a/src/ic/arm64/ic-compiler-arm64.cc b/src/ic/arm64/ic-compiler-arm64.cc index 6883374..08ce4cb 100644 --- a/src/ic/arm64/ic-compiler-arm64.cc +++ b/src/ic/arm64/ic-compiler-arm64.cc @@ -33,7 +33,7 @@ void PropertyICCompiler::GenerateRuntimeSetProperty( #define __ ACCESS_MASM(masm()) -Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, +Handle PropertyICCompiler::CompilePolymorphic(MapHandleList* maps, CodeHandleList* handlers, Handle name, Code::StubType type, @@ -59,7 +59,7 @@ Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, } Label number_case; - Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; + Label* smi_target = IncludesNumberMap(maps) ? &number_case : &miss; __ JumpIfSmi(receiver(), smi_target); // Polymorphic keyed stores may use the map register @@ -67,18 +67,17 @@ Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, DCHECK(kind() != Code::KEYED_STORE_IC || map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister())); __ Ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); - int receiver_count = types->length(); + int receiver_count = maps->length(); int number_of_handled_maps = 0; for (int current = 0; current < receiver_count; ++current) { - Handle type = types->at(current); - Handle map = IC::TypeToMap(*type, isolate()); + Handle map = maps->at(current); if (!map->is_deprecated()) { number_of_handled_maps++; Handle cell = Map::WeakCellForMap(map); __ CmpWeakValue(map_reg, cell, scratch2()); Label try_next; __ B(ne, &try_next); - if (type->Is(HeapType::Number())) { + if (map->instance_type() == HEAP_NUMBER_TYPE) { DCHECK(!number_case.is_unused()); __ Bind(&number_case); } diff --git a/src/ic/call-optimization.cc b/src/ic/call-optimization.cc index 5d7ef7b..85dc01a 100644 --- a/src/ic/call-optimization.cc +++ b/src/ic/call-optimization.cc @@ -51,12 +51,12 @@ bool CallOptimization::IsCompatibleReceiver(Handle receiver, DCHECK(is_simple_api_call()); if (!receiver->IsHeapObject()) return false; Handle map(HeapObject::cast(*receiver)->map()); - return IsCompatibleReceiverType(map, holder); + return IsCompatibleReceiverMap(map, holder); } -bool CallOptimization::IsCompatibleReceiverType(Handle map, - Handle holder) const { +bool CallOptimization::IsCompatibleReceiverMap(Handle map, + Handle holder) const { HolderLookup holder_lookup; Handle api_holder = LookupHolderOfExpectedType(map, &holder_lookup); switch (holder_lookup) { diff --git a/src/ic/call-optimization.h b/src/ic/call-optimization.h index 990a755..01947d7 100644 --- a/src/ic/call-optimization.h +++ b/src/ic/call-optimization.h @@ -46,8 +46,8 @@ class CallOptimization BASE_EMBEDDED { Handle holder) const; // Check if the api holder is between the receiver and the holder. - bool IsCompatibleReceiverType(Handle receiver_map, - Handle holder) const; + bool IsCompatibleReceiverMap(Handle receiver_map, + Handle holder) const; private: void Initialize(Handle function); diff --git a/src/ic/handler-compiler.cc b/src/ic/handler-compiler.cc index 4b253af..acf380f 100644 --- a/src/ic/handler-compiler.cc +++ b/src/ic/handler-compiler.cc @@ -26,9 +26,8 @@ Handle PropertyHandlerCompiler::Find(Handle name, Handle NamedLoadHandlerCompiler::ComputeLoadNonexistent( - Handle name, Handle type) { + Handle name, Handle receiver_map) { Isolate* isolate = name->GetIsolate(); - Handle receiver_map = IC::TypeToMap(*type, isolate); if (receiver_map->prototype()->IsNull()) { // TODO(jkummerow/verwaest): If there is no prototype and the property // is nonexistent, introduce a builtin to handle this (fast properties @@ -37,7 +36,7 @@ Handle NamedLoadHandlerCompiler::ComputeLoadNonexistent( } CacheHolderFlag flag; Handle stub_holder_map = - IC::GetHandlerCacheHolder(*type, false, isolate, &flag); + IC::GetHandlerCacheHolder(receiver_map, false, isolate, &flag); // If no dictionary mode objects are present in the prototype chain, the load // nonexistent IC stub can be shared for all names for a given map and we use @@ -62,7 +61,7 @@ Handle NamedLoadHandlerCompiler::ComputeLoadNonexistent( cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST); if (!handler.is_null()) return handler; - NamedLoadHandlerCompiler compiler(isolate, type, last, flag); + NamedLoadHandlerCompiler compiler(isolate, receiver_map, last, flag); handler = compiler.CompileLoadNonexistent(cache_name); Map::UpdateCodeCache(stub_holder_map, cache_name, handler); return handler; @@ -82,11 +81,6 @@ Handle PropertyHandlerCompiler::GetCode(Code::Kind kind, } -void PropertyHandlerCompiler::set_type_for_object(Handle object) { - type_ = IC::CurrentTypeOf(object, isolate()); -} - - #define __ ACCESS_MASM(masm()) @@ -95,13 +89,13 @@ Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg, Label* miss) { PrototypeCheckType check_type = CHECK_ALL_MAPS; int function_index = -1; - if (type()->Is(HeapType::String())) { + if (map()->instance_type() < FIRST_NONSTRING_TYPE) { function_index = Context::STRING_FUNCTION_INDEX; - } else if (type()->Is(HeapType::Symbol())) { + } else if (map()->instance_type() == SYMBOL_TYPE) { function_index = Context::SYMBOL_FUNCTION_INDEX; - } else if (type()->Is(HeapType::Number())) { + } else if (map()->instance_type() == HEAP_NUMBER_TYPE) { function_index = Context::NUMBER_FUNCTION_INDEX; - } else if (type()->Is(HeapType::Boolean())) { + } else if (*map() == isolate()->heap()->boolean_map()) { function_index = Context::BOOLEAN_FUNCTION_INDEX; } else { check_type = SKIP_RECEIVER; @@ -112,7 +106,8 @@ Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg, scratch1(), miss); Object* function = isolate()->native_context()->get(function_index); Object* prototype = JSFunction::cast(function)->instance_prototype(); - set_type_for_object(handle(prototype, isolate())); + Handle map(JSObject::cast(prototype)->map()); + set_map(map); object_reg = scratch1(); } @@ -155,7 +150,7 @@ void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle name, Handle last_map; if (holder().is_null()) { holder_reg = receiver(); - last_map = IC::TypeToMap(*type(), isolate()); + last_map = map(); // If |type| has null as its prototype, |holder()| is // Handle::null(). DCHECK(last_map->prototype() == isolate()->heap()->null_value()); @@ -168,7 +163,7 @@ void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle name, if (last_map->IsJSGlobalObjectMap()) { Handle global = holder().is_null() - ? Handle::cast(type()->AsConstant()->Value()) + ? Handle::cast(isolate()->global_object()) : Handle::cast(holder()); GenerateCheckPropertyCell(masm(), global, name, scratch1, miss); } else { @@ -236,8 +231,7 @@ Handle NamedLoadHandlerCompiler::CompileLoadCallback( int accessor_index) { DCHECK(call_optimization.is_simple_api_call()); Register holder = Frontend(name); - Handle receiver_map = IC::TypeToMap(*type(), isolate()); - GenerateApiAccessorCall(masm(), call_optimization, receiver_map, receiver(), + GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(), scratch2(), false, no_reg, holder, accessor_index); return GetCode(kind(), Code::FAST, name); } @@ -296,8 +290,8 @@ Handle NamedLoadHandlerCompiler::CompileLoadInterceptor( Handle info = Handle::cast(accessors); inline_followup = info->getter() != NULL && - ExecutableAccessorInfo::IsCompatibleReceiverType( - isolate(), info, type()); + ExecutableAccessorInfo::IsCompatibleReceiverMap( + isolate(), info, map()); } else if (accessors->IsAccessorPair()) { Handle property_holder(it->GetHolder()); Handle getter(Handle::cast(accessors)->getter(), @@ -306,9 +300,9 @@ Handle NamedLoadHandlerCompiler::CompileLoadInterceptor( if (!property_holder->HasFastProperties()) break; auto function = Handle::cast(getter); CallOptimization call_optimization(function); - Handle receiver_map = IC::TypeToMap(*type(), isolate()); + Handle receiver_map = map(); inline_followup = call_optimization.is_simple_api_call() && - call_optimization.IsCompatibleReceiverType( + call_optimization.IsCompatibleReceiverMap( receiver_map, property_holder); } } @@ -335,7 +329,8 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( LookupIterator* it, Register interceptor_reg) { Handle real_named_property_holder(it->GetHolder()); - set_type_for_object(holder()); + Handle holder_map(holder()->map()); + set_map(holder_map); set_holder(real_named_property_holder); Label miss; @@ -369,8 +364,7 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( auto function = handle(JSFunction::cast( AccessorPair::cast(*it->GetAccessors())->getter())); CallOptimization call_optimization(function); - Handle receiver_map = IC::TypeToMap(*type(), isolate()); - GenerateApiAccessorCall(masm(), call_optimization, receiver_map, + GenerateApiAccessorCall(masm(), call_optimization, holder_map, receiver(), scratch2(), false, no_reg, reg, it->GetAccessorIndex()); } @@ -381,7 +375,7 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( Handle NamedLoadHandlerCompiler::CompileLoadViaGetter( Handle name, int accessor_index, int expected_arguments) { Register holder = Frontend(name); - GenerateLoadViaGetter(masm(), type(), receiver(), holder, accessor_index, + GenerateLoadViaGetter(masm(), map(), receiver(), holder, accessor_index, expected_arguments, scratch2()); return GetCode(kind(), Code::FAST, name); } @@ -471,7 +465,7 @@ Handle NamedStoreHandlerCompiler::CompileStoreViaSetter( Handle object, Handle name, int accessor_index, int expected_arguments) { Register holder = Frontend(name); - GenerateStoreViaSetter(masm(), type(), receiver(), holder, accessor_index, + GenerateStoreViaSetter(masm(), map(), receiver(), holder, accessor_index, expected_arguments, scratch2()); return GetCode(kind(), Code::FAST, name); diff --git a/src/ic/handler-compiler.h b/src/ic/handler-compiler.h index d1d5bec..dd3b483 100644 --- a/src/ic/handler-compiler.h +++ b/src/ic/handler-compiler.h @@ -21,11 +21,10 @@ class PropertyHandlerCompiler : public PropertyAccessCompiler { CacheHolderFlag cache_holder, Code::StubType type); protected: - PropertyHandlerCompiler(Isolate* isolate, Code::Kind kind, - Handle type, Handle holder, - CacheHolderFlag cache_holder) + PropertyHandlerCompiler(Isolate* isolate, Code::Kind kind, Handle map, + Handle holder, CacheHolderFlag cache_holder) : PropertyAccessCompiler(isolate, kind, cache_holder), - type_(type), + map_(map), holder_(holder) {} virtual ~PropertyHandlerCompiler() {} @@ -99,23 +98,23 @@ class PropertyHandlerCompiler : public PropertyAccessCompiler { PrototypeCheckType check = CHECK_ALL_MAPS); Handle GetCode(Code::Kind kind, Code::StubType type, Handle name); - void set_type_for_object(Handle object); void set_holder(Handle holder) { holder_ = holder; } - Handle type() const { return type_; } + Handle map() const { return map_; } + void set_map(Handle map) { map_ = map; } Handle holder() const { return holder_; } private: - Handle type_; + Handle map_; Handle holder_; }; class NamedLoadHandlerCompiler : public PropertyHandlerCompiler { public: - NamedLoadHandlerCompiler(Isolate* isolate, Handle type, + NamedLoadHandlerCompiler(Isolate* isolate, Handle map, Handle holder, CacheHolderFlag cache_holder) - : PropertyHandlerCompiler(isolate, Code::LOAD_IC, type, holder, + : PropertyHandlerCompiler(isolate, Code::LOAD_IC, map, holder, cache_holder) {} virtual ~NamedLoadHandlerCompiler() {} @@ -144,16 +143,16 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler { // Static interface static Handle ComputeLoadNonexistent(Handle name, - Handle type); + Handle map); - static void GenerateLoadViaGetter(MacroAssembler* masm, Handle type, + static void GenerateLoadViaGetter(MacroAssembler* masm, Handle map, Register receiver, Register holder, int accessor_index, int expected_arguments, Register scratch); static void GenerateLoadViaGetterForDeopt(MacroAssembler* masm) { - GenerateLoadViaGetter(masm, Handle::null(), no_reg, no_reg, -1, - -1, no_reg); + GenerateLoadViaGetter(masm, Handle::null(), no_reg, no_reg, -1, -1, + no_reg); } static void GenerateLoadFunctionPrototype(MacroAssembler* masm, @@ -213,9 +212,9 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler { class NamedStoreHandlerCompiler : public PropertyHandlerCompiler { public: - explicit NamedStoreHandlerCompiler(Isolate* isolate, Handle type, + explicit NamedStoreHandlerCompiler(Isolate* isolate, Handle map, Handle holder) - : PropertyHandlerCompiler(isolate, Code::STORE_IC, type, holder, + : PropertyHandlerCompiler(isolate, Code::STORE_IC, map, holder, kCacheOnReceiver) {} virtual ~NamedStoreHandlerCompiler() {} @@ -233,14 +232,14 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler { int expected_arguments); Handle CompileStoreInterceptor(Handle name); - static void GenerateStoreViaSetter(MacroAssembler* masm, - Handle type, Register receiver, - Register holder, int accessor_index, - int expected_arguments, Register scratch); + static void GenerateStoreViaSetter(MacroAssembler* masm, Handle map, + Register receiver, Register holder, + int accessor_index, int expected_arguments, + Register scratch); static void GenerateStoreViaSetterForDeopt(MacroAssembler* masm) { - GenerateStoreViaSetter(masm, Handle::null(), no_reg, no_reg, -1, - -1, no_reg); + GenerateStoreViaSetter(masm, Handle::null(), no_reg, no_reg, -1, -1, + no_reg); } static void GenerateSlow(MacroAssembler* masm); @@ -284,8 +283,8 @@ class ElementHandlerCompiler : public PropertyHandlerCompiler { public: explicit ElementHandlerCompiler(Isolate* isolate) : PropertyHandlerCompiler(isolate, Code::KEYED_LOAD_IC, - Handle::null(), - Handle::null(), kCacheOnReceiver) {} + Handle::null(), Handle::null(), + kCacheOnReceiver) {} virtual ~ElementHandlerCompiler() {} diff --git a/src/ic/ia32/handler-compiler-ia32.cc b/src/ic/ia32/handler-compiler-ia32.cc index d5221cb..d4a8a1f 100644 --- a/src/ic/ia32/handler-compiler-ia32.cc +++ b/src/ic/ia32/handler-compiler-ia32.cc @@ -17,9 +17,8 @@ namespace internal { void NamedLoadHandlerCompiler::GenerateLoadViaGetter( - MacroAssembler* masm, Handle type, Register receiver, - Register holder, int accessor_index, int expected_arguments, - Register scratch) { + MacroAssembler* masm, Handle map, Register receiver, Register holder, + int accessor_index, int expected_arguments, Register scratch) { { FrameScope scope(masm, StackFrame::INTERNAL); @@ -27,7 +26,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter( DCHECK(!holder.is(scratch)); DCHECK(!receiver.is(scratch)); // Call the JavaScript getter with the receiver on the stack. - if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + if (map->IsJSGlobalObjectMap()) { // Swap in the global receiver. __ mov(scratch, FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); @@ -237,9 +236,8 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell( void NamedStoreHandlerCompiler::GenerateStoreViaSetter( - MacroAssembler* masm, Handle type, Register receiver, - Register holder, int accessor_index, int expected_arguments, - Register scratch) { + MacroAssembler* masm, Handle map, Register receiver, Register holder, + int accessor_index, int expected_arguments, Register scratch) { // ----------- S t a t e ------------- // -- esp[0] : return address // ----------------------------------- @@ -254,7 +252,7 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( DCHECK(!receiver.is(scratch)); DCHECK(!value().is(scratch)); // Call the JavaScript setter with receiver and value on the stack. - if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + if (map->IsJSGlobalObjectMap()) { __ mov(scratch, FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); receiver = scratch; @@ -418,7 +416,7 @@ Register PropertyHandlerCompiler::CheckPrototypes( Register object_reg, Register holder_reg, Register scratch1, Register scratch2, Handle name, Label* miss, PrototypeCheckType check) { - Handle receiver_map(IC::TypeToMap(*type(), isolate())); + Handle receiver_map = map(); // Make sure there's no overlap between holder and object registers. DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); @@ -430,8 +428,9 @@ Register PropertyHandlerCompiler::CheckPrototypes( int depth = 0; Handle current = Handle::null(); - if (type()->IsConstant()) - current = Handle::cast(type()->AsConstant()->Value()); + if (receiver_map->IsJSGlobalObjectMap()) { + current = isolate()->global_object(); + } Handle prototype = Handle::null(); Handle current_map = receiver_map; Handle holder_map(holder()->map()); diff --git a/src/ic/ia32/ic-compiler-ia32.cc b/src/ic/ia32/ic-compiler-ia32.cc index 076a2ac..6788bc7 100644 --- a/src/ic/ia32/ic-compiler-ia32.cc +++ b/src/ic/ia32/ic-compiler-ia32.cc @@ -36,7 +36,7 @@ void PropertyICCompiler::GenerateRuntimeSetProperty( #undef __ #define __ ACCESS_MASM(masm()) -Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, +Handle PropertyICCompiler::CompilePolymorphic(MapHandleList* maps, CodeHandleList* handlers, Handle name, Code::StubType type, @@ -63,7 +63,7 @@ Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, } Label number_case; - Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; + Label* smi_target = IncludesNumberMap(maps) ? &number_case : &miss; __ JumpIfSmi(receiver(), smi_target); // Polymorphic keyed stores may use the map register @@ -71,16 +71,15 @@ Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, DCHECK(kind() != Code::KEYED_STORE_IC || map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister())); __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); - int receiver_count = types->length(); + int receiver_count = maps->length(); int number_of_handled_maps = 0; for (int current = 0; current < receiver_count; ++current) { - Handle type = types->at(current); - Handle map = IC::TypeToMap(*type, isolate()); + Handle map = maps->at(current); if (!map->is_deprecated()) { number_of_handled_maps++; Handle cell = Map::WeakCellForMap(map); __ CmpWeakValue(map_reg, cell, scratch2()); - if (type->Is(HeapType::Number())) { + if (map->instance_type() == HEAP_NUMBER_TYPE) { DCHECK(!number_case.is_unused()); __ bind(&number_case); } diff --git a/src/ic/ic-compiler.cc b/src/ic/ic-compiler.cc index f69a1f4..08e0fa6 100644 --- a/src/ic/ic-compiler.cc +++ b/src/ic/ic-compiler.cc @@ -25,30 +25,30 @@ Handle PropertyICCompiler::Find(Handle name, } -bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) { - for (int i = 0; i < types->length(); ++i) { - if (types->at(i)->Is(HeapType::Number())) return true; +bool PropertyICCompiler::IncludesNumberMap(MapHandleList* maps) { + for (int i = 0; i < maps->length(); ++i) { + if (maps->at(i)->instance_type() == HEAP_NUMBER_TYPE) return true; } return false; } -Handle PropertyICCompiler::CompileMonomorphic(Handle type, +Handle PropertyICCompiler::CompileMonomorphic(Handle map, Handle handler, Handle name, IcCheckType check) { - TypeHandleList types(1); + MapHandleList maps(1); CodeHandleList handlers(1); - types.Add(type); + maps.Add(map); handlers.Add(handler); Code::StubType stub_type = handler->type(); - return CompilePolymorphic(&types, &handlers, name, stub_type, check); + return CompilePolymorphic(&maps, &handlers, name, stub_type, check); } Handle PropertyICCompiler::ComputeMonomorphic( - Code::Kind kind, Handle name, Handle type, - Handle handler, ExtraICState extra_ic_state) { + Code::Kind kind, Handle name, Handle map, Handle handler, + ExtraICState extra_ic_state) { Isolate* isolate = name->GetIsolate(); if (handler.is_identical_to(isolate->builtins()->LoadIC_Normal()) || handler.is_identical_to(isolate->builtins()->StoreIC_Normal())) { @@ -56,7 +56,7 @@ Handle PropertyICCompiler::ComputeMonomorphic( } CacheHolderFlag flag; - Handle stub_holder = IC::GetICCacheHolder(*type, isolate, &flag); + Handle stub_holder = IC::GetICCacheHolder(map, isolate, &flag); if (kind == Code::KEYED_STORE_IC) { // Always set the "property" bit. extra_ic_state = @@ -72,14 +72,14 @@ Handle PropertyICCompiler::ComputeMonomorphic( // There are multiple string maps that all use the same prototype. That // prototype cannot hold multiple handlers, one for each of the string maps, // for a single name. Hence, turn off caching of the IC. - bool can_be_cached = !type->Is(HeapType::String()); + bool can_be_cached = map->instance_type() >= FIRST_NONSTRING_TYPE; if (can_be_cached) { ic = Find(name, stub_holder, kind, extra_ic_state, flag); if (!ic.is_null()) return ic; } PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag); - ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY); + ic = ic_compiler.CompileMonomorphic(map, handler, name, PROPERTY); if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); return ic; @@ -98,9 +98,8 @@ Handle PropertyICCompiler::ComputeKeyedLoadMonomorphic( Handle stub = ComputeKeyedLoadMonomorphicHandler(receiver_map); PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC); - Handle code = - compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub, - isolate->factory()->empty_string(), ELEMENT); + Handle code = compiler.CompileMonomorphic( + receiver_map, stub, isolate->factory()->empty_string(), ELEMENT); Map::UpdateCodeCache(receiver_map, name, code); return code; @@ -256,7 +255,6 @@ Handle PropertyICCompiler::ComputeCompareNil(Handle receiver_map, } -// TODO(verwaest): Change this method so it takes in a TypeHandleList. Handle PropertyICCompiler::ComputeKeyedLoadPolymorphic( MapHandleList* receiver_maps) { Isolate* isolate = receiver_maps->at(0)->GetIsolate(); @@ -267,17 +265,13 @@ Handle PropertyICCompiler::ComputeKeyedLoadPolymorphic( Handle probe = cache->Lookup(receiver_maps, flags); if (probe->IsCode()) return Handle::cast(probe); - TypeHandleList types(receiver_maps->length()); - for (int i = 0; i < receiver_maps->length(); i++) { - types.Add(HeapType::Class(receiver_maps->at(i), isolate)); - } CodeHandleList handlers(receiver_maps->length()); ElementHandlerCompiler compiler(isolate); compiler.CompileElementHandlers(receiver_maps, &handlers); PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC); Handle code = ic_compiler.CompilePolymorphic( - &types, &handlers, isolate->factory()->empty_string(), Code::NORMAL, - ELEMENT); + receiver_maps, &handlers, isolate->factory()->empty_string(), + Code::NORMAL, ELEMENT); isolate->counters()->keyed_load_polymorphic_stubs()->Increment(); @@ -287,13 +281,13 @@ Handle PropertyICCompiler::ComputeKeyedLoadPolymorphic( Handle PropertyICCompiler::ComputePolymorphic( - Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers, - int valid_types, Handle name, ExtraICState extra_ic_state) { + Code::Kind kind, MapHandleList* maps, CodeHandleList* handlers, + int valid_maps, Handle name, ExtraICState extra_ic_state) { Handle handler = handlers->at(0); - Code::StubType type = valid_types == 1 ? handler->type() : Code::NORMAL; + Code::StubType type = valid_maps == 1 ? handler->type() : Code::NORMAL; DCHECK(kind == Code::LOAD_IC || kind == Code::STORE_IC); PropertyICCompiler ic_compiler(name->GetIsolate(), kind, extra_ic_state); - return ic_compiler.CompilePolymorphic(types, handlers, name, type, PROPERTY); + return ic_compiler.CompilePolymorphic(maps, handlers, name, type, PROPERTY); } diff --git a/src/ic/ic-compiler.h b/src/ic/ic-compiler.h index 41d901a..d1bd7a1 100644 --- a/src/ic/ic-compiler.h +++ b/src/ic/ic-compiler.h @@ -24,10 +24,9 @@ class PropertyICCompiler : public PropertyAccessCompiler { ExtraICState extra_state); static Handle ComputeMonomorphic(Code::Kind kind, Handle name, - Handle type, - Handle handler, + Handle map, Handle handler, ExtraICState extra_ic_state); - static Handle ComputePolymorphic(Code::Kind kind, TypeHandleList* types, + static Handle ComputePolymorphic(Code::Kind kind, MapHandleList* maps, CodeHandleList* handlers, int number_of_valid_maps, Handle name, @@ -76,11 +75,11 @@ class PropertyICCompiler : public PropertyAccessCompiler { Handle CompileStoreGeneric(Code::Flags flags); Handle CompileStoreMegamorphic(Code::Flags flags); - Handle CompileMonomorphic(Handle type, Handle handler, + Handle CompileMonomorphic(Handle map, Handle handler, Handle name, IcCheckType check); - Handle CompilePolymorphic(TypeHandleList* types, - CodeHandleList* handlers, Handle name, - Code::StubType type, IcCheckType check); + Handle CompilePolymorphic(MapHandleList* maps, CodeHandleList* handlers, + Handle name, Code::StubType type, + IcCheckType check); Handle CompileKeyedStoreMonomorphic(Handle receiver_map, KeyedAccessStoreMode store_mode); @@ -90,7 +89,7 @@ class PropertyICCompiler : public PropertyAccessCompiler { CodeHandleList* handler_stubs, MapHandleList* transitioned_maps); - bool IncludesNumberType(TypeHandleList* types); + bool IncludesNumberMap(MapHandleList* maps); Handle GetCode(Code::Kind kind, Code::StubType type, Handle name, InlineCacheState state = MONOMORPHIC); diff --git a/src/ic/ic-inl.h b/src/ic/ic-inl.h index 484b3a5..45dd347 100644 --- a/src/ic/ic-inl.h +++ b/src/ic/ic-inl.h @@ -161,15 +161,15 @@ Code* IC::raw_target() const { void IC::UpdateTarget() { target_ = handle(raw_target(), isolate_); } -template -JSFunction* IC::GetRootConstructor(TypeClass* type, Context* native_context) { - if (type->Is(TypeClass::Boolean())) { +JSFunction* IC::GetRootConstructor(Map* receiver_map, Context* native_context) { + Isolate* isolate = receiver_map->GetIsolate(); + if (receiver_map == isolate->heap()->boolean_map()) { return native_context->boolean_function(); - } else if (type->Is(TypeClass::Number())) { + } else if (receiver_map->instance_type() == HEAP_NUMBER_TYPE) { return native_context->number_function(); - } else if (type->Is(TypeClass::String())) { + } else if (receiver_map->instance_type() < FIRST_NONSTRING_TYPE) { return native_context->string_function(); - } else if (type->Is(TypeClass::Symbol())) { + } else if (receiver_map->instance_type() == SYMBOL_TYPE) { return native_context->symbol_function(); } else { return NULL; @@ -177,15 +177,15 @@ JSFunction* IC::GetRootConstructor(TypeClass* type, Context* native_context) { } -Handle IC::GetHandlerCacheHolder(HeapType* type, bool receiver_is_holder, - Isolate* isolate, CacheHolderFlag* flag) { - Handle receiver_map = TypeToMap(type, isolate); +Handle IC::GetHandlerCacheHolder(Handle receiver_map, + bool receiver_is_holder, Isolate* isolate, + CacheHolderFlag* flag) { if (receiver_is_holder) { *flag = kCacheOnReceiver; return receiver_map; } Context* native_context = *isolate->native_context(); - JSFunction* builtin_ctor = GetRootConstructor(type, native_context); + JSFunction* builtin_ctor = GetRootConstructor(*receiver_map, native_context); if (builtin_ctor != NULL) { *flag = kCacheOnPrototypeReceiverIsPrimitive; return handle(HeapObject::cast(builtin_ctor->instance_prototype())->map()); @@ -198,16 +198,16 @@ Handle IC::GetHandlerCacheHolder(HeapType* type, bool receiver_is_holder, } -Handle IC::GetICCacheHolder(HeapType* type, Isolate* isolate, +Handle IC::GetICCacheHolder(Handle map, Isolate* isolate, CacheHolderFlag* flag) { Context* native_context = *isolate->native_context(); - JSFunction* builtin_ctor = GetRootConstructor(type, native_context); + JSFunction* builtin_ctor = GetRootConstructor(*map, native_context); if (builtin_ctor != NULL) { *flag = kCacheOnPrototype; return handle(builtin_ctor->initial_map()); } *flag = kCacheOnReceiver; - return TypeToMap(type, isolate); + return map; } diff --git a/src/ic/ic.cc b/src/ic/ic.cc index ce5cc78..620f572 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -265,11 +265,10 @@ static void LookupForRead(LookupIterator* it) { bool IC::TryRemoveInvalidPrototypeDependentStub(Handle receiver, Handle name) { if (!IsNameCompatibleWithPrototypeFailure(name)) return false; - Handle receiver_map = TypeToMap(*receiver_type(), isolate()); if (UseVector()) { - maybe_handler_ = nexus()->FindHandlerForMap(receiver_map); + maybe_handler_ = nexus()->FindHandlerForMap(receiver_map()); } else { - maybe_handler_ = target()->FindHandlerForMap(*receiver_map); + maybe_handler_ = target()->FindHandlerForMap(*receiver_map()); } // The current map wasn't handled yet. There's no reason to stay monomorphic, @@ -278,21 +277,20 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle receiver, // TODO(verwaest): Check if the current map is actually what the old map // would transition to. if (maybe_handler_.is_null()) { - if (!receiver_map->IsJSObjectMap()) return false; + if (!receiver_map()->IsJSObjectMap()) return false; Map* first_map = FirstTargetMap(); if (first_map == NULL) return false; Handle old_map(first_map); if (old_map->is_deprecated()) return true; if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(), - receiver_map->elements_kind())) { + receiver_map()->elements_kind())) { return true; } return false; } CacheHolderFlag flag; - Handle ic_holder_map( - GetICCacheHolder(*receiver_type(), isolate(), &flag)); + Handle ic_holder_map(GetICCacheHolder(receiver_map(), isolate(), &flag)); DCHECK(flag != kCacheOnReceiver || receiver->IsJSObject()); DCHECK(flag != kCacheOnPrototype || !receiver->IsJSReceiver()); @@ -332,7 +330,7 @@ bool IC::IsNameCompatibleWithPrototypeFailure(Handle name) { void IC::UpdateState(Handle receiver, Handle name) { - update_receiver_type(receiver); + update_receiver_map(receiver); if (!name->IsString()) return; if (state() != MONOMORPHIC && state() != POLYMORPHIC) return; if (receiver->IsUndefined() || receiver->IsNull()) return; @@ -650,16 +648,16 @@ void IC::ConfigureVectorState(IC::State new_state) { } -void IC::ConfigureVectorState(Handle name, Handle type, +void IC::ConfigureVectorState(Handle name, Handle map, Handle handler) { DCHECK(UseVector()); if (kind() == Code::LOAD_IC) { LoadICNexus* nexus = casted_nexus(); - nexus->ConfigureMonomorphic(type, handler); + nexus->ConfigureMonomorphic(map, handler); } else { DCHECK(kind() == Code::KEYED_LOAD_IC); KeyedLoadICNexus* nexus = casted_nexus(); - nexus->ConfigureMonomorphic(name, type, handler); + nexus->ConfigureMonomorphic(name, map, handler); } vector_set_ = true; @@ -668,16 +666,16 @@ void IC::ConfigureVectorState(Handle name, Handle type, } -void IC::ConfigureVectorState(Handle name, TypeHandleList* types, +void IC::ConfigureVectorState(Handle name, MapHandleList* maps, CodeHandleList* handlers) { DCHECK(UseVector()); if (kind() == Code::LOAD_IC) { LoadICNexus* nexus = casted_nexus(); - nexus->ConfigurePolymorphic(types, handlers); + nexus->ConfigurePolymorphic(maps, handlers); } else { DCHECK(kind() == Code::KEYED_LOAD_IC); KeyedLoadICNexus* nexus = casted_nexus(); - nexus->ConfigurePolymorphic(name, types, handlers); + nexus->ConfigurePolymorphic(name, maps, handlers); } vector_set_ = true; @@ -783,74 +781,70 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, bool IC::UpdatePolymorphicIC(Handle name, Handle code) { if (!code->is_handler()) return false; if (target()->is_keyed_stub() && state() != PROTOTYPE_FAILURE) return false; - Handle type = receiver_type(); - TypeHandleList types; + Handle map = receiver_map(); + MapHandleList maps; CodeHandleList handlers; - TargetTypes(&types); - int number_of_types = types.length(); - int deprecated_types = 0; + TargetMaps(&maps); + int number_of_maps = maps.length(); + int deprecated_maps = 0; int handler_to_overwrite = -1; - 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()) { + for (int i = 0; i < number_of_maps; i++) { + Handle current_map = maps.at(i); + if (current_map->is_deprecated()) { // Filter out deprecated maps to ensure their instances get migrated. - ++deprecated_types; - } else if (type->NowIs(current_type)) { + ++deprecated_maps; + } else if (map.is_identical_to(current_map)) { // If the receiver type is already in the polymorphic IC, this indicates // there was a prototoype chain failure. In that case, just overwrite the // handler. handler_to_overwrite = i; - } else if (handler_to_overwrite == -1 && current_type->IsClass() && - type->IsClass() && - IsTransitionOfMonomorphicTarget(*current_type->AsClass()->Map(), - *type->AsClass()->Map())) { + } else if (handler_to_overwrite == -1 && + IsTransitionOfMonomorphicTarget(*current_map, *map)) { handler_to_overwrite = i; } } - int number_of_valid_types = - number_of_types - deprecated_types - (handler_to_overwrite != -1); + int number_of_valid_maps = + number_of_maps - deprecated_maps - (handler_to_overwrite != -1); - if (number_of_valid_types >= 4) return false; - if (number_of_types == 0 && state() != MONOMORPHIC && - state() != POLYMORPHIC) { + if (number_of_valid_maps >= 4) return false; + if (number_of_maps == 0 && state() != MONOMORPHIC && state() != POLYMORPHIC) { return false; } if (UseVector()) { - if (!nexus()->FindHandlers(&handlers, types.length())) return false; + if (!nexus()->FindHandlers(&handlers, maps.length())) return false; } else { - if (!target()->FindHandlers(&handlers, types.length())) return false; + if (!target()->FindHandlers(&handlers, maps.length())) return false; } - number_of_valid_types++; - if (number_of_valid_types > 1 && target()->is_keyed_stub()) return false; + number_of_valid_maps++; + if (number_of_valid_maps > 1 && target()->is_keyed_stub()) return false; Handle ic; - if (number_of_valid_types == 1) { + if (number_of_valid_maps == 1) { if (UseVector()) { - ConfigureVectorState(name, receiver_type(), code); + ConfigureVectorState(name, receiver_map(), code); } else { - ic = PropertyICCompiler::ComputeMonomorphic(kind(), name, type, code, + ic = PropertyICCompiler::ComputeMonomorphic(kind(), name, map, code, extra_ic_state()); } } else { if (handler_to_overwrite >= 0) { handlers.Set(handler_to_overwrite, code); - if (!type->NowIs(types.at(handler_to_overwrite))) { - types.Set(handler_to_overwrite, type); + if (!map.is_identical_to(maps.at(handler_to_overwrite))) { + maps.Set(handler_to_overwrite, map); } } else { - types.Add(type); + maps.Add(map); handlers.Add(code); } if (UseVector()) { - ConfigureVectorState(name, &types, &handlers); + ConfigureVectorState(name, &maps, &handlers); } else { - ic = PropertyICCompiler::ComputePolymorphic(kind(), &types, &handlers, - number_of_valid_types, name, + ic = PropertyICCompiler::ComputePolymorphic(kind(), &maps, &handlers, + number_of_valid_maps, name, extra_ic_state()); } } @@ -860,66 +854,25 @@ bool IC::UpdatePolymorphicIC(Handle name, Handle code) { } -Handle IC::CurrentTypeOf(Handle object, Isolate* isolate) { - return object->IsJSGlobalObject() - ? HeapType::Constant(Handle::cast(object), isolate) - : HeapType::NowOf(object, isolate); -} - - -Handle IC::TypeToMap(HeapType* type, Isolate* isolate) { - if (type->Is(HeapType::Number())) - 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()); - } - DCHECK(type->IsClass()); - return type->AsClass()->Map(); -} - - -template -typename T::TypeHandle IC::MapToType(Handle map, - typename T::Region* region) { - if (map->instance_type() == HEAP_NUMBER_TYPE) { - return T::Number(region); - } else if (map->instance_type() == ODDBALL_TYPE) { - // The only oddballs that can be recorded in ICs are booleans. - return T::Boolean(region); - } else { - return T::Class(map, region); - } -} - - -template Type* IC::MapToType(Handle map, Zone* zone); - - -template Handle IC::MapToType(Handle map, - Isolate* region); - - void IC::UpdateMonomorphicIC(Handle handler, Handle name) { DCHECK(handler->is_handler()); if (UseVector()) { - ConfigureVectorState(name, receiver_type(), handler); + ConfigureVectorState(name, receiver_map(), handler); } else { Handle ic = PropertyICCompiler::ComputeMonomorphic( - kind(), name, receiver_type(), handler, extra_ic_state()); + kind(), name, receiver_map(), handler, extra_ic_state()); set_target(*ic); } } void IC::CopyICToMegamorphicCache(Handle name) { - TypeHandleList types; + MapHandleList maps; CodeHandleList handlers; - TargetTypes(&types); - if (!target()->FindHandlers(&handlers, types.length())) return; - for (int i = 0; i < types.length(); i++) { - UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); + TargetMaps(&maps); + if (!target()->FindHandlers(&handlers, maps.length())) return; + for (int i = 0; i < maps.length(); i++) { + UpdateMegamorphicCache(*maps.at(i), *name, *handlers.at(i)); } } @@ -961,7 +914,7 @@ void IC::PatchCache(Handle name, Handle code) { } // Fall through. case MEGAMORPHIC: - UpdateMegamorphicCache(*receiver_type(), *name, *code); + UpdateMegamorphicCache(*receiver_map(), *name, *code); // Indicate that we've handled this case. if (UseVector()) { vector_set_ = true; @@ -1074,7 +1027,7 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { } else if (!lookup->IsFound()) { if (kind() == Code::LOAD_IC) { code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), - receiver_type()); + receiver_map()); // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. if (code.is_null()) code = slow_stub(); } else { @@ -1089,8 +1042,7 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { } -void IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) { - Map* map = *TypeToMap(type, isolate()); +void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { isolate()->stub_cache()->Set(name, map, code); } @@ -1100,7 +1052,7 @@ Handle IC::ComputeHandler(LookupIterator* lookup, Handle value) { lookup->GetReceiver().is_identical_to(lookup->GetHolder()); CacheHolderFlag flag; Handle stub_holder_map = IC::GetHandlerCacheHolder( - *receiver_type(), receiver_is_holder, isolate(), &flag); + receiver_map(), receiver_is_holder, isolate(), &flag); Handle code = PropertyHandlerCompiler::Find( lookup->name(), stub_holder_map, kind(), flag, @@ -1173,14 +1125,13 @@ Handle LoadIC::CompileHandler(LookupIterator* lookup, return function_prototype_stub.GetCode(); } - Handle type = receiver_type(); + Handle map = receiver_map(); Handle holder = lookup->GetHolder(); bool receiver_is_holder = receiver.is_identical_to(holder); switch (lookup->state()) { case LookupIterator::INTERCEPTOR: { DCHECK(!holder->GetNamedInterceptor()->getter()->IsUndefined()); - NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, - cache_holder); + NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); // Perform a lookup behind the interceptor. Copy the LookupIterator since // the original iterator will be used to fetch the value. LookupIterator it = *lookup; @@ -1195,8 +1146,8 @@ Handle LoadIC::CompileHandler(LookupIterator* lookup, DCHECK(receiver->IsJSObject()); Handle js_receiver = Handle::cast(receiver); int object_offset; - if (Accessors::IsJSObjectFieldAccessor(type, lookup->name(), - &object_offset)) { + if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(), + &object_offset)) { FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, js_receiver->map()); return SimpleFieldLoad(index); @@ -1208,13 +1159,12 @@ Handle LoadIC::CompileHandler(LookupIterator* lookup, Handle info = Handle::cast(accessors); if (v8::ToCData
(info->getter()) == 0) break; - if (!ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), info, - type)) { + if (!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info, + map)) { break; } if (!holder->HasFastProperties()) break; - NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, - cache_holder); + NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); return compiler.CompileLoadCallback(lookup->name(), info); } if (accessors->IsAccessorPair()) { @@ -1230,8 +1180,7 @@ Handle LoadIC::CompileHandler(LookupIterator* lookup, break; } CallOptimization call_optimization(function); - NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, - cache_holder); + NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); if (call_optimization.is_simple_api_call() && call_optimization.IsCompatibleReceiver(receiver, holder)) { return compiler.CompileLoadCallback(lookup->name(), call_optimization, @@ -1249,15 +1198,15 @@ Handle LoadIC::CompileHandler(LookupIterator* lookup, if (lookup->is_dictionary_holder()) { if (kind() != Code::LOAD_IC) break; if (holder->IsGlobalObject()) { - NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, + NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); Handle cell = lookup->GetPropertyCell(); Handle code = compiler.CompileLoadGlobal( cell, lookup->name(), lookup->IsConfigurable()); // TODO(verwaest): Move caching of these NORMAL stubs outside as well. CacheHolderFlag flag; - Handle stub_holder_map = GetHandlerCacheHolder( - *type, receiver_is_holder, isolate(), &flag); + Handle stub_holder_map = + GetHandlerCacheHolder(map, receiver_is_holder, isolate(), &flag); Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); return code; } @@ -1275,8 +1224,7 @@ Handle LoadIC::CompileHandler(LookupIterator* lookup, if (receiver_is_holder) { return SimpleFieldLoad(field); } - NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, - cache_holder); + NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); return compiler.CompileLoadField(lookup->name(), field); } @@ -1286,8 +1234,7 @@ Handle LoadIC::CompileHandler(LookupIterator* lookup, LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); return stub.GetCode(); } - NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, - cache_holder); + NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); return compiler.CompileLoadConstant(lookup->name(), lookup->GetConstantIndex()); } @@ -1334,7 +1281,7 @@ Handle KeyedLoadIC::LoadElementStub(Handle receiver) { if (FLAG_vector_ics) { Handle handler = PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map); - ConfigureVectorState(Handle::null(), receiver_type(), handler); + ConfigureVectorState(Handle::null(), receiver_map, handler); return null_handle; } return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map); @@ -1354,7 +1301,7 @@ Handle KeyedLoadIC::LoadElementStub(Handle receiver) { if (FLAG_vector_ics) { Handle handler = PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map); - ConfigureVectorState(Handle::null(), receiver_type(), handler); + ConfigureVectorState(Handle::null(), receiver_map, handler); return null_handle; } return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map); @@ -1382,11 +1329,8 @@ Handle KeyedLoadIC::LoadElementStub(Handle receiver) { CodeHandleList handlers(target_receiver_maps.length()); ElementHandlerCompiler compiler(isolate()); compiler.CompileElementHandlers(&target_receiver_maps, &handlers); - TypeHandleList types(target_receiver_maps.length()); - for (int i = 0; i < target_receiver_maps.length(); i++) { - types.Add(HeapType::Class(target_receiver_maps.at(i), isolate())); - } - ConfigureVectorState(Handle::null(), &types, &handlers); + ConfigureVectorState(Handle::null(), &target_receiver_maps, + &handlers); return null_handle; } @@ -1492,7 +1436,7 @@ bool StoreIC::LookupForWrite(LookupIterator* it, Handle value, it->PrepareForDataProperty(value); // The previous receiver map might just have been deprecated, // so reload it. - update_receiver_type(receiver); + update_receiver_map(receiver); return true; } @@ -1717,13 +1661,13 @@ Handle StoreIC::CompileHandler(LookupIterator* lookup, } DCHECK(lookup->IsCacheableTransition()); - NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); + NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); return compiler.CompileStoreTransition(transition, lookup->name()); } case LookupIterator::INTERCEPTOR: { DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined()); - NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); + NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); return compiler.CompileStoreInterceptor(lookup->name()); } @@ -1740,12 +1684,12 @@ Handle StoreIC::CompileHandler(LookupIterator* lookup, TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == 0"); break; } - if (!ExecutableAccessorInfo::IsCompatibleReceiverType( - isolate(), info, receiver_type())) { + if (!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info, + receiver_map())) { TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type"); break; } - NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); + NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); return compiler.CompileStoreCallback(receiver, lookup->name(), lookup->GetAccessorIndex()); } else if (accessors->IsAccessorPair()) { @@ -1757,7 +1701,7 @@ Handle StoreIC::CompileHandler(LookupIterator* lookup, } Handle function = Handle::cast(setter); CallOptimization call_optimization(function); - NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); + NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); if (call_optimization.is_simple_api_call() && call_optimization.IsCompatibleReceiver(receiver, holder)) { return compiler.CompileStoreCallback(receiver, lookup->name(), @@ -1801,7 +1745,7 @@ Handle StoreIC::CompileHandler(LookupIterator* lookup, lookup->representation()); return stub.GetCode(); } - NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); + NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); return compiler.CompileStoreField(lookup); } diff --git a/src/ic/ic.h b/src/ic/ic.h index 31c3128..8c1c82e 100644 --- a/src/ic/ic.h +++ b/src/ic/ic.h @@ -92,14 +92,14 @@ class IC { bool IsCallStub() const { return target()->is_call_stub(); } #endif - template - static JSFunction* GetRootConstructor(TypeClass* type, - Context* native_context); - static inline Handle GetHandlerCacheHolder(HeapType* type, + static inline JSFunction* GetRootConstructor(Map* receiver_map, + Context* native_context); + static inline Handle GetHandlerCacheHolder(Handle receiver_map, bool receiver_is_holder, Isolate* isolate, CacheHolderFlag* flag); - static inline Handle GetICCacheHolder(HeapType* type, Isolate* isolate, + static inline Handle GetICCacheHolder(Handle receiver_map, + Isolate* isolate, CacheHolderFlag* flag); static bool IsCleared(Code* code) { @@ -112,19 +112,6 @@ class IC { return state == UNINITIALIZED || state == PREMONOMORPHIC; } - // Utility functions to convert maps to types and back. There are two special - // cases: - // - The heap_number_map is used as a marker which includes heap numbers as - // well as smis. - // - The oddball map is only used for booleans. - static Handle TypeToMap(HeapType* type, Isolate* isolate); - template - static typename T::TypeHandle MapToType(Handle map, - typename T::Region* region); - - static Handle CurrentTypeOf(Handle object, - Isolate* isolate); - static bool ICUseVector(Code::Kind kind) { return (FLAG_vector_ics && (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC)) || @@ -163,10 +150,10 @@ class IC { // Configure for most states. void ConfigureVectorState(IC::State new_state); // Configure the vector for MONOMORPHIC. - void ConfigureVectorState(Handle name, Handle type, + void ConfigureVectorState(Handle name, Handle map, Handle handler); // Configure the vector for POLYMORPHIC. - void ConfigureVectorState(Handle name, TypeHandleList* types, + void ConfigureVectorState(Handle name, MapHandleList* maps, CodeHandleList* handlers); char TransitionMarkFromState(IC::State state); @@ -204,7 +191,7 @@ class IC { void UpdateMonomorphicIC(Handle handler, Handle name); bool UpdatePolymorphicIC(Handle name, Handle code); - void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code); + void UpdateMegamorphicCache(Map* map, Name* name, Code* code); void CopyICToMegamorphicCache(Handle name); bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); @@ -227,9 +214,13 @@ class IC { ExtraICState extra_ic_state() const { return extra_ic_state_; } void set_extra_ic_state(ExtraICState state) { extra_ic_state_ = state; } - Handle receiver_type() { return receiver_type_; } - void update_receiver_type(Handle receiver) { - receiver_type_ = CurrentTypeOf(receiver, isolate_); + Handle receiver_map() { return receiver_map_; } + void update_receiver_map(Handle receiver) { + if (receiver->IsSmi()) { + receiver_map_ = isolate_->factory()->heap_number_map(); + } else { + receiver_map_ = handle(HeapObject::cast(*receiver)->map()); + } } void TargetMaps(MapHandleList* list) { @@ -239,13 +230,6 @@ class IC { } } - void TargetTypes(TypeHandleList* list) { - FindTargetMaps(); - for (int i = 0; i < target_maps_.length(); i++) { - list->Add(MapToType(target_maps_.at(i), isolate_)); - } - } - Map* FirstTargetMap() { FindTargetMaps(); return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL; @@ -309,7 +293,7 @@ class IC { State old_state_; // For saving if we marked as prototype failure. State state_; Code::Kind kind_; - Handle receiver_type_; + Handle receiver_map_; MaybeHandle maybe_handler_; ExtraICState extra_ic_state_; diff --git a/src/ic/x64/handler-compiler-x64.cc b/src/ic/x64/handler-compiler-x64.cc index da27d4c..d451f2e 100644 --- a/src/ic/x64/handler-compiler-x64.cc +++ b/src/ic/x64/handler-compiler-x64.cc @@ -215,9 +215,8 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell( void NamedStoreHandlerCompiler::GenerateStoreViaSetter( - MacroAssembler* masm, Handle type, Register receiver, - Register holder, int accessor_index, int expected_arguments, - Register scratch) { + MacroAssembler* masm, Handle map, Register receiver, Register holder, + int accessor_index, int expected_arguments, Register scratch) { // ----------- S t a t e ------------- // -- rsp[0] : return address // ----------------------------------- @@ -232,7 +231,7 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( DCHECK(!receiver.is(scratch)); DCHECK(!value().is(scratch)); // Call the JavaScript setter with receiver and value on the stack. - if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + if (map->IsJSGlobalObjectMap()) { // Swap in the global receiver. __ movp(scratch, FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); @@ -262,9 +261,8 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( void NamedLoadHandlerCompiler::GenerateLoadViaGetter( - MacroAssembler* masm, Handle type, Register receiver, - Register holder, int accessor_index, int expected_arguments, - Register scratch) { + MacroAssembler* masm, Handle map, Register receiver, Register holder, + int accessor_index, int expected_arguments, Register scratch) { // ----------- S t a t e ------------- // -- rax : receiver // -- rcx : name @@ -277,7 +275,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter( DCHECK(!holder.is(scratch)); DCHECK(!receiver.is(scratch)); // Call the JavaScript getter with the receiver on the stack. - if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { + if (map->IsJSGlobalObjectMap()) { // Swap in the global receiver. __ movp(scratch, FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); @@ -416,7 +414,7 @@ Register PropertyHandlerCompiler::CheckPrototypes( Register object_reg, Register holder_reg, Register scratch1, Register scratch2, Handle name, Label* miss, PrototypeCheckType check) { - Handle receiver_map(IC::TypeToMap(*type(), isolate())); + Handle receiver_map = map(); // Make sure there's no overlap between holder and object registers. DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); @@ -430,8 +428,8 @@ Register PropertyHandlerCompiler::CheckPrototypes( int depth = 0; Handle current = Handle::null(); - if (type()->IsConstant()) { - current = Handle::cast(type()->AsConstant()->Value()); + if (receiver_map->IsJSGlobalObjectMap()) { + current = isolate()->global_object(); } Handle prototype = Handle::null(); Handle current_map = receiver_map; diff --git a/src/ic/x64/ic-compiler-x64.cc b/src/ic/x64/ic-compiler-x64.cc index eeae4d5..89e7aee 100644 --- a/src/ic/x64/ic-compiler-x64.cc +++ b/src/ic/x64/ic-compiler-x64.cc @@ -72,7 +72,7 @@ Handle PropertyICCompiler::CompileKeyedStorePolymorphic( } -Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, +Handle PropertyICCompiler::CompilePolymorphic(MapHandleList* maps, CodeHandleList* handlers, Handle name, Code::StubType type, @@ -99,7 +99,7 @@ Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, } Label number_case; - Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; + Label* smi_target = IncludesNumberMap(maps) ? &number_case : &miss; __ JumpIfSmi(receiver(), smi_target); // Polymorphic keyed stores may use the map register @@ -107,17 +107,16 @@ Handle PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, DCHECK(kind() != Code::KEYED_STORE_IC || map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister())); __ movp(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); - int receiver_count = types->length(); + int receiver_count = maps->length(); int number_of_handled_maps = 0; for (int current = 0; current < receiver_count; ++current) { - Handle type = types->at(current); - Handle map = IC::TypeToMap(*type, isolate()); + Handle map = maps->at(current); if (!map->is_deprecated()) { number_of_handled_maps++; Handle cell = Map::WeakCellForMap(map); // Check map and tail call if there's a match __ CmpWeakValue(map_reg, cell, scratch2()); - if (type->Is(HeapType::Number())) { + if (map->instance_type() == HEAP_NUMBER_TYPE) { DCHECK(!number_case.is_unused()); __ bind(&number_case); } diff --git a/src/objects.cc b/src/objects.cc index 7459ed4..1f48810 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -331,11 +331,10 @@ MaybeHandle Object::GetPropertyWithAccessor(Handle receiver, } -bool AccessorInfo::IsCompatibleReceiverType(Isolate* isolate, - Handle info, - Handle type) { +bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate, + Handle info, + Handle map) { if (!info->HasExpectedReceiverType()) return true; - Handle map = IC::TypeToMap(*type, isolate); if (!map->IsJSObjectMap()) return false; return FunctionTemplateInfo::cast(info->expected_receiver_type()) ->IsTemplateFor(*map); diff --git a/src/objects.h b/src/objects.h index d7d6e67..9221c62 100644 --- a/src/objects.h +++ b/src/objects.h @@ -10402,9 +10402,9 @@ class AccessorInfo: public Struct { inline void set_property_attributes(PropertyAttributes attributes); // Checks whether the given receiver is compatible with this accessor. - static bool IsCompatibleReceiverType(Isolate* isolate, - Handle info, - Handle type); + static bool IsCompatibleReceiverMap(Isolate* isolate, + Handle info, + Handle map); inline bool IsCompatibleReceiver(Object* receiver); DECLARE_CAST(AccessorInfo) diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc index 79afa2d..b0be315 100644 --- a/src/type-feedback-vector.cc +++ b/src/type-feedback-vector.cc @@ -207,14 +207,13 @@ Handle FeedbackNexus::EnsureArrayOfSize(int length) { } -void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types, +void FeedbackNexus::InstallHandlers(int start_index, MapHandleList* maps, CodeHandleList* handlers) { Isolate* isolate = GetIsolate(); Handle array = handle(FixedArray::cast(GetFeedback()), isolate); - int receiver_count = types->length(); + int receiver_count = maps->length(); for (int current = 0; current < receiver_count; ++current) { - Handle type = types->at(current); - Handle map = IC::TypeToMap(*type, isolate); + Handle map = maps->at(current); Handle cell = Map::WeakCellForMap(map); array->set(start_index + (current * 2), *cell); array->set(start_index + (current * 2 + 1), *handlers->at(current)); @@ -333,10 +332,9 @@ void KeyedLoadICNexus::ConfigurePremonomorphic() { } -void LoadICNexus::ConfigureMonomorphic(Handle type, +void LoadICNexus::ConfigureMonomorphic(Handle receiver_map, Handle handler) { Handle array = EnsureArrayOfSize(2); - Handle receiver_map = IC::TypeToMap(*type, GetIsolate()); Handle cell = Map::WeakCellForMap(receiver_map); array->set(0, *cell); array->set(1, *handler); @@ -344,10 +342,9 @@ void LoadICNexus::ConfigureMonomorphic(Handle type, void KeyedLoadICNexus::ConfigureMonomorphic(Handle name, - Handle type, + Handle receiver_map, Handle handler) { Handle array = EnsureArrayOfSize(3); - Handle receiver_map = IC::TypeToMap(*type, GetIsolate()); if (name.is_null()) { array->set(0, Smi::FromInt(0)); } else { @@ -359,25 +356,25 @@ void KeyedLoadICNexus::ConfigureMonomorphic(Handle name, } -void LoadICNexus::ConfigurePolymorphic(TypeHandleList* types, +void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers) { - int receiver_count = types->length(); + int receiver_count = maps->length(); EnsureArrayOfSize(receiver_count * 2); - InstallHandlers(0, types, handlers); + InstallHandlers(0, maps, handlers); } void KeyedLoadICNexus::ConfigurePolymorphic(Handle name, - TypeHandleList* types, + MapHandleList* maps, CodeHandleList* handlers) { - int receiver_count = types->length(); + int receiver_count = maps->length(); Handle array = EnsureArrayOfSize(1 + receiver_count * 2); if (name.is_null()) { array->set(0, Smi::FromInt(0)); } else { array->set(0, *name); } - InstallHandlers(1, types, handlers); + InstallHandlers(1, maps, handlers); } diff --git a/src/type-feedback-vector.h b/src/type-feedback-vector.h index c0646a4..b7abad5 100644 --- a/src/type-feedback-vector.h +++ b/src/type-feedback-vector.h @@ -262,7 +262,7 @@ class FeedbackNexus { } Handle EnsureArrayOfSize(int length); - void InstallHandlers(int start_index, TypeHandleList* types, + void InstallHandlers(int start_index, MapHandleList* maps, CodeHandleList* handlers); int ExtractMaps(int start_index, MapHandleList* maps) const; MaybeHandle FindHandlerForMap(int start_index, Handle map) const; @@ -329,9 +329,9 @@ class LoadICNexus : public FeedbackNexus { void ConfigureMegamorphic(); void ConfigurePremonomorphic(); - void ConfigureMonomorphic(Handle type, Handle handler); + void ConfigureMonomorphic(Handle receiver_map, Handle handler); - void ConfigurePolymorphic(TypeHandleList* types, CodeHandleList* handlers); + void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers); InlineCacheState StateFromFeedback() const OVERRIDE; int ExtractMaps(MapHandleList* maps) const OVERRIDE; @@ -357,10 +357,10 @@ class KeyedLoadICNexus : public FeedbackNexus { void ConfigureMegamorphic(); void ConfigurePremonomorphic(); // name can be a null handle for element loads. - void ConfigureMonomorphic(Handle name, Handle type, + void ConfigureMonomorphic(Handle name, Handle receiver_map, Handle handler); // name can be null. - void ConfigurePolymorphic(Handle name, TypeHandleList* types, + void ConfigurePolymorphic(Handle name, MapHandleList* maps, CodeHandleList* handlers); InlineCacheState StateFromFeedback() const OVERRIDE; -- 2.7.4