Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 97b4a0e1782999c39840ddfc29ff1761edd32fd7..b5e17ccf32acb3454389c5a2648df3c22324ae87 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -11764,8 +11764,9 @@ void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { |
in_object_properties = 0; |
} else { |
instance_type = JS_OBJECT_TYPE; |
- instance_size = function->shared()->CalculateInstanceSize(); |
- in_object_properties = function->shared()->CalculateInObjectProperties(); |
+ instance_size = function->shared()->CalculateInstanceSize(instance_type); |
+ in_object_properties = |
+ function->shared()->CalculateInObjectProperties(instance_type); |
} |
Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size); |
if (function->map()->is_strong()) { |
@@ -11793,6 +11794,66 @@ void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { |
} |
+Handle<Map> JSFunction::EnsureDerivedHasInitialMap( |
+ Handle<JSFunction> original_constructor, Handle<JSFunction> constructor) { |
+ DCHECK(constructor->has_initial_map()); |
+ Isolate* isolate = constructor->GetIsolate(); |
+ Handle<Map> constructor_initial_map(constructor->initial_map(), isolate); |
+ if (*original_constructor == *constructor) return constructor_initial_map; |
+ if (original_constructor->has_initial_map()) { |
+ // Check that |original_constructor|'s initial map still in sync with |
+ // the |constructor|, otherwise we must create a new initial map for |
+ // |original_constructor|. |
+ if (original_constructor->initial_map()->GetConstructor() == *constructor) { |
+ return handle(original_constructor->initial_map(), isolate); |
+ } |
+ } |
+ |
+ // First create a new map with the size and number of in-object properties |
+ // suggested by the function. |
+ DCHECK(!original_constructor->shared()->is_generator()); |
+ DCHECK(!constructor->shared()->is_generator()); |
+ |
+ Handle<Map> map = |
+ Map::Copy(constructor_initial_map, "EnsureDerivedHasInitialMap"); |
+ |
+ // Fetch or allocate prototype. |
+ Handle<Object> prototype; |
+ if (original_constructor->has_instance_prototype()) { |
+ prototype = handle(original_constructor->instance_prototype(), isolate); |
+ } else { |
+ prototype = isolate->factory()->NewFunctionPrototype(original_constructor); |
+ } |
+ |
+ DCHECK(prototype->IsJSReceiver()); |
+ if (map->prototype() != *prototype) { |
+ Map::SetPrototype(map, prototype, FAST_PROTOTYPE); |
+ } |
+ |
+ // Finally link initial map and constructor function if the original |
+ // constructor is actually a subclass constructor. |
+ if (IsSubclassConstructor(original_constructor->shared()->kind())) { |
+ InstanceType instance_type = map->instance_type(); |
+ int instance_size = |
+ original_constructor->shared()->CalculateInstanceSize(instance_type); |
+ map->set_instance_size(instance_size); |
+ |
+ int in_object_properties = |
+ original_constructor->shared()->CalculateInObjectProperties( |
Toon Verwaest
2015/10/26 15:10:57
Shouldn't we add up the expected number of propert
Igor Sheludko
2015/10/27 12:56:12
Done.
|
+ instance_type); |
+ map->SetInObjectProperties(in_object_properties); |
+ map->set_unused_property_fields(in_object_properties); |
+ |
+ JSFunction::SetInitialMap(original_constructor, map, prototype); |
+ map->SetConstructor(*constructor); |
+ original_constructor->StartInobjectSlackTracking(); |
+ } else { |
+ map->SetConstructor(*constructor); |
+ } |
+ return map; |
+} |
+ |
+ |
void JSFunction::SetInstanceClassName(String* name) { |
shared()->set_instance_class_name(name); |
} |
@@ -12108,10 +12169,9 @@ int SharedFunctionInfo::SourceSize() { |
} |
-int SharedFunctionInfo::CalculateInstanceSize() { |
- int instance_size = |
- JSObject::kHeaderSize + |
- expected_nof_properties() * kPointerSize; |
+int SharedFunctionInfo::CalculateInstanceSize(InstanceType instance_type) { |
+ int header_size = JSObject::GetHeaderWithInternalFieldsSize(instance_type); |
+ int instance_size = header_size + expected_nof_properties() * kPointerSize; |
if (instance_size > JSObject::kMaxInstanceSize) { |
instance_size = JSObject::kMaxInstanceSize; |
} |
@@ -12119,8 +12179,10 @@ int SharedFunctionInfo::CalculateInstanceSize() { |
} |
-int SharedFunctionInfo::CalculateInObjectProperties() { |
- return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; |
+int SharedFunctionInfo::CalculateInObjectProperties( |
+ InstanceType instance_type) { |
+ int header_size = JSObject::GetHeaderWithInternalFieldsSize(instance_type); |
+ return (CalculateInstanceSize(instance_type) - header_size) / kPointerSize; |
} |