| 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 <iomanip> | 5 #include <iomanip> |
| 6 #include <sstream> | 6 #include <sstream> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
| (...skipping 9887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9898 // static | 9898 // static |
| 9899 void JSObject::OptimizeAsPrototype(Handle<JSObject> object, | 9899 void JSObject::OptimizeAsPrototype(Handle<JSObject> object, |
| 9900 PrototypeOptimizationMode mode) { | 9900 PrototypeOptimizationMode mode) { |
| 9901 if (object->IsGlobalObject()) return; | 9901 if (object->IsGlobalObject()) return; |
| 9902 if (object->IsJSGlobalProxy()) return; | 9902 if (object->IsJSGlobalProxy()) return; |
| 9903 if (mode == FAST_PROTOTYPE && PrototypeBenefitsFromNormalization(object)) { | 9903 if (mode == FAST_PROTOTYPE && PrototypeBenefitsFromNormalization(object)) { |
| 9904 // First normalize to ensure all JSFunctions are DATA_CONSTANT. | 9904 // First normalize to ensure all JSFunctions are DATA_CONSTANT. |
| 9905 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0, | 9905 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0, |
| 9906 "NormalizeAsPrototype"); | 9906 "NormalizeAsPrototype"); |
| 9907 } | 9907 } |
| 9908 Handle<Map> previous_map(object->map()); | 9908 Isolate* isolate = object->GetIsolate(); |
| 9909 Handle<Map> previous_map(object->map(), isolate); |
| 9909 if (!object->HasFastProperties()) { | 9910 if (!object->HasFastProperties()) { |
| 9910 JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype"); | 9911 JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype"); |
| 9911 } | 9912 } |
| 9912 if (!object->map()->is_prototype_map()) { | 9913 if (!object->map()->is_prototype_map()) { |
| 9913 if (object->map() == *previous_map) { | 9914 if (object->map() == *previous_map) { |
| 9914 Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype"); | 9915 Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype"); |
| 9915 JSObject::MigrateToMap(object, new_map); | 9916 JSObject::MigrateToMap(object, new_map); |
| 9916 } | 9917 } |
| 9917 Object* maybe_constructor = object->map()->GetConstructor(); | 9918 Object* maybe_constructor = object->map()->GetConstructor(); |
| 9918 if (maybe_constructor->IsJSFunction()) { | 9919 if (maybe_constructor->IsJSFunction()) { |
| 9919 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 9920 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
| 9920 // Replace the pointer to the exact constructor with the Object function | 9921 // Replace the pointer to the exact constructor with the Object function |
| 9921 // from the same context if undetectable from JS. This is to avoid keeping | 9922 // from the same context if undetectable from JS. This is to avoid keeping |
| 9922 // memory alive unnecessarily. | 9923 // memory alive unnecessarily. |
| 9923 if (!constructor->shared()->IsApiFunction() && | 9924 if (!constructor->shared()->IsApiFunction() && |
| 9924 object->class_name() == | 9925 object->class_name() == isolate->heap()->Object_string()) { |
| 9925 object->GetIsolate()->heap()->Object_string()) { | |
| 9926 Context* context = constructor->context()->native_context(); | 9926 Context* context = constructor->context()->native_context(); |
| 9927 JSFunction* object_function = context->object_function(); | 9927 JSFunction* object_function = context->object_function(); |
| 9928 object->map()->SetConstructor(object_function); | 9928 object->map()->SetConstructor(object_function); |
| 9929 } | 9929 } |
| 9930 } | 9930 } |
| 9931 object->map()->set_is_prototype_map(true); | 9931 object->map()->set_is_prototype_map(true); |
| 9932 } | 9932 } |
| 9933 Handle<Map> new_map(object->map(), isolate); |
| 9934 Map::SetPrototypeObject(new_map, object, isolate); |
| 9933 } | 9935 } |
| 9934 | 9936 |
| 9935 | 9937 |
| 9936 // static | 9938 // static |
| 9937 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { | 9939 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { |
| 9938 if (!object->map()->is_prototype_map()) return; | 9940 if (!object->map()->is_prototype_map()) return; |
| 9939 OptimizeAsPrototype(object, FAST_PROTOTYPE); | 9941 OptimizeAsPrototype(object, FAST_PROTOTYPE); |
| 9940 } | 9942 } |
| 9941 | 9943 |
| 9942 | 9944 |
| 9943 // static | 9945 // static |
| 9944 void JSObject::RegisterPrototypeUser(Handle<JSObject> prototype, | 9946 void JSObject::RegisterPrototypeUser(Handle<JSObject> prototype, |
| 9945 Handle<HeapObject> user) { | 9947 Handle<HeapObject> user) { |
| 9946 DCHECK(FLAG_track_prototype_users); | 9948 DCHECK(FLAG_track_prototype_users); |
| 9947 Isolate* isolate = prototype->GetIsolate(); | 9949 Isolate* isolate = prototype->GetIsolate(); |
| 9948 if (prototype->IsJSGlobalProxy()) { | 9950 if (prototype->IsJSGlobalProxy()) { |
| 9949 prototype = handle(JSObject::cast(prototype->map()->prototype()), isolate); | 9951 prototype = handle(JSObject::cast(prototype->map()->prototype()), isolate); |
| 9950 } | 9952 } |
| 9951 Handle<PrototypeInfo> proto_info; | 9953 Handle<Map> proto_map(prototype->map(), isolate); |
| 9952 Object* maybe_proto_info = prototype->map()->prototype_info(); | 9954 Handle<PrototypeInfo> proto_info = |
| 9953 if (maybe_proto_info->IsPrototypeInfo()) { | 9955 Map::GetOrCreatePrototypeInfo(proto_map, isolate); |
| 9954 proto_info = handle(PrototypeInfo::cast(maybe_proto_info), isolate); | 9956 proto_info->set_prototype_object(*prototype); |
| 9955 } else { | |
| 9956 proto_info = isolate->factory()->NewPrototypeInfo(prototype); | |
| 9957 prototype->map()->set_prototype_info(*proto_info); | |
| 9958 } | |
| 9959 Handle<Object> maybe_registry(proto_info->prototype_users(), isolate); | 9957 Handle<Object> maybe_registry(proto_info->prototype_users(), isolate); |
| 9960 Handle<WeakFixedArray> new_array = WeakFixedArray::Add(maybe_registry, user); | 9958 Handle<WeakFixedArray> new_array = WeakFixedArray::Add(maybe_registry, user); |
| 9961 if (!maybe_registry.is_identical_to(new_array)) { | 9959 if (!maybe_registry.is_identical_to(new_array)) { |
| 9962 proto_info->set_prototype_users(*new_array); | 9960 proto_info->set_prototype_users(*new_array); |
| 9963 } | 9961 } |
| 9964 } | 9962 } |
| 9965 | 9963 |
| 9966 | 9964 |
| 9967 // static | 9965 // static |
| 9968 void JSObject::UnregisterPrototypeUser(Handle<JSObject> prototype, | 9966 void JSObject::UnregisterPrototypeUser(Handle<JSObject> prototype, |
| 9969 Handle<HeapObject> user) { | 9967 Handle<HeapObject> user) { |
| 9970 Isolate* isolate = prototype->GetIsolate(); | 9968 Isolate* isolate = prototype->GetIsolate(); |
| 9971 if (prototype->IsJSGlobalProxy()) { | 9969 if (prototype->IsJSGlobalProxy()) { |
| 9972 prototype = handle(JSObject::cast(prototype->map()->prototype()), isolate); | 9970 prototype = handle(JSObject::cast(prototype->map()->prototype()), isolate); |
| 9973 } | 9971 } |
| 9974 DCHECK(prototype->map()->is_prototype_map()); | 9972 DCHECK(prototype->map()->is_prototype_map()); |
| 9975 Object* maybe_proto_info = prototype->map()->prototype_info(); | 9973 Object* maybe_proto_info = prototype->map()->prototype_info(); |
| 9976 if (!maybe_proto_info->IsPrototypeInfo()) return; | 9974 if (!maybe_proto_info->IsPrototypeInfo()) return; |
| 9977 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info), | 9975 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info), |
| 9978 isolate); | 9976 isolate); |
| 9979 Object* maybe_registry = proto_info->prototype_users(); | 9977 Object* maybe_registry = proto_info->prototype_users(); |
| 9980 if (!maybe_registry->IsWeakFixedArray()) return; | 9978 if (!maybe_registry->IsWeakFixedArray()) return; |
| 9981 WeakFixedArray::cast(maybe_registry)->Remove(user); | 9979 WeakFixedArray::cast(maybe_registry)->Remove(user); |
| 9982 } | 9980 } |
| 9983 | 9981 |
| 9984 | 9982 |
| 9985 // static | 9983 // static |
| 9984 Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<Map> map, |
| 9985 Isolate* isolate) { |
| 9986 Object* maybe_proto_info = map->prototype_info(); |
| 9987 if (maybe_proto_info->IsPrototypeInfo()) { |
| 9988 return handle(PrototypeInfo::cast(maybe_proto_info), isolate); |
| 9989 } |
| 9990 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo(); |
| 9991 map->set_prototype_info(*proto_info); |
| 9992 return proto_info; |
| 9993 } |
| 9994 |
| 9995 |
| 9996 // static |
| 9997 void Map::SetPrototypeObject(Handle<Map> map, Handle<JSObject> prototype_obj, |
| 9998 Isolate* isolate) { |
| 9999 if (!FLAG_track_prototype_users) return; |
| 10000 Handle<PrototypeInfo> proto_info = GetOrCreatePrototypeInfo(map, isolate); |
| 10001 proto_info->set_prototype_object(*prototype_obj); |
| 10002 } |
| 10003 |
| 10004 |
| 10005 Object* Map::GetPrototypeObject() { |
| 10006 DisallowHeapAllocation no_handlification_required; |
| 10007 if (!is_prototype_map()) return Smi::FromInt(0); |
| 10008 Object* maybe_prototype_info = prototype_info(); |
| 10009 if (!maybe_prototype_info->IsPrototypeInfo()) return Smi::FromInt(0); |
| 10010 PrototypeInfo* proto_info = PrototypeInfo::cast(maybe_prototype_info); |
| 10011 Object* maybe_obj = proto_info->prototype_object(); |
| 10012 if (maybe_obj->IsSmi()) return maybe_obj; |
| 10013 JSObject* object = JSObject::cast(maybe_obj); |
| 10014 if (object->map() != this) { |
| 10015 proto_info->set_prototype_object(Smi::FromInt(0)); |
| 10016 return Smi::FromInt(0); |
| 10017 } |
| 10018 return object; |
| 10019 } |
| 10020 |
| 10021 |
| 10022 // static |
| 9986 void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype, | 10023 void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype, |
| 9987 PrototypeOptimizationMode proto_mode) { | 10024 PrototypeOptimizationMode proto_mode) { |
| 9988 if (map->prototype()->IsJSObject() && FLAG_track_prototype_users) { | 10025 if (map->prototype()->IsJSObject() && FLAG_track_prototype_users) { |
| 9989 Handle<JSObject> old_prototype(JSObject::cast(map->prototype())); | 10026 Handle<JSObject> old_prototype(JSObject::cast(map->prototype())); |
| 9990 JSObject::UnregisterPrototypeUser(old_prototype, map); | 10027 JSObject::UnregisterPrototypeUser(old_prototype, map); |
| 9991 } | 10028 } |
| 9992 if (prototype->IsJSObject()) { | 10029 if (prototype->IsJSObject()) { |
| 9993 Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype); | 10030 Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype); |
| 9994 if (ShouldRegisterAsPrototypeUser(map, prototype_jsobj)) { | 10031 if (ShouldRegisterAsPrototypeUser(map, prototype_jsobj)) { |
| 9995 JSObject::RegisterPrototypeUser(prototype_jsobj, map); | 10032 JSObject::RegisterPrototypeUser(prototype_jsobj, map); |
| (...skipping 7123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17119 CompilationInfo* info) { | 17156 CompilationInfo* info) { |
| 17120 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( | 17157 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
| 17121 handle(cell->dependent_code(), info->isolate()), | 17158 handle(cell->dependent_code(), info->isolate()), |
| 17122 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); | 17159 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
| 17123 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17160 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 17124 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17161 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 17125 cell, info->zone()); | 17162 cell, info->zone()); |
| 17126 } | 17163 } |
| 17127 | 17164 |
| 17128 } } // namespace v8::internal | 17165 } } // namespace v8::internal |
| OLD | NEW |