Index: src/heap.cc |
diff --git a/src/heap.cc b/src/heap.cc |
index fafcb64d370a8ba6c11f87dd4c882456ea903cec..d2553376361118bf5a887d59ba1fa91975db15fa 100644 |
--- a/src/heap.cc |
+++ b/src/heap.cc |
@@ -3963,30 +3963,36 @@ void Heap::InitializeFunction(JSFunction* function, |
MaybeObject* Heap::AllocateFunctionPrototype(JSFunction* function) { |
- // Allocate the prototype. Make sure to use the object function |
- // from the function's context, since the function can be from a |
- // different context. |
- JSFunction* object_function = |
- function->context()->native_context()->object_function(); |
- |
- // Each function prototype gets a copy of the object function map. |
- // This avoid unwanted sharing of maps between prototypes of different |
- // constructors. |
+ // Make sure to use globals from the function's context, since the function |
+ // can be from a different context. |
+ Context* native_context = function->context()->native_context(); |
+ bool needs_constructor_property; |
Map* new_map; |
- ASSERT(object_function->has_initial_map()); |
- MaybeObject* maybe_map = object_function->initial_map()->Copy(); |
- if (!maybe_map->To(&new_map)) return maybe_map; |
+ if (function->shared()->is_generator()) { |
+ // Generator prototypes can share maps since they don't have "constructor" |
+ // properties. |
+ new_map = native_context->generator_object_prototype_map(); |
+ needs_constructor_property = false; |
+ } else { |
+ // Each function prototype gets a fresh map to avoid unwanted sharing of |
+ // maps between prototypes of different constructors. |
+ JSFunction* object_function = native_context->object_function(); |
+ ASSERT(object_function->has_initial_map()); |
+ MaybeObject* maybe_map = object_function->initial_map()->Copy(); |
+ if (!maybe_map->To(&new_map)) return maybe_map; |
+ needs_constructor_property = true; |
+ } |
Object* prototype; |
MaybeObject* maybe_prototype = AllocateJSObjectFromMap(new_map); |
if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; |
- // When creating the prototype for the function we must set its |
- // constructor to the function. |
- MaybeObject* maybe_failure = |
- JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributes( |
- constructor_string(), function, DONT_ENUM); |
- if (maybe_failure->IsFailure()) return maybe_failure; |
+ if (needs_constructor_property) { |
+ MaybeObject* maybe_failure = |
+ JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributes( |
+ constructor_string(), function, DONT_ENUM); |
+ if (maybe_failure->IsFailure()) return maybe_failure; |
+ } |
return prototype; |
} |
@@ -4086,10 +4092,21 @@ MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) { |
// First create a new map with the size and number of in-object properties |
// suggested by the function. |
- int instance_size = fun->shared()->CalculateInstanceSize(); |
- int in_object_properties = fun->shared()->CalculateInObjectProperties(); |
+ InstanceType instance_type; |
+ int instance_size; |
+ int in_object_properties; |
+ if (fun->shared()->is_generator()) { |
+ // TODO(wingo): Replace with JS_GENERATOR_OBJECT_TYPE. |
+ instance_type = JS_OBJECT_TYPE; |
+ instance_size = JSObject::kHeaderSize; |
+ in_object_properties = 0; |
+ } else { |
+ instance_type = JS_OBJECT_TYPE; |
+ instance_size = fun->shared()->CalculateInstanceSize(); |
+ in_object_properties = fun->shared()->CalculateInObjectProperties(); |
+ } |
Map* map; |
- MaybeObject* maybe_map = AllocateMap(JS_OBJECT_TYPE, instance_size); |
+ MaybeObject* maybe_map = AllocateMap(instance_type, instance_size); |
if (!maybe_map->To(&map)) return maybe_map; |
// Fetch or allocate prototype. |
@@ -4111,7 +4128,8 @@ MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) { |
// the inline_new flag so we only change the map if we generate a |
// specialized construct stub. |
ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields); |
- if (fun->shared()->CanGenerateInlineConstructor(prototype)) { |
+ if (instance_type == JS_OBJECT_TYPE && |
+ fun->shared()->CanGenerateInlineConstructor(prototype)) { |
int count = fun->shared()->this_property_assignments_count(); |
if (count > in_object_properties) { |
// Inline constructor can only handle inobject properties. |
@@ -4144,7 +4162,9 @@ MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) { |
} |
} |
- fun->shared()->StartInobjectSlackTracking(map); |
+ if (instance_type == JS_OBJECT_TYPE) { |
+ fun->shared()->StartInobjectSlackTracking(map); |
+ } |
return map; |
} |