| Index: src/lookup.h
|
| diff --git a/src/lookup.h b/src/lookup.h
|
| index 0c298d99bf7ed2a0de1015a1f383a1fb5292c34c..9a053198cbc8378c07c0806964ff0b320b43e06e 100644
|
| --- a/src/lookup.h
|
| +++ b/src/lookup.h
|
| @@ -47,7 +47,6 @@ class LookupIterator final BASE_EMBEDDED {
|
| LookupIterator(Handle<Object> receiver, Handle<Name> name,
|
| Configuration configuration = DEFAULT)
|
| : configuration_(ComputeConfiguration(configuration, name)),
|
| - state_(NOT_FOUND),
|
| interceptor_state_(InterceptorState::kUninitialized),
|
| property_details_(PropertyDetails::Empty()),
|
| isolate_(name->GetIsolate()),
|
| @@ -55,21 +54,18 @@ class LookupIterator final BASE_EMBEDDED {
|
| // kMaxUInt32 isn't a valid index.
|
| index_(kMaxUInt32),
|
| receiver_(receiver),
|
| - holder_(GetRoot(isolate_, receiver)),
|
| - initial_holder_(holder_),
|
| - number_(DescriptorArray::kNotFound) {
|
| + initial_holder_(GetRoot(isolate_, receiver)) {
|
| #ifdef DEBUG
|
| uint32_t index; // Assert that the name is not an array index.
|
| DCHECK(!name->AsArrayIndex(&index));
|
| #endif // DEBUG
|
| - Next();
|
| + Start<false>();
|
| }
|
|
|
| LookupIterator(Handle<Object> receiver, Handle<Name> name,
|
| Handle<JSReceiver> holder,
|
| Configuration configuration = DEFAULT)
|
| : configuration_(ComputeConfiguration(configuration, name)),
|
| - state_(NOT_FOUND),
|
| interceptor_state_(InterceptorState::kUninitialized),
|
| property_details_(PropertyDetails::Empty()),
|
| isolate_(name->GetIsolate()),
|
| @@ -77,51 +73,43 @@ class LookupIterator final BASE_EMBEDDED {
|
| // kMaxUInt32 isn't a valid index.
|
| index_(kMaxUInt32),
|
| receiver_(receiver),
|
| - holder_(holder),
|
| - initial_holder_(holder_),
|
| - number_(DescriptorArray::kNotFound) {
|
| + initial_holder_(holder) {
|
| #ifdef DEBUG
|
| uint32_t index; // Assert that the name is not an array index.
|
| DCHECK(!name->AsArrayIndex(&index));
|
| #endif // DEBUG
|
| - Next();
|
| + Start<false>();
|
| }
|
|
|
| LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index,
|
| Configuration configuration = DEFAULT)
|
| : configuration_(configuration),
|
| - state_(NOT_FOUND),
|
| interceptor_state_(InterceptorState::kUninitialized),
|
| property_details_(PropertyDetails::Empty()),
|
| isolate_(isolate),
|
| name_(),
|
| index_(index),
|
| receiver_(receiver),
|
| - holder_(GetRoot(isolate, receiver, index)),
|
| - initial_holder_(holder_),
|
| - number_(DescriptorArray::kNotFound) {
|
| + initial_holder_(GetRoot(isolate, receiver, index)) {
|
| // kMaxUInt32 isn't a valid index.
|
| DCHECK_NE(kMaxUInt32, index_);
|
| - Next();
|
| + Start<true>();
|
| }
|
|
|
| LookupIterator(Isolate* isolate, Handle<Object> receiver, uint32_t index,
|
| Handle<JSReceiver> holder,
|
| Configuration configuration = DEFAULT)
|
| : configuration_(configuration),
|
| - state_(NOT_FOUND),
|
| interceptor_state_(InterceptorState::kUninitialized),
|
| property_details_(PropertyDetails::Empty()),
|
| isolate_(isolate),
|
| name_(),
|
| index_(index),
|
| receiver_(receiver),
|
| - holder_(holder),
|
| - initial_holder_(holder_),
|
| - number_(DescriptorArray::kNotFound) {
|
| + initial_holder_(holder) {
|
| // kMaxUInt32 isn't a valid index.
|
| DCHECK_NE(kMaxUInt32, index_);
|
| - Next();
|
| + Start<true>();
|
| }
|
|
|
| static LookupIterator PropertyOrElement(
|
| @@ -154,7 +142,10 @@ class LookupIterator final BASE_EMBEDDED {
|
| Isolate* isolate, Handle<Object> receiver, Handle<Object> key,
|
| bool* success, Configuration configuration = DEFAULT);
|
|
|
| - void Restart() { RestartInternal(InterceptorState::kUninitialized); }
|
| + void Restart() {
|
| + InterceptorState state = InterceptorState::kUninitialized;
|
| + IsElement() ? RestartInternal<true>(state) : RestartInternal<false>(state);
|
| + }
|
|
|
| Isolate* isolate() const { return isolate_; }
|
| State state() const { return state_; }
|
| @@ -184,7 +175,17 @@ class LookupIterator final BASE_EMBEDDED {
|
| Heap* heap() const { return isolate_->heap(); }
|
| Factory* factory() const { return isolate_->factory(); }
|
| Handle<Object> GetReceiver() const { return receiver_; }
|
| - Handle<JSObject> GetStoreTarget() const;
|
| +
|
| + Handle<JSObject> GetStoreTarget() const {
|
| + if (receiver_->IsJSGlobalProxy()) {
|
| + Map* map = JSGlobalProxy::cast(*receiver_)->map();
|
| + if (map->has_hidden_prototype()) {
|
| + return handle(JSGlobalObject::cast(map->prototype()), isolate_);
|
| + }
|
| + }
|
| + return Handle<JSObject>::cast(receiver_);
|
| + }
|
| +
|
| bool is_dictionary_holder() const { return !holder_->HasFastProperties(); }
|
| Handle<Map> transition_map() const {
|
| DCHECK_EQ(TRANSITION, state_);
|
| @@ -256,9 +257,17 @@ class LookupIterator final BASE_EMBEDDED {
|
| }
|
| Handle<Object> GetDataValue() const;
|
| void WriteDataValue(Handle<Object> value);
|
| - void UpdateProtector();
|
| + inline void UpdateProtector() {
|
| + if (FLAG_harmony_species && !IsElement() &&
|
| + (*name_ == heap()->constructor_string() ||
|
| + *name_ == heap()->species_symbol())) {
|
| + InternalUpdateProtector();
|
| + }
|
| + }
|
|
|
| private:
|
| + void InternalUpdateProtector();
|
| +
|
| enum class InterceptorState {
|
| kUninitialized,
|
| kSkipNonMasking,
|
| @@ -268,16 +277,32 @@ class LookupIterator final BASE_EMBEDDED {
|
| Handle<Map> GetReceiverMap() const;
|
|
|
| MUST_USE_RESULT inline JSReceiver* NextHolder(Map* map);
|
| - inline State LookupInHolder(Map* map, JSReceiver* holder);
|
| +
|
| + template <bool is_element>
|
| + void Start();
|
| + template <bool is_element>
|
| + void NextInternal(Map* map, JSReceiver* holder);
|
| + template <bool is_element>
|
| + inline State LookupInHolder(Map* map, JSReceiver* holder) {
|
| + return map->instance_type() <= LAST_SPECIAL_RECEIVER_TYPE
|
| + ? LookupInSpecialHolder<is_element>(map, holder)
|
| + : LookupInRegularHolder<is_element>(map, holder);
|
| + }
|
| + template <bool is_element>
|
| + State LookupInRegularHolder(Map* map, JSReceiver* holder);
|
| + template <bool is_element>
|
| + State LookupInSpecialHolder(Map* map, JSReceiver* holder);
|
| + template <bool is_element>
|
| void RestartLookupForNonMaskingInterceptors() {
|
| - RestartInternal(InterceptorState::kProcessNonMasking);
|
| + RestartInternal<is_element>(InterceptorState::kProcessNonMasking);
|
| }
|
| + template <bool is_element>
|
| void RestartInternal(InterceptorState interceptor_state);
|
| - State LookupNonMaskingInterceptorInHolder(Map* map, JSReceiver* holder);
|
| Handle<Object> FetchValue() const;
|
| + template <bool is_element>
|
| void ReloadPropertyInformation();
|
| +
|
| inline bool SkipInterceptor(JSObject* holder);
|
| - bool HasInterceptor(Map* map) const;
|
| inline InterceptorInfo* GetInterceptor(JSObject* holder) const {
|
| if (IsElement()) return holder->GetIndexedInterceptor();
|
| return holder->GetNamedInterceptor();
|
|
|