Index: src/heap.cc |
=================================================================== |
--- src/heap.cc (revision 2708) |
+++ src/heap.cc (working copy) |
@@ -1054,6 +1054,7 @@ |
map->set_constructor(null_value()); |
map->set_instance_size(instance_size); |
map->set_inobject_properties(0); |
+ map->set_pre_allocated_property_fields(0); |
map->set_instance_descriptors(empty_descriptor_array()); |
map->set_code_cache(empty_fixed_array()); |
map->set_unused_property_fields(0); |
@@ -1611,6 +1612,9 @@ |
share->set_start_position_and_type(0); |
share->set_debug_info(undefined_value()); |
share->set_inferred_name(empty_string()); |
+ share->set_compiler_hints(0); |
+ share->set_this_property_assignments_count(0); |
+ share->set_this_property_assignments(undefined_value()); |
return result; |
} |
@@ -2050,16 +2054,10 @@ |
Object* Heap::AllocateInitialMap(JSFunction* fun) { |
ASSERT(!fun->has_initial_map()); |
- // First create a new map with the expected number of properties being |
- // allocated in-object. |
- int expected_nof_properties = fun->shared()->expected_nof_properties(); |
- int instance_size = JSObject::kHeaderSize + |
- expected_nof_properties * kPointerSize; |
- if (instance_size > JSObject::kMaxInstanceSize) { |
- instance_size = JSObject::kMaxInstanceSize; |
- expected_nof_properties = (instance_size - JSObject::kHeaderSize) / |
- kPointerSize; |
- } |
+ // 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(); |
Object* map_obj = Heap::AllocateMap(JS_OBJECT_TYPE, instance_size); |
if (map_obj->IsFailure()) return map_obj; |
@@ -2072,9 +2070,33 @@ |
if (prototype->IsFailure()) return prototype; |
} |
Map* map = Map::cast(map_obj); |
- map->set_inobject_properties(expected_nof_properties); |
- map->set_unused_property_fields(expected_nof_properties); |
+ map->set_inobject_properties(in_object_properties); |
+ map->set_unused_property_fields(in_object_properties); |
map->set_prototype(prototype); |
+ |
+ // If the function has only simple this property assignments add field |
+ // descriptors for these to the initial map as the object cannot be |
+ // constructed without having these properties. |
+ ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields); |
+ if (fun->shared()->has_only_this_property_assignments() && |
+ fun->shared()->this_property_assignments_count() > 0) { |
+ int count = fun->shared()->this_property_assignments_count(); |
+ if (count > in_object_properties) { |
+ count = in_object_properties; |
+ } |
+ DescriptorArray* descriptors = *Factory::NewDescriptorArray(count); |
+ if (descriptors->IsFailure()) return descriptors; |
+ for (int i = 0; i < count; i++) { |
+ String* name = fun->shared()->GetThisPropertyAssignmentName(i); |
+ ASSERT(name->IsSymbol()); |
+ FieldDescriptor field(name, i, NONE); |
+ descriptors->Set(i, &field); |
+ } |
+ descriptors->Sort(); |
+ map->set_instance_descriptors(descriptors); |
+ map->set_pre_allocated_property_fields(count); |
+ map->set_unused_property_fields(in_object_properties - count); |
+ } |
return map; |
} |
@@ -2106,7 +2128,11 @@ |
ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); |
// Allocate the backing storage for the properties. |
- int prop_size = map->unused_property_fields() - map->inobject_properties(); |
+ int prop_size = |
+ map->pre_allocated_property_fields() + |
+ map->unused_property_fields() - |
+ map->inobject_properties(); |
+ ASSERT(prop_size >= 0); |
Object* properties = AllocateFixedArray(prop_size, pretenure); |
if (properties->IsFailure()) return properties; |
@@ -2599,6 +2625,7 @@ |
Object* Heap::AllocateFixedArray(int length) { |
+ ASSERT(length >= 0); |
if (length == 0) return empty_fixed_array(); |
Object* result = AllocateRawFixedArray(length); |
if (!result->IsFailure()) { |