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

Side by Side Diff: src/objects.cc

Issue 447293002: Mark as prototype only after instantiating the function (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/allocation-site-scopes.h" 8 #include "src/allocation-site-scopes.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 7221 matching lines...) Expand 10 before | Expand all | Expand 10 after
7232 new_map->InitializeDescriptors(map->instance_descriptors()); 7232 new_map->InitializeDescriptors(map->instance_descriptors());
7233 } 7233 }
7234 7234
7235 Handle<Name> name = isolate->factory()->observed_symbol(); 7235 Handle<Name> name = isolate->factory()->observed_symbol();
7236 ConnectTransition(map, new_map, name, FULL_TRANSITION); 7236 ConnectTransition(map, new_map, name, FULL_TRANSITION);
7237 7237
7238 return new_map; 7238 return new_map;
7239 } 7239 }
7240 7240
7241 7241
7242 Handle<Map> Map::CopyAsPrototypeMap(Handle<Map> map) {
7243 if (map->is_prototype_map()) return map;
7244 Handle<Map> result = Copy(map);
7245 result->mark_prototype_map();
7246 return result;
7247 }
7248
7249
7250 Handle<Map> Map::Copy(Handle<Map> map) { 7242 Handle<Map> Map::Copy(Handle<Map> map) {
7251 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 7243 Handle<DescriptorArray> descriptors(map->instance_descriptors());
7252 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); 7244 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
7253 Handle<DescriptorArray> new_descriptors = 7245 Handle<DescriptorArray> new_descriptors =
7254 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); 7246 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
7255 return CopyReplaceDescriptors( 7247 return CopyReplaceDescriptors(
7256 map, new_descriptors, OMIT_TRANSITION, MaybeHandle<Name>()); 7248 map, new_descriptors, OMIT_TRANSITION, MaybeHandle<Name>());
7257 } 7249 }
7258 7250
7259 7251
(...skipping 2607 matching lines...) Expand 10 before | Expand all | Expand 10 after
9867 return initial_map; 9859 return initial_map;
9868 } 9860 }
9869 9861
9870 9862
9871 void JSFunction::SetInstancePrototype(Handle<JSFunction> function, 9863 void JSFunction::SetInstancePrototype(Handle<JSFunction> function,
9872 Handle<Object> value) { 9864 Handle<Object> value) {
9873 Isolate* isolate = function->GetIsolate(); 9865 Isolate* isolate = function->GetIsolate();
9874 9866
9875 DCHECK(value->IsJSReceiver()); 9867 DCHECK(value->IsJSReceiver());
9876 9868
9877 // First some logic for the map of the prototype to make sure it is in fast
9878 // mode.
9879 if (value->IsJSObject()) {
9880 Handle<JSObject> js_proto = Handle<JSObject>::cast(value);
9881 JSObject::OptimizeAsPrototype(js_proto);
9882 if (js_proto->HasFastProperties()) {
9883 Handle<Map> new_map = Map::CopyAsPrototypeMap(handle(js_proto->map()));
9884 JSObject::MigrateToMap(js_proto, new_map);
9885 }
9886 }
9887
9888 // Now some logic for the maps of the objects that are created by using this 9869 // Now some logic for the maps of the objects that are created by using this
9889 // function as a constructor. 9870 // function as a constructor.
9890 if (function->has_initial_map()) { 9871 if (function->has_initial_map()) {
9891 // If the function has allocated the initial map replace it with a 9872 // If the function has allocated the initial map replace it with a
9892 // copy containing the new prototype. Also complete any in-object 9873 // copy containing the new prototype. Also complete any in-object
9893 // slack tracking that is in progress at this point because it is 9874 // slack tracking that is in progress at this point because it is
9894 // still tracking the old copy. 9875 // still tracking the old copy.
9895 if (function->IsInobjectSlackTrackingInProgress()) { 9876 if (function->IsInobjectSlackTrackingInProgress()) {
9896 function->CompleteInobjectSlackTracking(); 9877 function->CompleteInobjectSlackTracking();
9897 } 9878 }
9898 Handle<Map> initial_map(function->initial_map(), isolate); 9879 Handle<Map> initial_map(function->initial_map(), isolate);
9899 Handle<Map> new_map = Map::Copy(initial_map); 9880 Handle<Map> new_map = Map::Copy(initial_map);
9900 new_map->set_prototype(*value); 9881 new_map->set_prototype(*value);
9901 9882
9902 // If the function is used as the global Array function, cache the 9883 // If the function is used as the global Array function, cache the
9903 // initial map (and transitioned versions) in the native context. 9884 // initial map (and transitioned versions) in the native context.
9904 Context* native_context = function->context()->native_context(); 9885 Context* native_context = function->context()->native_context();
9905 Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX); 9886 Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX);
9906 if (array_function->IsJSFunction() && 9887 if (array_function->IsJSFunction() &&
9907 *function == JSFunction::cast(array_function)) { 9888 *function == JSFunction::cast(array_function)) {
9908 CacheInitialJSArrayMaps(handle(native_context, isolate), new_map); 9889 CacheInitialJSArrayMaps(handle(native_context, isolate), new_map);
9909 } 9890 }
9910 9891
9911 function->set_initial_map(*new_map); 9892 JSFunction::SetInitialMap(function, new_map);
9912 9893
9913 // Deoptimize all code that embeds the previous initial map. 9894 // Deoptimize all code that embeds the previous initial map.
9914 initial_map->dependent_code()->DeoptimizeDependentCodeGroup( 9895 initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
9915 isolate, DependentCode::kInitialMapChangedGroup); 9896 isolate, DependentCode::kInitialMapChangedGroup);
9916 } else { 9897 } else {
9917 // Put the value in the initial map field until an initial map is 9898 // Put the value in the initial map field until an initial map is
9918 // needed. At that point, a new initial map is created and the 9899 // needed. At that point, a new initial map is created and the
9919 // prototype is put into the initial map where it belongs. 9900 // prototype is put into the initial map where it belongs.
9920 function->set_prototype_or_initial_map(*value); 9901 function->set_prototype_or_initial_map(*value);
9921 } 9902 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
9968 return false; 9949 return false;
9969 } 9950 }
9970 #endif 9951 #endif
9971 9952
9972 set_map(no_prototype_map); 9953 set_map(no_prototype_map);
9973 set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value()); 9954 set_prototype_or_initial_map(no_prototype_map->GetHeap()->the_hole_value());
9974 return true; 9955 return true;
9975 } 9956 }
9976 9957
9977 9958
9959 void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map) {
9960 if (map->prototype()->IsJSObject()) {
9961 Handle<JSObject> js_proto = handle(JSObject::cast(map->prototype()));
9962 if (!js_proto->map()->is_prototype_map() &&
9963 !js_proto->map()->IsGlobalObjectMap() &&
9964 !js_proto->map()->IsJSGlobalProxyMap()) {
9965 // Normalize and turn fast again to make all functions CONSTANT
9966 // properties.
9967 if (!js_proto->GetIsolate()->bootstrapper()->IsActive()) {
9968 JSObject::NormalizeProperties(js_proto, KEEP_INOBJECT_PROPERTIES, 0);
9969 }
9970 if (!js_proto->HasFastProperties()) {
9971 JSObject::MigrateSlowToFast(js_proto, 0);
9972 }
9973 if (js_proto->HasFastProperties()) {
9974 Handle<Map> new_map = Map::Copy(handle(js_proto->map()));
9975 JSObject::MigrateToMap(js_proto, new_map);
9976 js_proto->map()->set_is_prototype_map(true);
9977 }
9978 }
9979 }
9980 function->set_prototype_or_initial_map(*map);
9981 map->set_constructor(*function);
9982 }
9983
9984
9978 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { 9985 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
9979 if (function->has_initial_map()) return; 9986 if (function->has_initial_map()) return;
9980 Isolate* isolate = function->GetIsolate(); 9987 Isolate* isolate = function->GetIsolate();
9981 9988
9982 // First create a new map with the size and number of in-object properties 9989 // First create a new map with the size and number of in-object properties
9983 // suggested by the function. 9990 // suggested by the function.
9984 InstanceType instance_type; 9991 InstanceType instance_type;
9985 int instance_size; 9992 int instance_size;
9986 int in_object_properties; 9993 int in_object_properties;
9987 if (function->shared()->is_generator()) { 9994 if (function->shared()->is_generator()) {
(...skipping 13 matching lines...) Expand all
10001 prototype = handle(function->instance_prototype(), isolate); 10008 prototype = handle(function->instance_prototype(), isolate);
10002 } else { 10009 } else {
10003 prototype = isolate->factory()->NewFunctionPrototype(function); 10010 prototype = isolate->factory()->NewFunctionPrototype(function);
10004 } 10011 }
10005 map->set_inobject_properties(in_object_properties); 10012 map->set_inobject_properties(in_object_properties);
10006 map->set_unused_property_fields(in_object_properties); 10013 map->set_unused_property_fields(in_object_properties);
10007 map->set_prototype(*prototype); 10014 map->set_prototype(*prototype);
10008 DCHECK(map->has_fast_object_elements()); 10015 DCHECK(map->has_fast_object_elements());
10009 10016
10010 // Finally link initial map and constructor function. 10017 // Finally link initial map and constructor function.
10011 function->set_initial_map(*map); 10018 JSFunction::SetInitialMap(function, map);
10012 map->set_constructor(*function);
10013 10019
10014 if (!function->shared()->is_generator()) { 10020 if (!function->shared()->is_generator()) {
10015 function->StartInobjectSlackTracking(); 10021 function->StartInobjectSlackTracking();
10016 } 10022 }
10017 } 10023 }
10018 10024
10019 10025
10020 void JSFunction::SetInstanceClassName(String* name) { 10026 void JSFunction::SetInstanceClassName(String* name) {
10021 shared()->set_instance_class_name(name); 10027 shared()->set_instance_class_name(name);
10022 } 10028 }
(...skipping 6867 matching lines...) Expand 10 before | Expand all | Expand 10 after
16890 #define ERROR_MESSAGES_TEXTS(C, T) T, 16896 #define ERROR_MESSAGES_TEXTS(C, T) T,
16891 static const char* error_messages_[] = { 16897 static const char* error_messages_[] = {
16892 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16898 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16893 }; 16899 };
16894 #undef ERROR_MESSAGES_TEXTS 16900 #undef ERROR_MESSAGES_TEXTS
16895 return error_messages_[reason]; 16901 return error_messages_[reason];
16896 } 16902 }
16897 16903
16898 16904
16899 } } // namespace v8::internal 16905 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698