| Index: src/keys.h
|
| diff --git a/src/keys.h b/src/keys.h
|
| index 502c834527e65caf9e3cab6f5bb68e442f940a09..ecd3d97c550cf5a8aa80f2aa312c18d1001115ca 100644
|
| --- a/src/keys.h
|
| +++ b/src/keys.h
|
| @@ -53,8 +53,8 @@ class KeyAccumulator final BASE_EMBEDDED {
|
| Handle<AccessCheckInfo> access_check_info, Handle<JSReceiver> receiver,
|
| Handle<JSObject> object);
|
|
|
| - static Handle<FixedArray> GetEnumPropertyKeys(Isolate* isolate,
|
| - Handle<JSObject> object);
|
| + static Handle<FixedArray> GetOwnEnumPropertyKeys(Isolate* isolate,
|
| + Handle<JSObject> object);
|
|
|
| void AddKey(Object* key, AddKeyConversion convert = DO_NOT_CONVERT);
|
| void AddKey(Handle<Object> key, AddKeyConversion convert = DO_NOT_CONVERT);
|
| @@ -64,13 +64,27 @@ class KeyAccumulator final BASE_EMBEDDED {
|
| // Jump to the next level, pushing the current |levelLength_| to
|
| // |levelLengths_| and adding a new list to |elements_|.
|
| Isolate* isolate() { return isolate_; }
|
| + // Filter keys based on their property descriptors.
|
| PropertyFilter filter() { return filter_; }
|
| + // The collection mode defines whether we collect the keys from the prototype
|
| + // chain or only look at the receiver.
|
| + KeyCollectionMode mode() { return mode_; }
|
| void set_filter_proxy_keys(bool filter) { filter_proxy_keys_ = filter; }
|
| + // In case of for-in loops we have to treat JSProxy keys differently and
|
| + // deduplicate them. Additionally we convert JSProxy keys back to array
|
| + // indices.
|
| void set_is_for_in(bool value) { is_for_in_ = value; }
|
| void set_skip_indices(bool value) { skip_indices_ = value; }
|
| + // The last_non_empty_prototype is used to limit the prototypes for which
|
| + // we have to keep track of non-enumerable keys that can shadow keys
|
| + // repeated on the prototype chain.
|
| void set_last_non_empty_prototype(Handle<JSReceiver> object) {
|
| last_non_empty_prototype_ = object;
|
| }
|
| + // Shadowing keys are used to filter keys. This happens when non-enumerable
|
| + // keys appear again on the prototype chain.
|
| + void AddShadowKey(Object* key);
|
| + void AddShadowKey(Handle<Object> key);
|
|
|
| private:
|
| Maybe<bool> CollectOwnKeys(Handle<JSReceiver> receiver,
|
| @@ -79,17 +93,18 @@ class KeyAccumulator final BASE_EMBEDDED {
|
| Handle<JSProxy> proxy);
|
| Maybe<bool> CollectOwnJSProxyTargetKeys(Handle<JSProxy> proxy,
|
| Handle<JSReceiver> target);
|
| -
|
| Maybe<bool> AddKeysFromJSProxy(Handle<JSProxy> proxy,
|
| Handle<FixedArray> keys);
|
| -
|
| + bool IsShadowed(Handle<Object> key);
|
| Handle<OrderedHashSet> keys() { return Handle<OrderedHashSet>::cast(keys_); }
|
|
|
| Isolate* isolate_;
|
| // keys_ is either an Handle<OrderedHashSet> or in the case of own JSProxy
|
| - // keys a Handle<FixedArray>.
|
| + // keys a Handle<FixedArray>. The OrderedHashSet is in-place converted to the
|
| + // result list, a FixedArray containing all collected keys.
|
| Handle<FixedArray> keys_;
|
| Handle<JSReceiver> last_non_empty_prototype_;
|
| + Handle<ObjectHashSet> shadowed_keys_;
|
| KeyCollectionMode mode_;
|
| PropertyFilter filter_;
|
| bool filter_proxy_keys_ = true;
|
| @@ -101,7 +116,8 @@ class KeyAccumulator final BASE_EMBEDDED {
|
|
|
| // The FastKeyAccumulator handles the cases where there are no elements on the
|
| // prototype chain and forwords the complex/slow cases to the normal
|
| -// KeyAccumulator.
|
| +// KeyAccumulator. This significantly speeds up the cases where the OWN_ONLY
|
| +// case where we do not have to walk the prototype chain.
|
| class FastKeyAccumulator {
|
| public:
|
| FastKeyAccumulator(Isolate* isolate, Handle<JSReceiver> receiver,
|
|
|