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 |