aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast/ast-numbering.cc2
-rw-r--r--src/compiler/access-info.cc3
-rw-r--r--src/compiler/typer.cc2
-rw-r--r--src/crankshaft/hydrogen.cc3
-rw-r--r--src/objects.cc109
-rw-r--r--src/objects.h3
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;