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

Side by Side Diff: src/objects.cc

Issue 1090193002: Don't use normalized map cache for prototype maps (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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
« no previous file with comments | « src/flag-definitions.h ('k') | test/mjsunit/regress/regress-crbug-477924.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1922 matching lines...) Expand 10 before | Expand all | Expand 10 after
1933 CHECK(new_map->is_dictionary_map()); 1933 CHECK(new_map->is_dictionary_map());
1934 1934
1935 // Slow-to-slow migration is trivial. 1935 // Slow-to-slow migration is trivial.
1936 object->set_map(*new_map); 1936 object->set_map(*new_map);
1937 } 1937 }
1938 if (old_map->is_prototype_map()) { 1938 if (old_map->is_prototype_map()) {
1939 DCHECK(new_map->is_prototype_map()); 1939 DCHECK(new_map->is_prototype_map());
1940 DCHECK(object->map() == *new_map); 1940 DCHECK(object->map() == *new_map);
1941 new_map->set_prototype_info(old_map->prototype_info()); 1941 new_map->set_prototype_info(old_map->prototype_info());
1942 old_map->set_prototype_info(Smi::FromInt(0)); 1942 old_map->set_prototype_info(Smi::FromInt(0));
1943 if (FLAG_trace_prototype_users) {
1944 PrintF("Moving prototype_info %p from map %p to map %p.\n",
1945 reinterpret_cast<void*>(new_map->prototype_info()),
1946 reinterpret_cast<void*>(*old_map),
1947 reinterpret_cast<void*>(*new_map));
1948 }
1943 } 1949 }
1944 } 1950 }
1945 1951
1946 1952
1947 // To migrate a fast instance to a fast map: 1953 // To migrate a fast instance to a fast map:
1948 // - First check whether the instance needs to be rewritten. If not, simply 1954 // - First check whether the instance needs to be rewritten. If not, simply
1949 // change the map. 1955 // change the map.
1950 // - Otherwise, allocate a fixed array large enough to hold all fields, in 1956 // - Otherwise, allocate a fixed array large enough to hold all fields, in
1951 // addition to unused space. 1957 // addition to unused space.
1952 // - Copy all existing properties in, in the following order: backing store 1958 // - Copy all existing properties in, in the following order: backing store
(...skipping 2761 matching lines...) Expand 10 before | Expand all | Expand 10 after
4714 int inobject_props = object->map()->inobject_properties(); 4720 int inobject_props = object->map()->inobject_properties();
4715 4721
4716 // Allocate new map. 4722 // Allocate new map.
4717 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); 4723 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
4718 new_map->set_dictionary_map(false); 4724 new_map->set_dictionary_map(false);
4719 4725
4720 if (object->map()->is_prototype_map()) { 4726 if (object->map()->is_prototype_map()) {
4721 DCHECK(new_map->is_prototype_map()); 4727 DCHECK(new_map->is_prototype_map());
4722 new_map->set_prototype_info(object->map()->prototype_info()); 4728 new_map->set_prototype_info(object->map()->prototype_info());
4723 object->map()->set_prototype_info(Smi::FromInt(0)); 4729 object->map()->set_prototype_info(Smi::FromInt(0));
4730 if (FLAG_trace_prototype_users) {
4731 PrintF("Moving prototype_info %p from map %p to map %p.\n",
4732 reinterpret_cast<void*>(new_map->prototype_info()),
4733 reinterpret_cast<void*>(object->map()),
4734 reinterpret_cast<void*>(*new_map));
4735 }
4724 } 4736 }
4725 4737
4726 #if TRACE_MAPS 4738 #if TRACE_MAPS
4727 if (FLAG_trace_maps) { 4739 if (FLAG_trace_maps) {
4728 PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n", 4740 PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n",
4729 reinterpret_cast<void*>(object->map()), 4741 reinterpret_cast<void*>(object->map()),
4730 reinterpret_cast<void*>(*new_map), reason); 4742 reinterpret_cast<void*>(*new_map), reason);
4731 } 4743 }
4732 #endif 4744 #endif
4733 4745
(...skipping 2151 matching lines...) Expand 10 before | Expand all | Expand 10 after
6885 } 6897 }
6886 6898
6887 6899
6888 Handle<Map> Map::Normalize(Handle<Map> fast_map, PropertyNormalizationMode mode, 6900 Handle<Map> Map::Normalize(Handle<Map> fast_map, PropertyNormalizationMode mode,
6889 const char* reason) { 6901 const char* reason) {
6890 DCHECK(!fast_map->is_dictionary_map()); 6902 DCHECK(!fast_map->is_dictionary_map());
6891 6903
6892 Isolate* isolate = fast_map->GetIsolate(); 6904 Isolate* isolate = fast_map->GetIsolate();
6893 Handle<Object> maybe_cache(isolate->native_context()->normalized_map_cache(), 6905 Handle<Object> maybe_cache(isolate->native_context()->normalized_map_cache(),
6894 isolate); 6906 isolate);
6895 bool use_cache = !maybe_cache->IsUndefined(); 6907 bool use_cache = !fast_map->is_prototype_map() && !maybe_cache->IsUndefined();
6896 Handle<NormalizedMapCache> cache; 6908 Handle<NormalizedMapCache> cache;
6897 if (use_cache) cache = Handle<NormalizedMapCache>::cast(maybe_cache); 6909 if (use_cache) cache = Handle<NormalizedMapCache>::cast(maybe_cache);
6898 6910
6899 Handle<Map> new_map; 6911 Handle<Map> new_map;
6900 if (use_cache && cache->Get(fast_map, mode).ToHandle(&new_map)) { 6912 if (use_cache && cache->Get(fast_map, mode).ToHandle(&new_map)) {
6901 #ifdef VERIFY_HEAP 6913 #ifdef VERIFY_HEAP
6902 if (FLAG_verify_heap) new_map->DictionaryMapVerify(); 6914 if (FLAG_verify_heap) new_map->DictionaryMapVerify();
6903 #endif 6915 #endif
6904 #ifdef ENABLE_SLOW_DCHECKS 6916 #ifdef ENABLE_SLOW_DCHECKS
6905 if (FLAG_enable_slow_asserts) { 6917 if (FLAG_enable_slow_asserts) {
(...skipping 3140 matching lines...) Expand 10 before | Expand all | Expand 10 after
10046 proto_info = handle(PrototypeInfo::cast(maybe_proto_info), isolate); 10058 proto_info = handle(PrototypeInfo::cast(maybe_proto_info), isolate);
10047 } else { 10059 } else {
10048 proto_info = isolate->factory()->NewPrototypeInfo(); 10060 proto_info = isolate->factory()->NewPrototypeInfo();
10049 prototype->map()->set_prototype_info(*proto_info); 10061 prototype->map()->set_prototype_info(*proto_info);
10050 } 10062 }
10051 Handle<Object> maybe_registry(proto_info->prototype_users(), isolate); 10063 Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
10052 Handle<WeakFixedArray> new_array = WeakFixedArray::Add(maybe_registry, user); 10064 Handle<WeakFixedArray> new_array = WeakFixedArray::Add(maybe_registry, user);
10053 if (!maybe_registry.is_identical_to(new_array)) { 10065 if (!maybe_registry.is_identical_to(new_array)) {
10054 proto_info->set_prototype_users(*new_array); 10066 proto_info->set_prototype_users(*new_array);
10055 } 10067 }
10068 if (FLAG_trace_prototype_users) {
10069 PrintF("Registering %p as a user of prototype %p.\n",
10070 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype));
10071 }
10056 } 10072 }
10057 10073
10058 10074
10059 // static 10075 // static
10060 void JSObject::UnregisterPrototypeUser(Handle<JSObject> prototype, 10076 void JSObject::UnregisterPrototypeUser(Handle<JSObject> prototype,
10061 Handle<HeapObject> user) { 10077 Handle<HeapObject> user) {
10062 Isolate* isolate = prototype->GetIsolate(); 10078 Isolate* isolate = prototype->GetIsolate();
10063 if (prototype->IsJSGlobalProxy()) { 10079 if (prototype->IsJSGlobalProxy()) {
10064 PrototypeIterator iter(isolate, prototype); 10080 PrototypeIterator iter(isolate, prototype);
10065 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 10081 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
10066 } 10082 }
10067 DCHECK(prototype->map()->is_prototype_map()); 10083 DCHECK(prototype->map()->is_prototype_map());
10068 Object* maybe_proto_info = prototype->map()->prototype_info(); 10084 Object* maybe_proto_info = prototype->map()->prototype_info();
10069 if (!maybe_proto_info->IsPrototypeInfo()) return; 10085 if (!maybe_proto_info->IsPrototypeInfo()) return;
10070 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info), 10086 Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info),
10071 isolate); 10087 isolate);
10072 Object* maybe_registry = proto_info->prototype_users(); 10088 Object* maybe_registry = proto_info->prototype_users();
10073 if (!maybe_registry->IsWeakFixedArray()) return; 10089 if (!maybe_registry->IsWeakFixedArray()) return;
10074 WeakFixedArray::cast(maybe_registry)->Remove(user); 10090 WeakFixedArray::cast(maybe_registry)->Remove(user);
10091 if (FLAG_trace_prototype_users) {
10092 PrintF("Unregistering %p as a user of prototype %p.\n",
10093 reinterpret_cast<void*>(*user), reinterpret_cast<void*>(*prototype));
10094 }
10075 } 10095 }
10076 10096
10077 10097
10078 static void InvalidatePrototypeChainsInternal(Map* map) { 10098 static void InvalidatePrototypeChainsInternal(Map* map) {
10079 if (!map->is_prototype_map()) return; 10099 if (!map->is_prototype_map()) return;
10080 Object* maybe_proto_info = map->prototype_info(); 10100 Object* maybe_proto_info = map->prototype_info();
10081 if (!maybe_proto_info->IsPrototypeInfo()) return; 10101 if (!maybe_proto_info->IsPrototypeInfo()) return;
10082 PrototypeInfo* proto_info = PrototypeInfo::cast(maybe_proto_info); 10102 PrototypeInfo* proto_info = PrototypeInfo::cast(maybe_proto_info);
10083 Object* maybe_cell = proto_info->validity_cell(); 10103 Object* maybe_cell = proto_info->validity_cell();
10084 if (maybe_cell->IsCell()) { 10104 if (maybe_cell->IsCell()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
10119 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map, 10139 Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
10120 Isolate* isolate) { 10140 Isolate* isolate) {
10121 Handle<Object> maybe_prototype(map->prototype(), isolate); 10141 Handle<Object> maybe_prototype(map->prototype(), isolate);
10122 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null(); 10142 if (!maybe_prototype->IsJSObject()) return Handle<Cell>::null();
10123 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype); 10143 Handle<JSObject> prototype = Handle<JSObject>::cast(maybe_prototype);
10124 if (prototype->IsJSGlobalProxy()) { 10144 if (prototype->IsJSGlobalProxy()) {
10125 PrototypeIterator iter(isolate, prototype); 10145 PrototypeIterator iter(isolate, prototype);
10126 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); 10146 prototype = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
10127 } 10147 }
10128 Handle<PrototypeInfo> proto_info( 10148 Handle<PrototypeInfo> proto_info(
10129 PrototypeInfo::cast(prototype->map()->prototype_info())); 10149 PrototypeInfo::cast(prototype->map()->prototype_info()), isolate);
10130 Object* maybe_cell = proto_info->validity_cell(); 10150 Object* maybe_cell = proto_info->validity_cell();
10131 // Return existing cell if it's still valid. 10151 // Return existing cell if it's still valid.
10132 if (maybe_cell->IsCell()) { 10152 if (maybe_cell->IsCell()) {
10133 Handle<Cell> cell(Cell::cast(maybe_cell), isolate); 10153 Handle<Cell> cell(Cell::cast(maybe_cell), isolate);
10134 if (cell->value() == Smi::FromInt(Map::kPrototypeChainValid)) { 10154 if (cell->value() == Smi::FromInt(Map::kPrototypeChainValid)) {
10135 return handle(Cell::cast(maybe_cell), isolate); 10155 return handle(Cell::cast(maybe_cell), isolate);
10136 } 10156 }
10137 } 10157 }
10138 // Otherwise create a new cell. 10158 // Otherwise create a new cell.
10139 Handle<Cell> cell = isolate->factory()->NewCell( 10159 Handle<Cell> cell = isolate->factory()->NewCell(
(...skipping 7003 matching lines...) Expand 10 before | Expand all | Expand 10 after
17143 CompilationInfo* info) { 17163 CompilationInfo* info) {
17144 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( 17164 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo(
17145 handle(cell->dependent_code(), info->isolate()), 17165 handle(cell->dependent_code(), info->isolate()),
17146 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); 17166 DependentCode::kPropertyCellChangedGroup, info->object_wrapper());
17147 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); 17167 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
17148 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 17168 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
17149 cell, info->zone()); 17169 cell, info->zone());
17150 } 17170 }
17151 17171
17152 } } // namespace v8::internal 17172 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/flag-definitions.h ('k') | test/mjsunit/regress/regress-crbug-477924.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698