Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 11831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11842 if (details.location() == kDescriptor) continue; | 11842 if (details.location() == kDescriptor) continue; |
| 11843 if (details.representation().IsHeapObject() || | 11843 if (details.representation().IsHeapObject() || |
| 11844 details.representation().IsTagged()) { | 11844 details.representation().IsTagged()) { |
| 11845 FieldIndex index = FieldIndex::ForDescriptor(map, i); | 11845 FieldIndex index = FieldIndex::ForDescriptor(map, i); |
| 11846 if (object->RawFastPropertyAt(index)->IsJSFunction()) return true; | 11846 if (object->RawFastPropertyAt(index)->IsJSFunction()) return true; |
| 11847 } | 11847 } |
| 11848 } | 11848 } |
| 11849 return false; | 11849 return false; |
| 11850 } | 11850 } |
| 11851 | 11851 |
| 11852 // static | |
| 11853 void JSObject::MakePrototypesFast(Handle<Object> receiver, | |
| 11854 bool include_receiver, Isolate* isolate) { | |
| 11855 if (!receiver->IsJSReceiver()) return; | |
| 11856 PrototypeIterator::WhereToStart start = | |
| 11857 include_receiver ? PrototypeIterator::START_AT_RECEIVER | |
| 11858 : PrototypeIterator::START_AT_PROTOTYPE; | |
| 11859 for (PrototypeIterator iter(isolate, Handle<JSReceiver>::cast(receiver), | |
| 11860 start); | |
| 11861 !iter.IsAtEnd(); iter.Advance()) { | |
| 11862 Handle<Object> current = PrototypeIterator::GetCurrent(iter); | |
| 11863 if (!current->IsJSObject()) return; | |
| 11864 Handle<JSObject> current_obj = Handle<JSObject>::cast(current); | |
| 11865 Map* current_map = current_obj->map(); | |
| 11866 if (current_map->is_prototype_map() && | |
| 11867 !current_map->should_be_fast_prototype_map()) { | |
| 11868 Handle<Map> map(current_map); | |
| 11869 Map::SetShouldBeFastPrototypeMap(map, true, isolate); | |
| 11870 JSObject::OptimizeAsPrototype(current_obj, FAST_PROTOTYPE); | |
| 11871 } | |
| 11872 } | |
| 11873 } | |
| 11852 | 11874 |
| 11853 // static | 11875 // static |
| 11854 void JSObject::OptimizeAsPrototype(Handle<JSObject> object, | 11876 void JSObject::OptimizeAsPrototype(Handle<JSObject> object, |
| 11855 PrototypeOptimizationMode mode) { | 11877 PrototypeOptimizationMode mode) { |
| 11856 if (object->IsJSGlobalObject()) return; | 11878 if (object->IsJSGlobalObject()) return; |
| 11857 if (mode == FAST_PROTOTYPE && PrototypeBenefitsFromNormalization(object)) { | 11879 if (mode == FAST_PROTOTYPE && PrototypeBenefitsFromNormalization(object)) { |
| 11858 // First normalize to ensure all JSFunctions are DATA_CONSTANT. | 11880 // First normalize to ensure all JSFunctions are DATA_CONSTANT. |
| 11859 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0, | 11881 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0, |
| 11860 "NormalizeAsPrototype"); | 11882 "NormalizeAsPrototype"); |
| 11861 } | 11883 } |
| 11862 Handle<Map> previous_map(object->map()); | 11884 Handle<Map> previous_map(object->map()); |
| 11863 if (!object->HasFastProperties()) { | 11885 if (object->map()->is_prototype_map()) { |
| 11864 JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype"); | 11886 if (object->map()->should_be_fast_prototype_map() && |
| 11865 } | 11887 !object->HasFastProperties()) { |
| 11866 if (!object->map()->is_prototype_map()) { | 11888 JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype"); |
| 11889 } | |
| 11890 } else { | |
| 11867 if (object->map() == *previous_map) { | 11891 if (object->map() == *previous_map) { |
| 11868 Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype"); | 11892 Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype"); |
| 11869 JSObject::MigrateToMap(object, new_map); | 11893 JSObject::MigrateToMap(object, new_map); |
| 11870 } | 11894 } |
| 11871 object->map()->set_is_prototype_map(true); | 11895 object->map()->set_is_prototype_map(true); |
| 11872 | 11896 |
| 11873 // Replace the pointer to the exact constructor with the Object function | 11897 // Replace the pointer to the exact constructor with the Object function |
| 11874 // from the same context if undetectable from JS. This is to avoid keeping | 11898 // from the same context if undetectable from JS. This is to avoid keeping |
| 11875 // memory alive unnecessarily. | 11899 // memory alive unnecessarily. |
| 11876 Object* maybe_constructor = object->map()->GetConstructor(); | 11900 Object* maybe_constructor = object->map()->GetConstructor(); |
| 11877 if (maybe_constructor->IsJSFunction()) { | 11901 if (maybe_constructor->IsJSFunction()) { |
| 11878 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 11902 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
| 11879 Isolate* isolate = object->GetIsolate(); | 11903 Isolate* isolate = object->GetIsolate(); |
| 11880 if (!constructor->shared()->IsApiFunction() && | 11904 if (!constructor->shared()->IsApiFunction() && |
| 11881 object->class_name() == isolate->heap()->Object_string()) { | 11905 object->class_name() == isolate->heap()->Object_string()) { |
| 11882 Context* context = constructor->context()->native_context(); | 11906 Context* context = constructor->context()->native_context(); |
| 11883 JSFunction* object_function = context->object_function(); | 11907 JSFunction* object_function = context->object_function(); |
| 11884 object->map()->SetConstructor(object_function); | 11908 object->map()->SetConstructor(object_function); |
| 11885 } | 11909 } |
| 11886 } | 11910 } |
| 11887 } | 11911 } |
| 11888 } | 11912 } |
| 11889 | 11913 |
| 11890 | 11914 |
| 11891 // static | 11915 // static |
| 11892 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { | 11916 void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) { |
| 11893 if (!object->map()->is_prototype_map()) return; | 11917 if (!object->map()->is_prototype_map()) return; |
| 11918 if (!object->map()->should_be_fast_prototype_map()) return; | |
| 11894 OptimizeAsPrototype(object, FAST_PROTOTYPE); | 11919 OptimizeAsPrototype(object, FAST_PROTOTYPE); |
| 11895 } | 11920 } |
| 11896 | 11921 |
| 11897 | 11922 |
| 11898 // static | 11923 // static |
| 11899 void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) { | 11924 void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) { |
| 11900 // Contract: In line with InvalidatePrototypeChains()'s requirements, | 11925 // Contract: In line with InvalidatePrototypeChains()'s requirements, |
| 11901 // leaf maps don't need to register as users, only prototypes do. | 11926 // leaf maps don't need to register as users, only prototypes do. |
| 11902 DCHECK(user->is_prototype_map()); | 11927 DCHECK(user->is_prototype_map()); |
| 11903 | 11928 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12025 Isolate* isolate) { | 12050 Isolate* isolate) { |
| 12026 Object* maybe_proto_info = prototype_map->prototype_info(); | 12051 Object* maybe_proto_info = prototype_map->prototype_info(); |
| 12027 if (maybe_proto_info->IsPrototypeInfo()) { | 12052 if (maybe_proto_info->IsPrototypeInfo()) { |
| 12028 return handle(PrototypeInfo::cast(maybe_proto_info), isolate); | 12053 return handle(PrototypeInfo::cast(maybe_proto_info), isolate); |
| 12029 } | 12054 } |
| 12030 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo(); | 12055 Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo(); |
| 12031 prototype_map->set_prototype_info(*proto_info); | 12056 prototype_map->set_prototype_info(*proto_info); |
| 12032 return proto_info; | 12057 return proto_info; |
| 12033 } | 12058 } |
| 12034 | 12059 |
| 12060 // static | |
| 12061 void Map::SetShouldBeFastPrototypeMap(Handle<Map> map, bool value, | |
| 12062 Isolate* isolate) { | |
| 12063 GetOrCreatePrototypeInfo(map, isolate)->set_should_be_fast_map(value); | |
|
Toon Verwaest
2016/06/07 14:48:06
If the bool is false, should we really allocate a
Jakob Kummerow
2016/06/08 12:18:59
Good point (although it never happens currently).
| |
| 12064 } | |
| 12035 | 12065 |
| 12036 // static | 12066 // static |
| 12037 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, | 12067 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, |
| 12038 Isolate* isolate) { | 12068 Isolate* isolate) { |
| 12039 Handle<Object> maybe_prototype(map->prototype(), isolate); | 12069 Handle<Object> maybe_prototype(map->prototype(), isolate); |
| 12040 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null(); | 12070 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null(); |
| 12041 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype); | 12071 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype); |
| 12042 // Ensure the prototype is registered with its own prototypes so its cell | 12072 // Ensure the prototype is registered with its own prototypes so its cell |
| 12043 // will be invalidated when necessary. | 12073 // will be invalidated when necessary. |
| 12044 JSObject::LazyRegisterPrototypeUser(handle(prototype->map(), isolate), | 12074 JSObject::LazyRegisterPrototypeUser(handle(prototype->map(), isolate), |
| (...skipping 6773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 18818 if (cell->value() != *new_value) { | 18848 if (cell->value() != *new_value) { |
| 18819 cell->set_value(*new_value); | 18849 cell->set_value(*new_value); |
| 18820 Isolate* isolate = cell->GetIsolate(); | 18850 Isolate* isolate = cell->GetIsolate(); |
| 18821 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18851 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 18822 isolate, DependentCode::kPropertyCellChangedGroup); | 18852 isolate, DependentCode::kPropertyCellChangedGroup); |
| 18823 } | 18853 } |
| 18824 } | 18854 } |
| 18825 | 18855 |
| 18826 } // namespace internal | 18856 } // namespace internal |
| 18827 } // namespace v8 | 18857 } // namespace v8 |
| OLD | NEW |