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

Side by Side Diff: src/objects.cc

Issue 2036493006: Keep prototype maps in dictionary mode until ICs see them (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix tests & rebase Created 4 years, 6 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
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698