diff options
-rw-r--r-- | src/ast/ast-numbering.cc | 2 | ||||
-rw-r--r-- | src/compiler/access-info.cc | 3 | ||||
-rw-r--r-- | src/compiler/typer.cc | 2 | ||||
-rw-r--r-- | src/crankshaft/hydrogen.cc | 3 | ||||
-rw-r--r-- | src/objects.cc | 109 | ||||
-rw-r--r-- | src/objects.h | 3 |
6 files changed, 76 insertions, 46 deletions
diff --git a/src/ast/ast-numbering.cc b/src/ast/ast-numbering.cc index 499760de..811bd33a 100644 --- a/src/ast/ast-numbering.cc +++ b/src/ast/ast-numbering.cc @@ -616,6 +616,8 @@ void AstNumberingVisitor::VisitStatements(ZoneList<Statement*>* statements) { if (statements == NULL) return; for (int i = 0; i < statements->length(); i++) { Visit(statements->at(i)); + if (statements->at(i)->IsJump()) + break; } } diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc index 8fef2f07..d563e1dd 100644 --- a/src/compiler/access-info.cc +++ b/src/compiler/access-info.cc @@ -231,7 +231,8 @@ bool AccessInfoFactory::ComputeElementAccessInfos( MapTransitionList transitions(maps.length()); for (Handle<Map> map : maps) { if (Map::TryUpdate(map).ToHandle(&map)) { - Map* transition_target = + Map* transition_target = map->is_stable() ? + nullptr : map->FindElementsKindTransitionedMap(&possible_transition_targets); if (transition_target == nullptr) { receiver_maps.Add(map); diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc index ed1a04aa..09003ca8 100644 --- a/src/compiler/typer.cc +++ b/src/compiler/typer.cc @@ -1431,7 +1431,7 @@ Type* Typer::Visitor::JSCallTyper(Type* fun, Typer* t) { return Type::String(); case kStringIndexOf: case kStringLastIndexOf: - return Type::Range(-1.0, String::kMaxLength - 1.0, t->zone()); + return Type::Range(-1.0, String::kMaxLength, t->zone()); case kStringEndsWith: case kStringIncludes: return Type::Boolean(); diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc index d55bb37c..df7b02f2 100644 --- a/src/crankshaft/hydrogen.cc +++ b/src/crankshaft/hydrogen.cc @@ -7176,7 +7176,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( // Get transition target for each map (NULL == no transition). for (int i = 0; i < maps->length(); ++i) { Handle<Map> map = maps->at(i); - Map* transitioned_map = + Map* transitioned_map = map->is_stable() ? + nullptr : map->FindElementsKindTransitionedMap(&possible_transitioned_maps); if (transitioned_map != nullptr) { transition_target.Add(handle(transitioned_map)); diff --git a/src/objects.cc b/src/objects.cc index 9f9a6280..d5b77777 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -12670,6 +12670,53 @@ void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { map->StartInobjectSlackTracking(); } +namespace { +bool FastInitializeDerivedMap(Isolate* isolate, Handle<JSFunction> new_target, + Handle<JSFunction> constructor, + Handle<Map> constructor_initial_map) { + // Check that |function|'s initial map still in sync with the |constructor|, + // otherwise we must create a new initial map for |function|. + if (new_target->has_initial_map() && + new_target->initial_map()->GetConstructor() == *constructor) { + DCHECK(new_target->instance_prototype()->IsJSReceiver()); + return true; + } + // Create a new map with the size and number of in-object properties + // suggested by |function|. + + // Link initial map and constructor function if the new.target is actually a + // subclass constructor. + if (!IsDerivedConstructor(new_target->shared()->kind())) return false; + + Handle<Object> prototype(new_target->instance_prototype(), isolate); + InstanceType instance_type = constructor_initial_map->instance_type(); + DCHECK(CanSubclassHaveInobjectProperties(instance_type)); + + int internal_fields = + JSObject::GetInternalFieldCount(*constructor_initial_map); + int pre_allocated = constructor_initial_map->GetInObjectProperties() - + constructor_initial_map->unused_property_fields(); + int instance_size; + int in_object_properties; + new_target->CalculateInstanceSizeForDerivedClass( + instance_type, internal_fields, &instance_size, + &in_object_properties); + + int unused_property_fields = in_object_properties - pre_allocated; + Handle<Map> map = + Map::CopyInitialMap(constructor_initial_map, instance_size, + in_object_properties, unused_property_fields); + map->set_new_target_is_base(false); + + JSFunction::SetInitialMap(new_target, map, prototype); + map->SetConstructor(*constructor); + map->set_construction_counter(Map::kNoSlackTracking); + map->StartInobjectSlackTracking(); + + return true; +} + +} // namespace // static MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate, @@ -12688,42 +12735,10 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate, // Check that |function|'s initial map still in sync with the |constructor|, // otherwise we must create a new initial map for |function|. - if (function->has_initial_map() && - function->initial_map()->GetConstructor() == *constructor) { + if (FastInitializeDerivedMap(isolate, function, constructor, + constructor_initial_map)) { return handle(function->initial_map(), isolate); } - - // Create a new map with the size and number of in-object properties - // suggested by |function|. - - // Link initial map and constructor function if the new.target is actually a - // subclass constructor. - if (IsDerivedConstructor(function->shared()->kind())) { - Handle<Object> prototype(function->instance_prototype(), isolate); - InstanceType instance_type = constructor_initial_map->instance_type(); - DCHECK(CanSubclassHaveInobjectProperties(instance_type)); - int internal_fields = - JSObject::GetInternalFieldCount(*constructor_initial_map); - int pre_allocated = constructor_initial_map->GetInObjectProperties() - - constructor_initial_map->unused_property_fields(); - int instance_size; - int in_object_properties; - function->CalculateInstanceSizeForDerivedClass( - instance_type, internal_fields, &instance_size, - &in_object_properties); - - int unused_property_fields = in_object_properties - pre_allocated; - Handle<Map> map = - Map::CopyInitialMap(constructor_initial_map, instance_size, - in_object_properties, unused_property_fields); - map->set_new_target_is_base(false); - - JSFunction::SetInitialMap(function, map, prototype); - map->SetConstructor(*constructor); - map->set_construction_counter(Map::kNoSlackTracking); - map->StartInobjectSlackTracking(); - return map; - } } // Slow path, new.target is either a proxy or can't cache the map. @@ -13371,15 +13386,17 @@ void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type, int* instance_size, int* in_object_properties) { int header_size = JSObject::GetHeaderSize(instance_type); - DCHECK_LE(requested_internal_fields, - (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2); + int max_nof_fields = + (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2; + CHECK_LE(max_nof_fields, JSObject::kMaxInObjectProperties); + *in_object_properties = Min(requested_in_object_properties, max_nof_fields); + CHECK_LE(requested_internal_fields, max_nof_fields - *in_object_properties); *instance_size = - Min(header_size + - ((requested_internal_fields + requested_in_object_properties) - << kPointerSizeLog2), - JSObject::kMaxInstanceSize); - *in_object_properties = ((*instance_size - header_size) >> kPointerSizeLog2) - - requested_internal_fields; + header_size + + ((requested_internal_fields + *in_object_properties) << kPointerSizeLog2); + CHECK_EQ(*in_object_properties, + ((*instance_size - header_size) >> kPointerSizeLog2) - + requested_internal_fields); } @@ -13404,7 +13421,13 @@ void JSFunction::CalculateInstanceSizeForDerivedClass( if (!current->IsJSFunction()) break; JSFunction* func = JSFunction::cast(current); SharedFunctionInfo* shared = func->shared(); - expected_nof_properties += shared->expected_nof_properties(); + int count = shared->expected_nof_properties(); + // Check that the estimate is sane. + if (expected_nof_properties <= JSObject::kMaxInObjectProperties - count) { + expected_nof_properties += count; + } else { + expected_nof_properties = JSObject::kMaxInObjectProperties; + } if (!IsDerivedConstructor(shared->kind())) { break; } diff --git a/src/objects.h b/src/objects.h index 04d3d384..289f5fca 100644 --- a/src/objects.h +++ b/src/objects.h @@ -2544,6 +2544,9 @@ class JSObject: public JSReceiver { static const int kHeaderSize = kElementsOffset + kPointerSize; STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize); + static const int kMaxInObjectProperties = + (kMaxInstanceSize - kHeaderSize) >> kPointerSizeLog2; + STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors); typedef FlexibleBodyDescriptor<JSReceiver::kPropertiesOffset> BodyDescriptor; |