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

Side by Side Diff: src/lookup.cc

Issue 570293002: Simplify the LookupIterator (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « src/lookup.h ('k') | src/lookup-inl.h » ('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 2014 the V8 project authors. All rights reserved. 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 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/deoptimizer.h" 8 #include "src/deoptimizer.h"
9 #include "src/lookup.h" 9 #include "src/lookup.h"
10 #include "src/lookup-inl.h" 10 #include "src/lookup-inl.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 15
16 void LookupIterator::Next() { 16 void LookupIterator::Next() {
17 DCHECK_NE(JSPROXY, state_); 17 DCHECK_NE(JSPROXY, state_);
18 DCHECK_NE(TRANSITION, state_); 18 DCHECK_NE(TRANSITION, state_);
19 DisallowHeapAllocation no_gc; 19 DisallowHeapAllocation no_gc;
20 has_property_ = false; 20 has_property_ = false;
21 21
22 JSReceiver* holder = 22 JSReceiver* holder = *holder_;
23 maybe_holder_.is_null() ? NULL : *maybe_holder_.ToHandleChecked();
24 Map* map = *holder_map_; 23 Map* map = *holder_map_;
25 24
26 // Perform lookup on current holder. 25 // Perform lookup on current holder.
27 state_ = LookupInHolder(map, holder); 26 state_ = LookupInHolder(map, holder);
28 if (IsFound()) return; 27 if (IsFound()) return;
29 28
30 // Continue lookup if lookup on current holder failed. 29 // Continue lookup if lookup on current holder failed.
31 do { 30 do {
32 JSReceiver* maybe_holder = NextHolder(map); 31 JSReceiver* maybe_holder = NextHolder(map);
33 if (maybe_holder == NULL) break; 32 if (maybe_holder == NULL) break;
34 holder = maybe_holder; 33 holder = maybe_holder;
35 map = holder->map(); 34 map = holder->map();
36 state_ = LookupInHolder(map, holder); 35 state_ = LookupInHolder(map, holder);
37 } while (!IsFound()); 36 } while (!IsFound());
38 37
39 if (holder == NULL) return; 38 if (holder != *holder_) {
40 39 holder_ = handle(holder, isolate_);
41 maybe_holder_ = handle(holder, isolate_); 40 holder_map_ = handle(map, isolate_);
42 holder_map_ = handle(map, isolate_); 41 }
43 } 42 }
44 43
45 44
46 Handle<JSReceiver> LookupIterator::GetRoot() const { 45 Handle<JSReceiver> LookupIterator::GetRoot() const {
47 Handle<Object> receiver = GetReceiver(); 46 if (receiver_->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver_);
48 if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver);
49 Handle<Object> root = 47 Handle<Object> root =
50 handle(receiver->GetRootMap(isolate_)->prototype(), isolate_); 48 handle(receiver_->GetRootMap(isolate_)->prototype(), isolate_);
51 CHECK(!root->IsNull()); 49 CHECK(!root->IsNull());
52 return Handle<JSReceiver>::cast(root); 50 return Handle<JSReceiver>::cast(root);
53 } 51 }
54 52
55 53
56 Handle<Map> LookupIterator::GetReceiverMap() const { 54 Handle<Map> LookupIterator::GetReceiverMap() const {
57 Handle<Object> receiver = GetReceiver(); 55 if (receiver_->IsNumber()) return isolate_->factory()->heap_number_map();
58 if (receiver->IsNumber()) return isolate_->factory()->heap_number_map(); 56 return handle(Handle<HeapObject>::cast(receiver_)->map(), isolate_);
59 return handle(Handle<HeapObject>::cast(receiver)->map(), isolate_);
60 } 57 }
61 58
62 59
63 Handle<JSObject> LookupIterator::GetStoreTarget() const { 60 Handle<JSObject> LookupIterator::GetStoreTarget() const {
64 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver()); 61 if (receiver_->IsJSGlobalProxy()) {
65 62 PrototypeIterator iter(isolate(), receiver_);
66 if (receiver->IsJSGlobalProxy()) { 63 if (iter.IsAtEnd()) return Handle<JSGlobalProxy>::cast(receiver_);
67 PrototypeIterator iter(isolate(), receiver);
68 if (iter.IsAtEnd()) return receiver;
69 return Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); 64 return Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
70 } 65 }
71 return receiver; 66 return Handle<JSObject>::cast(receiver_);
72 } 67 }
73 68
74 69
75 bool LookupIterator::IsBootstrapping() const { 70 bool LookupIterator::IsBootstrapping() const {
76 return isolate_->bootstrapper()->IsActive(); 71 return isolate_->bootstrapper()->IsActive();
77 } 72 }
78 73
79 74
80 bool LookupIterator::HasAccess(v8::AccessType access_type) const { 75 bool LookupIterator::HasAccess(v8::AccessType access_type) const {
81 DCHECK_EQ(ACCESS_CHECK, state_); 76 DCHECK_EQ(ACCESS_CHECK, state_);
82 DCHECK(is_guaranteed_to_have_holder());
83 return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type); 77 return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type);
84 } 78 }
85 79
86 80
87 void LookupIterator::ReloadPropertyInformation() { 81 void LookupIterator::ReloadPropertyInformation() {
88 state_ = BEFORE_PROPERTY; 82 state_ = BEFORE_PROPERTY;
89 state_ = LookupInHolder(*holder_map_, *maybe_holder_.ToHandleChecked()); 83 state_ = LookupInHolder(*holder_map_, *holder_);
90 DCHECK(IsFound() || holder_map_->is_dictionary_map()); 84 DCHECK(IsFound() || holder_map_->is_dictionary_map());
91 } 85 }
92 86
93 87
94 void LookupIterator::PrepareForDataProperty(Handle<Object> value) { 88 void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
95 DCHECK(state_ == DATA || state_ == ACCESSOR); 89 DCHECK(state_ == DATA || state_ == ACCESSOR);
96 DCHECK(HolderIsReceiverOrHiddenPrototype()); 90 DCHECK(HolderIsReceiverOrHiddenPrototype());
97 if (holder_map_->is_dictionary_map()) return; 91 if (holder_map_->is_dictionary_map()) return;
98 holder_map_ = 92 holder_map_ =
99 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); 93 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 transition_map_ = Map::TransitionToDataProperty( 135 transition_map_ = Map::TransitionToDataProperty(
142 handle(receiver->map(), isolate_), name_, value, attributes, store_mode); 136 handle(receiver->map(), isolate_), name_, value, attributes, store_mode);
143 state_ = TRANSITION; 137 state_ = TRANSITION;
144 } 138 }
145 139
146 140
147 void LookupIterator::ApplyTransitionToDataProperty() { 141 void LookupIterator::ApplyTransitionToDataProperty() {
148 DCHECK_EQ(TRANSITION, state_); 142 DCHECK_EQ(TRANSITION, state_);
149 143
150 Handle<JSObject> receiver = GetStoreTarget(); 144 Handle<JSObject> receiver = GetStoreTarget();
151 maybe_holder_ = receiver; 145 holder_ = receiver;
152 holder_map_ = transition_map_; 146 holder_map_ = transition_map_;
153 JSObject::MigrateToMap(receiver, holder_map_); 147 JSObject::MigrateToMap(receiver, holder_map_);
154 ReloadPropertyInformation(); 148 ReloadPropertyInformation();
155 } 149 }
156 150
157 151
158 void LookupIterator::TransitionToAccessorProperty( 152 void LookupIterator::TransitionToAccessorProperty(
159 AccessorComponent component, Handle<Object> accessor, 153 AccessorComponent component, Handle<Object> accessor,
160 PropertyAttributes attributes) { 154 PropertyAttributes attributes) {
161 DCHECK(!accessor->IsNull()); 155 DCHECK(!accessor->IsNull());
162 // Can only be called when the receiver is a JSObject. JSProxy has to be 156 // Can only be called when the receiver is a JSObject. JSProxy has to be
163 // handled via a trap. Adding properties to primitive values is not 157 // handled via a trap. Adding properties to primitive values is not
164 // observable. 158 // observable.
165 Handle<JSObject> receiver = GetStoreTarget(); 159 Handle<JSObject> receiver = GetStoreTarget();
166 maybe_holder_ = receiver; 160 holder_ = receiver;
167 holder_map_ = 161 holder_map_ =
168 Map::TransitionToAccessorProperty(handle(receiver->map(), isolate_), 162 Map::TransitionToAccessorProperty(handle(receiver->map(), isolate_),
169 name_, component, accessor, attributes); 163 name_, component, accessor, attributes);
170 JSObject::MigrateToMap(receiver, holder_map_); 164 JSObject::MigrateToMap(receiver, holder_map_);
171 165
172 ReloadPropertyInformation(); 166 ReloadPropertyInformation();
173 167
174 if (!holder_map_->is_dictionary_map()) return; 168 if (!holder_map_->is_dictionary_map()) return;
175 169
176 // We have to deoptimize since accesses to data properties may have been 170 // We have to deoptimize since accesses to data properties may have been
(...skipping 24 matching lines...) Expand all
201 holder_map_ = handle(receiver->map(), isolate_); 195 holder_map_ = handle(receiver->map(), isolate_);
202 ReloadPropertyInformation(); 196 ReloadPropertyInformation();
203 } 197 }
204 198
205 199
206 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { 200 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
207 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); 201 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
208 // Optimization that only works if configuration_ is not mutable. 202 // Optimization that only works if configuration_ is not mutable.
209 if (!check_prototype_chain()) return true; 203 if (!check_prototype_chain()) return true;
210 DisallowHeapAllocation no_gc; 204 DisallowHeapAllocation no_gc;
211 Handle<Object> receiver = GetReceiver(); 205 if (!receiver_->IsJSReceiver()) return false;
212 if (!receiver->IsJSReceiver()) return false; 206 Object* current = *receiver_;
213 Object* current = *receiver; 207 JSReceiver* holder = *holder_;
214 JSReceiver* holder = *maybe_holder_.ToHandleChecked();
215 // JSProxy do not occur as hidden prototypes. 208 // JSProxy do not occur as hidden prototypes.
216 if (current->IsJSProxy()) { 209 if (current->IsJSProxy()) {
217 return JSReceiver::cast(current) == holder; 210 return JSReceiver::cast(current) == holder;
218 } 211 }
219 PrototypeIterator iter(isolate(), current, 212 PrototypeIterator iter(isolate(), current,
220 PrototypeIterator::START_AT_RECEIVER); 213 PrototypeIterator::START_AT_RECEIVER);
221 do { 214 do {
222 if (JSReceiver::cast(iter.GetCurrent()) == holder) return true; 215 if (JSReceiver::cast(iter.GetCurrent()) == holder) return true;
223 DCHECK(!current->IsJSProxy()); 216 DCHECK(!current->IsJSProxy());
224 iter.Advance(); 217 iter.Advance();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 283
291 284
292 Handle<Object> LookupIterator::GetDataValue() const { 285 Handle<Object> LookupIterator::GetDataValue() const {
293 DCHECK_EQ(DATA, state_); 286 DCHECK_EQ(DATA, state_);
294 Handle<Object> value = FetchValue(); 287 Handle<Object> value = FetchValue();
295 return value; 288 return value;
296 } 289 }
297 290
298 291
299 void LookupIterator::WriteDataValue(Handle<Object> value) { 292 void LookupIterator::WriteDataValue(Handle<Object> value) {
300 DCHECK(is_guaranteed_to_have_holder());
301 DCHECK_EQ(DATA, state_); 293 DCHECK_EQ(DATA, state_);
302 Handle<JSObject> holder = GetHolder<JSObject>(); 294 Handle<JSObject> holder = GetHolder<JSObject>();
303 if (holder_map_->is_dictionary_map()) { 295 if (holder_map_->is_dictionary_map()) {
304 NameDictionary* property_dictionary = holder->property_dictionary(); 296 NameDictionary* property_dictionary = holder->property_dictionary();
305 if (holder->IsGlobalObject()) { 297 if (holder->IsGlobalObject()) {
306 Handle<PropertyCell> cell( 298 Handle<PropertyCell> cell(
307 PropertyCell::cast(property_dictionary->ValueAt(dictionary_entry()))); 299 PropertyCell::cast(property_dictionary->ValueAt(dictionary_entry())));
308 PropertyCell::SetValueInferType(cell, value); 300 PropertyCell::SetValueInferType(cell, value);
309 } else { 301 } else {
310 property_dictionary->ValueAtPut(dictionary_entry(), *value); 302 property_dictionary->ValueAtPut(dictionary_entry(), *value);
311 } 303 }
312 } else if (property_details_.type() == v8::internal::FIELD) { 304 } else if (property_details_.type() == v8::internal::FIELD) {
313 holder->WriteToField(descriptor_number(), *value); 305 holder->WriteToField(descriptor_number(), *value);
314 } else { 306 } else {
315 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); 307 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type());
316 } 308 }
317 } 309 }
318 310
319 311
320 void LookupIterator::InternalizeName() { 312 void LookupIterator::InternalizeName() {
321 if (name_->IsUniqueName()) return; 313 if (name_->IsUniqueName()) return;
322 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); 314 name_ = factory()->InternalizeString(Handle<String>::cast(name_));
323 } 315 }
324 } } // namespace v8::internal 316 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/lookup.h ('k') | src/lookup-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698