| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |