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 1922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |