Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/heap.cc

Issue 13192004: arrange to create prototypes for generators (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Explicitly add constructor properties in generator.js Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3945 matching lines...) Expand 10 before | Expand all | Expand 10 after
3956 function->set_shared(shared); 3956 function->set_shared(shared);
3957 function->set_code(shared->code()); 3957 function->set_code(shared->code());
3958 function->set_prototype_or_initial_map(prototype); 3958 function->set_prototype_or_initial_map(prototype);
3959 function->set_context(undefined_value()); 3959 function->set_context(undefined_value());
3960 function->set_literals_or_bindings(empty_fixed_array()); 3960 function->set_literals_or_bindings(empty_fixed_array());
3961 function->set_next_function_link(undefined_value()); 3961 function->set_next_function_link(undefined_value());
3962 } 3962 }
3963 3963
3964 3964
3965 MaybeObject* Heap::AllocateFunctionPrototype(JSFunction* function) { 3965 MaybeObject* Heap::AllocateFunctionPrototype(JSFunction* function) {
3966 // Allocate the prototype. Make sure to use the object function 3966 // Make sure to use globals from the function's context, since the function
3967 // from the function's context, since the function can be from a 3967 // can be from a different context.
3968 // different context. 3968 Context* native_context = function->context()->native_context();
3969 JSFunction* object_function = 3969 bool needs_constructor_property;
3970 function->context()->native_context()->object_function();
3971
3972 // Each function prototype gets a copy of the object function map.
3973 // This avoid unwanted sharing of maps between prototypes of different
3974 // constructors.
3975 Map* new_map; 3970 Map* new_map;
3976 ASSERT(object_function->has_initial_map()); 3971 if (function->shared()->is_generator()) {
3977 MaybeObject* maybe_map = object_function->initial_map()->Copy(); 3972 // Generator prototypes can share maps since they don't have "constructor"
3978 if (!maybe_map->To(&new_map)) return maybe_map; 3973 // properties.
3974 new_map = native_context->generator_object_prototype_map();
3975 needs_constructor_property = false;
3976 } else {
3977 // Each function prototype gets a fresh map to avoid unwanted sharing of
3978 // maps between prototypes of different constructors.
3979 JSFunction* object_function = native_context->object_function();
3980 ASSERT(object_function->has_initial_map());
3981 MaybeObject* maybe_map = object_function->initial_map()->Copy();
3982 if (!maybe_map->To(&new_map)) return maybe_map;
3983 needs_constructor_property = true;
3984 }
3979 3985
3980 Object* prototype; 3986 Object* prototype;
3981 MaybeObject* maybe_prototype = AllocateJSObjectFromMap(new_map); 3987 MaybeObject* maybe_prototype = AllocateJSObjectFromMap(new_map);
3982 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; 3988 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
3983 3989
3984 // When creating the prototype for the function we must set its 3990 if (needs_constructor_property) {
3985 // constructor to the function. 3991 MaybeObject* maybe_failure =
3986 MaybeObject* maybe_failure = 3992 JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributes(
3987 JSObject::cast(prototype)->SetLocalPropertyIgnoreAttributes( 3993 constructor_string(), function, DONT_ENUM);
3988 constructor_string(), function, DONT_ENUM); 3994 if (maybe_failure->IsFailure()) return maybe_failure;
3989 if (maybe_failure->IsFailure()) return maybe_failure; 3995 }
3990 3996
3991 return prototype; 3997 return prototype;
3992 } 3998 }
3993 3999
3994 4000
3995 MaybeObject* Heap::AllocateFunction(Map* function_map, 4001 MaybeObject* Heap::AllocateFunction(Map* function_map,
3996 SharedFunctionInfo* shared, 4002 SharedFunctionInfo* shared,
3997 Object* prototype, 4003 Object* prototype,
3998 PretenureFlag pretenure) { 4004 PretenureFlag pretenure) {
3999 AllocationSpace space = 4005 AllocationSpace space =
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
4079 } 4085 }
4080 return false; 4086 return false;
4081 } 4087 }
4082 4088
4083 4089
4084 MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) { 4090 MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) {
4085 ASSERT(!fun->has_initial_map()); 4091 ASSERT(!fun->has_initial_map());
4086 4092
4087 // First create a new map with the size and number of in-object properties 4093 // First create a new map with the size and number of in-object properties
4088 // suggested by the function. 4094 // suggested by the function.
4089 int instance_size = fun->shared()->CalculateInstanceSize(); 4095 InstanceType instance_type;
4090 int in_object_properties = fun->shared()->CalculateInObjectProperties(); 4096 int instance_size;
4097 int in_object_properties;
4098 if (fun->shared()->is_generator()) {
4099 // TODO(wingo): Replace with JS_GENERATOR_OBJECT_TYPE.
4100 instance_type = JS_OBJECT_TYPE;
4101 instance_size = JSObject::kHeaderSize;
4102 in_object_properties = 0;
4103 } else {
4104 instance_type = JS_OBJECT_TYPE;
4105 instance_size = fun->shared()->CalculateInstanceSize();
4106 in_object_properties = fun->shared()->CalculateInObjectProperties();
4107 }
4091 Map* map; 4108 Map* map;
4092 MaybeObject* maybe_map = AllocateMap(JS_OBJECT_TYPE, instance_size); 4109 MaybeObject* maybe_map = AllocateMap(instance_type, instance_size);
4093 if (!maybe_map->To(&map)) return maybe_map; 4110 if (!maybe_map->To(&map)) return maybe_map;
4094 4111
4095 // Fetch or allocate prototype. 4112 // Fetch or allocate prototype.
4096 Object* prototype; 4113 Object* prototype;
4097 if (fun->has_instance_prototype()) { 4114 if (fun->has_instance_prototype()) {
4098 prototype = fun->instance_prototype(); 4115 prototype = fun->instance_prototype();
4099 } else { 4116 } else {
4100 MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun); 4117 MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun);
4101 if (!maybe_prototype->To(&prototype)) return maybe_prototype; 4118 if (!maybe_prototype->To(&prototype)) return maybe_prototype;
4102 } 4119 }
4103 map->set_inobject_properties(in_object_properties); 4120 map->set_inobject_properties(in_object_properties);
4104 map->set_unused_property_fields(in_object_properties); 4121 map->set_unused_property_fields(in_object_properties);
4105 map->set_prototype(prototype); 4122 map->set_prototype(prototype);
4106 ASSERT(map->has_fast_object_elements()); 4123 ASSERT(map->has_fast_object_elements());
4107 4124
4108 // If the function has only simple this property assignments add 4125 // If the function has only simple this property assignments add
4109 // field descriptors for these to the initial map as the object 4126 // field descriptors for these to the initial map as the object
4110 // cannot be constructed without having these properties. Guard by 4127 // cannot be constructed without having these properties. Guard by
4111 // the inline_new flag so we only change the map if we generate a 4128 // the inline_new flag so we only change the map if we generate a
4112 // specialized construct stub. 4129 // specialized construct stub.
4113 ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields); 4130 ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields);
4114 if (fun->shared()->CanGenerateInlineConstructor(prototype)) { 4131 if (instance_type == JS_OBJECT_TYPE &&
4132 fun->shared()->CanGenerateInlineConstructor(prototype)) {
4115 int count = fun->shared()->this_property_assignments_count(); 4133 int count = fun->shared()->this_property_assignments_count();
4116 if (count > in_object_properties) { 4134 if (count > in_object_properties) {
4117 // Inline constructor can only handle inobject properties. 4135 // Inline constructor can only handle inobject properties.
4118 fun->shared()->ForbidInlineConstructor(); 4136 fun->shared()->ForbidInlineConstructor();
4119 } else { 4137 } else {
4120 DescriptorArray* descriptors; 4138 DescriptorArray* descriptors;
4121 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(count); 4139 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(count);
4122 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; 4140 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
4123 4141
4124 DescriptorArray::WhitenessWitness witness(descriptors); 4142 DescriptorArray::WhitenessWitness witness(descriptors);
(...skipping 12 matching lines...) Expand all
4137 if (HasDuplicates(descriptors)) { 4155 if (HasDuplicates(descriptors)) {
4138 fun->shared()->ForbidInlineConstructor(); 4156 fun->shared()->ForbidInlineConstructor();
4139 } else { 4157 } else {
4140 map->InitializeDescriptors(descriptors); 4158 map->InitializeDescriptors(descriptors);
4141 map->set_pre_allocated_property_fields(count); 4159 map->set_pre_allocated_property_fields(count);
4142 map->set_unused_property_fields(in_object_properties - count); 4160 map->set_unused_property_fields(in_object_properties - count);
4143 } 4161 }
4144 } 4162 }
4145 } 4163 }
4146 4164
4147 fun->shared()->StartInobjectSlackTracking(map); 4165 if (instance_type == JS_OBJECT_TYPE) {
4166 fun->shared()->StartInobjectSlackTracking(map);
4167 }
4148 4168
4149 return map; 4169 return map;
4150 } 4170 }
4151 4171
4152 4172
4153 void Heap::InitializeJSObjectFromMap(JSObject* obj, 4173 void Heap::InitializeJSObjectFromMap(JSObject* obj,
4154 FixedArray* properties, 4174 FixedArray* properties,
4155 Map* map) { 4175 Map* map) {
4156 obj->set_properties(properties); 4176 obj->set_properties(properties);
4157 obj->initialize_elements(); 4177 obj->initialize_elements();
(...skipping 3662 matching lines...) Expand 10 before | Expand all | Expand 10 after
7820 static_cast<int>(object_sizes_last_time_[index])); 7840 static_cast<int>(object_sizes_last_time_[index]));
7821 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) 7841 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
7822 #undef ADJUST_LAST_TIME_OBJECT_COUNT 7842 #undef ADJUST_LAST_TIME_OBJECT_COUNT
7823 7843
7824 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 7844 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
7825 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 7845 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
7826 ClearObjectStats(); 7846 ClearObjectStats();
7827 } 7847 }
7828 7848
7829 } } // namespace v8::internal 7849 } } // namespace v8::internal
OLDNEW
« src/generator.js ('K') | « src/generator.js ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698