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

Side by Side Diff: src/keys.cc

Issue 2169523002: [keys] Postpone shadowed key checking in the KeyAccumulator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: typo Created 4 years, 5 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/keys.h ('k') | src/objects.cc » ('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 "src/keys.h" 5 #include "src/keys.h"
6 6
7 #include "src/api-arguments.h" 7 #include "src/api-arguments.h"
8 #include "src/elements.h" 8 #include "src/elements.h"
9 #include "src/factory.h" 9 #include "src/factory.h"
10 #include "src/identity-map.h" 10 #include "src/identity-map.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 for (int i = 0; i < keys->length(); ++i) { 110 for (int i = 0; i < keys->length(); ++i) {
111 Handle<Name> key(Name::cast(keys->get(i)), isolate); 111 Handle<Name> key(Name::cast(keys->get(i)), isolate);
112 if (key->FilterKey(filter)) continue; // Skip this key. 112 if (key->FilterKey(filter)) continue; // Skip this key.
113 if (filter & ONLY_ENUMERABLE) { 113 if (filter & ONLY_ENUMERABLE) {
114 PropertyDescriptor desc; 114 PropertyDescriptor desc;
115 Maybe<bool> found = 115 Maybe<bool> found =
116 JSProxy::GetOwnPropertyDescriptor(isolate, owner, key, &desc); 116 JSProxy::GetOwnPropertyDescriptor(isolate, owner, key, &desc);
117 MAYBE_RETURN(found, MaybeHandle<FixedArray>()); 117 MAYBE_RETURN(found, MaybeHandle<FixedArray>());
118 if (!found.FromJust()) continue; 118 if (!found.FromJust()) continue;
119 if (!desc.enumerable()) { 119 if (!desc.enumerable()) {
120 accumulator->AddShadowKey(key); 120 accumulator->AddShadowingKey(key);
121 continue; 121 continue;
122 } 122 }
123 } 123 }
124 // Keep this key. 124 // Keep this key.
125 if (store_position != i) { 125 if (store_position != i) {
126 keys->set(store_position, *key); 126 keys->set(store_position, *key);
127 } 127 }
128 store_position++; 128 store_position++;
129 } 129 }
130 if (store_position == 0) return isolate->factory()->empty_fixed_array(); 130 if (store_position == 0) return isolate->factory()->empty_fixed_array();
(...skipping 28 matching lines...) Expand all
159 MAYBE_RETURN(CollectOwnJSProxyKeys(receiver, Handle<JSProxy>::cast(object)), 159 MAYBE_RETURN(CollectOwnJSProxyKeys(receiver, Handle<JSProxy>::cast(object)),
160 Nothing<bool>()); 160 Nothing<bool>());
161 return Just(true); 161 return Just(true);
162 } 162 }
163 163
164 PrototypeIterator::WhereToEnd end = mode_ == KeyCollectionMode::kOwnOnly 164 PrototypeIterator::WhereToEnd end = mode_ == KeyCollectionMode::kOwnOnly
165 ? PrototypeIterator::END_AT_NON_HIDDEN 165 ? PrototypeIterator::END_AT_NON_HIDDEN
166 : PrototypeIterator::END_AT_NULL; 166 : PrototypeIterator::END_AT_NULL;
167 for (PrototypeIterator iter(isolate_, object, kStartAtReceiver, end); 167 for (PrototypeIterator iter(isolate_, object, kStartAtReceiver, end);
168 !iter.IsAtEnd();) { 168 !iter.IsAtEnd();) {
169 // Start the shadow checks only after the first prototype has added
170 // shadowing keys.
171 if (HasShadowingKeys()) skip_shadow_check_ = false;
169 Handle<JSReceiver> current = 172 Handle<JSReceiver> current =
170 PrototypeIterator::GetCurrent<JSReceiver>(iter); 173 PrototypeIterator::GetCurrent<JSReceiver>(iter);
171 Maybe<bool> result = Just(false); // Dummy initialization. 174 Maybe<bool> result = Just(false); // Dummy initialization.
172 if (current->IsJSProxy()) { 175 if (current->IsJSProxy()) {
173 result = CollectOwnJSProxyKeys(receiver, Handle<JSProxy>::cast(current)); 176 result = CollectOwnJSProxyKeys(receiver, Handle<JSProxy>::cast(current));
174 } else { 177 } else {
175 DCHECK(current->IsJSObject()); 178 DCHECK(current->IsJSObject());
176 result = CollectOwnKeys(receiver, Handle<JSObject>::cast(current)); 179 result = CollectOwnKeys(receiver, Handle<JSObject>::cast(current));
177 } 180 }
178 MAYBE_RETURN(result, Nothing<bool>()); 181 MAYBE_RETURN(result, Nothing<bool>());
179 if (!result.FromJust()) break; // |false| means "stop iterating". 182 if (!result.FromJust()) break; // |false| means "stop iterating".
180 // Iterate through proxies but ignore access checks for the ALL_CAN_READ 183 // Iterate through proxies but ignore access checks for the ALL_CAN_READ
181 // case on API objects for OWN_ONLY keys handled in CollectOwnKeys. 184 // case on API objects for OWN_ONLY keys handled in CollectOwnKeys.
182 if (!iter.AdvanceFollowingProxiesIgnoringAccessChecks()) { 185 if (!iter.AdvanceFollowingProxiesIgnoringAccessChecks()) {
183 return Nothing<bool>(); 186 return Nothing<bool>();
184 } 187 }
185 if (!last_non_empty_prototype_.is_null() && 188 if (!last_non_empty_prototype_.is_null() &&
186 *last_non_empty_prototype_ == *current) { 189 *last_non_empty_prototype_ == *current) {
187 break; 190 break;
188 } 191 }
189 } 192 }
190 return Just(true); 193 return Just(true);
191 } 194 }
192 195
196 bool KeyAccumulator::HasShadowingKeys() { return !shadowing_keys_.is_null(); }
197
193 bool KeyAccumulator::IsShadowed(Handle<Object> key) { 198 bool KeyAccumulator::IsShadowed(Handle<Object> key) {
194 if (shadowed_keys_.is_null()) return false; 199 if (!HasShadowingKeys() || skip_shadow_check_) return false;
195 return shadowed_keys_->Has(isolate_, key); 200 return shadowing_keys_->Has(isolate_, key);
196 } 201 }
197 202
198 void KeyAccumulator::AddShadowKey(Object* key) { 203 void KeyAccumulator::AddShadowingKey(Object* key) {
199 if (mode_ == KeyCollectionMode::kOwnOnly) return; 204 if (mode_ == KeyCollectionMode::kOwnOnly) return;
200 AddShadowKey(handle(key, isolate_)); 205 AddShadowingKey(handle(key, isolate_));
201 } 206 }
202 void KeyAccumulator::AddShadowKey(Handle<Object> key) { 207 void KeyAccumulator::AddShadowingKey(Handle<Object> key) {
203 if (mode_ == KeyCollectionMode::kOwnOnly) return; 208 if (mode_ == KeyCollectionMode::kOwnOnly) return;
204 if (shadowed_keys_.is_null()) { 209 if (shadowing_keys_.is_null()) {
205 shadowed_keys_ = ObjectHashSet::New(isolate_, 16); 210 shadowing_keys_ = ObjectHashSet::New(isolate_, 16);
206 } 211 }
207 shadowed_keys_ = ObjectHashSet::Add(shadowed_keys_, key); 212 shadowing_keys_ = ObjectHashSet::Add(shadowing_keys_, key);
208 } 213 }
209 214
210 namespace { 215 namespace {
211 216
212 void TrySettingEmptyEnumCache(JSReceiver* object) { 217 void TrySettingEmptyEnumCache(JSReceiver* object) {
213 Map* map = object->map(); 218 Map* map = object->map();
214 DCHECK_EQ(kInvalidEnumCacheSentinel, map->EnumLength()); 219 DCHECK_EQ(kInvalidEnumCacheSentinel, map->EnumLength());
215 if (!map->OnlyHasSimpleProperties()) return; 220 if (!map->OnlyHasSimpleProperties()) return;
216 if (map->IsJSProxyMap()) return; 221 if (map->IsJSProxyMap()) return;
217 if (map->NumberOfOwnDescriptors() > 0) { 222 if (map->NumberOfOwnDescriptors() > 0) {
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 } 546 }
542 547
543 Name* key = descs->GetKey(i); 548 Name* key = descs->GetKey(i);
544 if (skip_symbols == key->IsSymbol()) { 549 if (skip_symbols == key->IsSymbol()) {
545 if (first_skipped == -1) first_skipped = i; 550 if (first_skipped == -1) first_skipped = i;
546 continue; 551 continue;
547 } 552 }
548 if (key->FilterKey(keys->filter())) continue; 553 if (key->FilterKey(keys->filter())) continue;
549 554
550 if (is_shadowing_key) { 555 if (is_shadowing_key) {
551 keys->AddShadowKey(key); 556 keys->AddShadowingKey(key);
552 } else { 557 } else {
553 keys->AddKey(key, DO_NOT_CONVERT); 558 keys->AddKey(key, DO_NOT_CONVERT);
554 } 559 }
555 } 560 }
556 return first_skipped; 561 return first_skipped;
557 } 562 }
558 563
559 template <class T> 564 template <class T>
560 Handle<FixedArray> GetOwnEnumPropertyDictionaryKeys(Isolate* isolate, 565 Handle<FixedArray> GetOwnEnumPropertyDictionaryKeys(Isolate* isolate,
561 KeyCollectionMode mode, 566 KeyCollectionMode mode,
(...skipping 21 matching lines...) Expand all
583 // we do not have to filter out non-enumerable ones 588 // we do not have to filter out non-enumerable ones
584 Map* map = object->map(); 589 Map* map = object->map();
585 int nof_descriptors = map->NumberOfOwnDescriptors(); 590 int nof_descriptors = map->NumberOfOwnDescriptors();
586 if (enum_keys->length() != nof_descriptors) { 591 if (enum_keys->length() != nof_descriptors) {
587 Handle<DescriptorArray> descs = 592 Handle<DescriptorArray> descs =
588 Handle<DescriptorArray>(map->instance_descriptors(), isolate_); 593 Handle<DescriptorArray>(map->instance_descriptors(), isolate_);
589 for (int i = 0; i < nof_descriptors; i++) { 594 for (int i = 0; i < nof_descriptors; i++) {
590 PropertyDetails details = descs->GetDetails(i); 595 PropertyDetails details = descs->GetDetails(i);
591 if (!details.IsDontEnum()) continue; 596 if (!details.IsDontEnum()) continue;
592 Object* key = descs->GetKey(i); 597 Object* key = descs->GetKey(i);
593 this->AddShadowKey(key); 598 this->AddShadowingKey(key);
594 } 599 }
595 } 600 }
596 } else if (object->IsJSGlobalObject()) { 601 } else if (object->IsJSGlobalObject()) {
597 enum_keys = GetOwnEnumPropertyDictionaryKeys( 602 enum_keys = GetOwnEnumPropertyDictionaryKeys(
598 isolate_, mode_, this, object, object->global_dictionary()); 603 isolate_, mode_, this, object, object->global_dictionary());
599 } else { 604 } else {
600 enum_keys = GetOwnEnumPropertyDictionaryKeys( 605 enum_keys = GetOwnEnumPropertyDictionaryKeys(
601 isolate_, mode_, this, object, object->property_dictionary()); 606 isolate_, mode_, this, object, object->property_dictionary());
602 } 607 }
603 AddKeys(enum_keys, DO_NOT_CONVERT); 608 AddKeys(enum_keys, DO_NOT_CONVERT);
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 Nothing<bool>()); 865 Nothing<bool>());
861 bool prev_filter_proxy_keys_ = filter_proxy_keys_; 866 bool prev_filter_proxy_keys_ = filter_proxy_keys_;
862 filter_proxy_keys_ = false; 867 filter_proxy_keys_ = false;
863 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys); 868 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys);
864 filter_proxy_keys_ = prev_filter_proxy_keys_; 869 filter_proxy_keys_ = prev_filter_proxy_keys_;
865 return result; 870 return result;
866 } 871 }
867 872
868 } // namespace internal 873 } // namespace internal
869 } // namespace v8 874 } // namespace v8
OLDNEW
« no previous file with comments | « src/keys.h ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698