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

Unified Diff: src/keys.cc

Issue 2638323002: [keys] Make for-in great again. (Closed)
Patch Set: readding test Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/keys.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/keys.cc
diff --git a/src/keys.cc b/src/keys.cc
index 35ca22301fc5c860b805cbc43ac77192e520d09e..d1b28690c8361f8b5f6ea435350a23e1844d9d97 100644
--- a/src/keys.cc
+++ b/src/keys.cc
@@ -227,7 +227,7 @@ void TrySettingEmptyEnumCache(JSReceiver* object) {
map->SetEnumLength(0);
}
-bool CheckAndInitalizeSimpleEnumCache(JSReceiver* object) {
+bool CheckAndInitalizeEmptyEnumCache(JSReceiver* object) {
if (object->map()->EnumLength() == kInvalidEnumCacheSentinel) {
TrySettingEmptyEnumCache(object);
}
@@ -248,7 +248,7 @@ void FastKeyAccumulator::Prepare() {
for (PrototypeIterator iter(isolate_, *receiver_); !iter.IsAtEnd();
iter.Advance()) {
JSReceiver* current = iter.GetCurrent<JSReceiver>();
- bool has_no_properties = CheckAndInitalizeSimpleEnumCache(current);
+ bool has_no_properties = CheckAndInitalizeEmptyEnumCache(current);
if (has_no_properties) continue;
last_prototype = current;
has_empty_prototype_ = false;
@@ -271,6 +271,8 @@ static Handle<FixedArray> ReduceFixedArrayTo(Isolate* isolate,
return isolate->factory()->CopyFixedArrayUpTo(array, length);
}
+// Initializes and directly returns the enume cache. Users of this function
+// have to make sure to never directly leak the enum cache.
Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate,
Handle<JSObject> object) {
Handle<Map> map(object->map());
@@ -370,25 +372,6 @@ MaybeHandle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
return result;
}
-MaybeHandle<FixedArray> GetOwnKeysWithUninitializedEnumCache(
- Isolate* isolate, Handle<JSObject> object) {
- // Uninitalized enum cache
- Map* map = object->map();
- if (object->elements() != isolate->heap()->empty_fixed_array() ||
- object->elements() != isolate->heap()->empty_slow_element_dictionary()) {
- // Assume that there are elements.
- return MaybeHandle<FixedArray>();
- }
- int number_of_own_descriptors = map->NumberOfOwnDescriptors();
- if (number_of_own_descriptors == 0) {
- map->SetEnumLength(0);
- return isolate->factory()->empty_fixed_array();
- }
- // We have no elements but possibly enumerable property keys, hence we can
- // directly initialize the enum cache.
- return GetFastEnumPropertyKeys(isolate, object);
-}
-
bool OnlyHasSimpleProperties(Map* map) {
return map->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER;
}
@@ -428,8 +411,7 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
if (enum_length == kInvalidEnumCacheSentinel) {
Handle<FixedArray> keys;
// Try initializing the enum cache and return own properties.
- if (GetOwnKeysWithUninitializedEnumCache(isolate_, object)
- .ToHandle(&keys)) {
+ if (GetOwnKeysWithUninitializedEnumCache().ToHandle(&keys)) {
if (FLAG_trace_for_in_enumerate) {
PrintF("| strings=%d symbols=0 elements=0 || prototypes>=1 ||\n",
keys->length());
@@ -444,6 +426,28 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
return GetOwnKeysWithElements<true>(isolate_, object, keys_conversion);
}
+MaybeHandle<FixedArray>
+FastKeyAccumulator::GetOwnKeysWithUninitializedEnumCache() {
+ Handle<JSObject> object = Handle<JSObject>::cast(receiver_);
+ // Uninitalized enum cache
+ Map* map = object->map();
+ if (object->elements()->length() != 0) {
+ // Assume that there are elements.
+ return MaybeHandle<FixedArray>();
+ }
+ int number_of_own_descriptors = map->NumberOfOwnDescriptors();
+ if (number_of_own_descriptors == 0) {
+ map->SetEnumLength(0);
+ return isolate_->factory()->empty_fixed_array();
+ }
+ // We have no elements but possibly enumerable property keys, hence we can
+ // directly initialize the enum cache.
+ Handle<FixedArray> keys = GetFastEnumPropertyKeys(isolate_, object);
+ if (is_for_in_) return keys;
+ // Do not leak the enum cache as it might end up as an elements backing store.
+ return isolate_->factory()->CopyFixedArray(keys);
+}
+
MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow(
GetKeysConversion keys_conversion) {
KeyAccumulator accumulator(isolate_, mode_, filter_);
« no previous file with comments | « src/keys.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698