Line data Source code
1 : // Copyright 2014 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_LOOKUP_INL_H_
6 : #define V8_LOOKUP_INL_H_
7 :
8 : #include "src/lookup.h"
9 :
10 : #include "src/handles-inl.h"
11 : #include "src/heap/factory-inl.h"
12 : #include "src/objects-inl.h"
13 : #include "src/objects/api-callbacks.h"
14 : #include "src/objects/name-inl.h"
15 : #include "src/objects/map-inl.h"
16 :
17 : namespace v8 {
18 : namespace internal {
19 :
20 34140116 : LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
21 : Handle<Name> name, Configuration configuration)
22 : : LookupIterator(isolate, receiver, name, GetRoot(isolate, receiver),
23 34140116 : configuration) {}
24 :
25 865 : LookupIterator::LookupIterator(Handle<Object> receiver, Handle<Name> name,
26 : Handle<JSReceiver> holder,
27 : Configuration configuration)
28 : : LookupIterator(holder->GetIsolate(), receiver, name, holder,
29 26133302 : configuration) {}
30 :
31 90285398 : LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
32 : Handle<Name> name, Handle<JSReceiver> holder,
33 : Configuration configuration)
34 : : configuration_(ComputeConfiguration(configuration, name)),
35 : interceptor_state_(InterceptorState::kUninitialized),
36 : property_details_(PropertyDetails::Empty()),
37 : isolate_(isolate),
38 : name_(isolate_->factory()->InternalizeName(name)),
39 : receiver_(receiver),
40 : initial_holder_(holder),
41 : // kMaxUInt32 isn't a valid index.
42 : index_(kMaxUInt32),
43 270856323 : number_(static_cast<uint32_t>(DescriptorArray::kNotFound)) {
44 : #ifdef DEBUG
45 : uint32_t index; // Assert that the name is not an array index.
46 : DCHECK(!name->AsArrayIndex(&index));
47 : #endif // DEBUG
48 90285440 : Start<false>();
49 90285421 : }
50 :
51 36575389 : LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
52 : uint32_t index, Configuration configuration)
53 : : LookupIterator(isolate, receiver, index,
54 73150783 : GetRoot(isolate, receiver, index), configuration) {}
55 :
56 9701738 : LookupIterator LookupIterator::PropertyOrElement(
57 : Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
58 : Handle<JSReceiver> holder, Configuration configuration) {
59 : uint32_t index;
60 9701738 : if (name->AsArrayIndex(&index)) {
61 : LookupIterator it =
62 57894 : LookupIterator(isolate, receiver, index, holder, configuration);
63 57894 : it.name_ = name;
64 57894 : return it;
65 : }
66 : return LookupIterator(receiver, name, holder, configuration);
67 : }
68 :
69 5470766 : LookupIterator LookupIterator::PropertyOrElement(
70 : Isolate* isolate, Handle<Object> receiver, Handle<Name> name,
71 : Configuration configuration) {
72 : uint32_t index;
73 5470766 : if (name->AsArrayIndex(&index)) {
74 79608 : LookupIterator it = LookupIterator(isolate, receiver, index, configuration);
75 79608 : it.name_ = name;
76 79608 : return it;
77 : }
78 5391167 : return LookupIterator(isolate, receiver, name, configuration);
79 : }
80 :
81 1889282 : Handle<Name> LookupIterator::GetName() {
82 1889282 : if (name_.is_null()) {
83 : DCHECK(IsElement());
84 290588 : name_ = factory()->Uint32ToString(index_);
85 : }
86 1889282 : return name_;
87 : }
88 :
89 : bool LookupIterator::is_dictionary_holder() const {
90 1533465 : return !holder_->HasFastProperties();
91 : }
92 :
93 : Handle<Map> LookupIterator::transition_map() const {
94 : DCHECK_EQ(TRANSITION, state_);
95 : return Handle<Map>::cast(transition_);
96 : }
97 :
98 : Handle<PropertyCell> LookupIterator::transition_cell() const {
99 : DCHECK_EQ(TRANSITION, state_);
100 : return Handle<PropertyCell>::cast(transition_);
101 : }
102 :
103 : template <class T>
104 : Handle<T> LookupIterator::GetHolder() const {
105 : DCHECK(IsFound());
106 : return Handle<T>::cast(holder_);
107 : }
108 :
109 38556391 : bool LookupIterator::ExtendingNonExtensible(Handle<JSReceiver> receiver) {
110 : DCHECK(receiver.is_identical_to(GetStoreTarget<JSReceiver>()));
111 38556391 : return !receiver->map()->is_extensible() &&
112 887 : (IsElement() || !name_->IsPrivate());
113 : }
114 :
115 482324 : bool LookupIterator::IsCacheableTransition() {
116 : DCHECK_EQ(TRANSITION, state_);
117 440181 : return transition_->IsPropertyCell() ||
118 39863 : (transition_map()->is_dictionary_map() &&
119 962411 : !GetStoreTarget<JSReceiver>()->HasFastProperties()) ||
120 882685 : transition_map()->GetBackPointer()->IsMap();
121 : }
122 :
123 58704414 : void LookupIterator::UpdateProtector() {
124 58704414 : if (IsElement()) return;
125 : // This list must be kept in sync with
126 : // CodeStubAssembler::CheckForAssociatedProtector!
127 : ReadOnlyRoots roots(heap());
128 94320841 : if (*name_ == roots.is_concat_spreadable_symbol() ||
129 86049620 : *name_ == roots.constructor_string() || *name_ == roots.next_string() ||
130 85939838 : *name_ == roots.species_symbol() || *name_ == roots.iterator_symbol() ||
131 90126915 : *name_ == roots.resolve_string() || *name_ == roots.then_string()) {
132 4196616 : InternalUpdateProtector();
133 : }
134 : }
135 :
136 : int LookupIterator::descriptor_number() const {
137 : DCHECK(!IsElement());
138 : DCHECK(has_property_);
139 : DCHECK(holder_->HasFastProperties());
140 29057588 : return number_;
141 : }
142 :
143 : int LookupIterator::dictionary_entry() const {
144 : DCHECK(!IsElement());
145 : DCHECK(has_property_);
146 : DCHECK(!holder_->HasFastProperties());
147 28678473 : return number_;
148 : }
149 :
150 : LookupIterator::Configuration LookupIterator::ComputeConfiguration(
151 : Configuration configuration, Handle<Name> name) {
152 90285398 : return name->IsPrivate() ? OWN_SKIP_INTERCEPTOR : configuration;
153 : }
154 :
155 70715519 : Handle<JSReceiver> LookupIterator::GetRoot(Isolate* isolate,
156 : Handle<Object> receiver,
157 : uint32_t index) {
158 70715519 : if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver);
159 379367 : return GetRootForNonJSReceiver(isolate, receiver, index);
160 : }
161 :
162 : template <class T>
163 40956102 : Handle<T> LookupIterator::GetStoreTarget() const {
164 : DCHECK(receiver_->IsJSReceiver());
165 40956102 : if (receiver_->IsJSGlobalProxy()) {
166 : Map map = JSGlobalProxy::cast(*receiver_)->map();
167 80451 : if (map->has_hidden_prototype()) {
168 160902 : return handle(JSGlobalObject::cast(map->prototype()), isolate_);
169 : }
170 : }
171 : return Handle<T>::cast(receiver_);
172 : }
173 :
174 : template <bool is_element>
175 : InterceptorInfo LookupIterator::GetInterceptor(JSObject holder) {
176 : return is_element ? holder->GetIndexedInterceptor()
177 1568467 : : holder->GetNamedInterceptor();
178 : }
179 :
180 606060 : inline Handle<InterceptorInfo> LookupIterator::GetInterceptor() const {
181 : DCHECK_EQ(INTERCEPTOR, state_);
182 : InterceptorInfo result =
183 : IsElement() ? GetInterceptor<true>(JSObject::cast(*holder_))
184 606060 : : GetInterceptor<false>(JSObject::cast(*holder_));
185 1212120 : return handle(result, isolate_);
186 : }
187 :
188 : } // namespace internal
189 : } // namespace v8
190 :
191 : #endif // V8_LOOKUP_INL_H_
|