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

Side by Side Diff: src/lookup.cc

Issue 540903002: Flatten property_kind into state. Add UNKNOWN as a state for dict-mode receivers (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add DCHECKs 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_);
18 DCHECK_NE(TRANSITION, state_);
17 DisallowHeapAllocation no_gc; 19 DisallowHeapAllocation no_gc;
18 has_property_ = false; 20 has_property_ = false;
19 21
20 JSReceiver* holder = NULL; 22 JSReceiver* holder =
23 maybe_holder_.is_null() ? NULL : *maybe_holder_.ToHandleChecked();
21 Map* map = *holder_map_; 24 Map* map = *holder_map_;
22 25
23 // Perform lookup on current holder. 26 // Perform lookup on current holder.
24 state_ = LookupInHolder(map); 27 state_ = LookupInHolder(map, holder);
28 if (IsFound()) return;
25 29
26 // Continue lookup if lookup on current holder failed. 30 // Continue lookup if lookup on current holder failed.
27 while (!IsFound()) { 31 do {
28 JSReceiver* maybe_holder = NextHolder(map); 32 JSReceiver* maybe_holder = NextHolder(map);
29 if (maybe_holder == NULL) break; 33 if (maybe_holder == NULL) break;
30 holder = maybe_holder; 34 holder = maybe_holder;
31 map = holder->map(); 35 map = holder->map();
32 state_ = LookupInHolder(map); 36 state_ = LookupInHolder(map, holder);
33 } 37 } while (!IsFound());
34 38
35 // Either was found in the receiver, or the receiver has no prototype.
36 if (holder == NULL) return; 39 if (holder == NULL) return;
37 40
38 maybe_holder_ = handle(holder, isolate_); 41 maybe_holder_ = handle(holder, isolate_);
39 holder_map_ = handle(map, isolate_); 42 holder_map_ = handle(map, isolate_);
40 } 43 }
41 44
42 45
43 Handle<JSReceiver> LookupIterator::GetRoot() const { 46 Handle<JSReceiver> LookupIterator::GetRoot() const {
44 Handle<Object> receiver = GetReceiver(); 47 Handle<Object> receiver = GetReceiver();
45 if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver); 48 if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver);
(...skipping 28 matching lines...) Expand all
74 } 77 }
75 78
76 79
77 bool LookupIterator::HasAccess(v8::AccessType access_type) const { 80 bool LookupIterator::HasAccess(v8::AccessType access_type) const {
78 DCHECK_EQ(ACCESS_CHECK, state_); 81 DCHECK_EQ(ACCESS_CHECK, state_);
79 DCHECK(is_guaranteed_to_have_holder()); 82 DCHECK(is_guaranteed_to_have_holder());
80 return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type); 83 return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type);
81 } 84 }
82 85
83 86
84 bool LookupIterator::HasProperty() {
85 DCHECK_EQ(PROPERTY, state_);
86 DCHECK(is_guaranteed_to_have_holder());
87
88 if (property_encoding_ == DICTIONARY) {
89 Handle<JSObject> holder = GetHolder<JSObject>();
90 number_ = holder->property_dictionary()->FindEntry(name_);
91 if (number_ == NameDictionary::kNotFound) return false;
92
93 property_details_ = holder->property_dictionary()->DetailsAt(number_);
94 // Holes in dictionary cells are absent values.
95 if (holder->IsGlobalObject() &&
96 (property_details_.IsDeleted() || FetchValue()->IsTheHole())) {
97 return false;
98 }
99 } else {
100 // Can't use descriptor_number() yet because has_property_ is still false.
101 property_details_ =
102 holder_map_->instance_descriptors()->GetDetails(number_);
103 }
104
105 LoadPropertyKind();
106
107 has_property_ = true;
108 return true;
109 }
110
111
112 void LookupIterator::LoadPropertyKind() {
113 switch (property_details_.type()) {
114 case v8::internal::FIELD:
115 case v8::internal::NORMAL:
116 case v8::internal::CONSTANT:
117 property_kind_ = DATA;
118 break;
119 case v8::internal::CALLBACKS:
120 property_kind_ = ACCESSOR;
121 break;
122 }
123 }
124
125
126 void LookupIterator::ReloadPropertyInformation() { 87 void LookupIterator::ReloadPropertyInformation() {
127 state_ = BEFORE_PROPERTY; 88 state_ = BEFORE_PROPERTY;
128 state_ = LookupInHolder(*holder_map_); 89 state_ = LookupInHolder(*holder_map_, *maybe_holder_.ToHandleChecked());
129 DCHECK(IsFound()); 90 DCHECK(IsFound() || holder_map_->is_dictionary_map());
130 HasProperty();
131 } 91 }
132 92
133 93
134 void LookupIterator::PrepareForDataProperty(Handle<Object> value) { 94 void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
135 DCHECK(has_property_); 95 DCHECK(state_ == DATA || state_ == ACCESSOR);
136 DCHECK(HolderIsReceiverOrHiddenPrototype()); 96 DCHECK(HolderIsReceiverOrHiddenPrototype());
137 if (property_encoding_ == DICTIONARY) return; 97 if (property_encoding_ == DICTIONARY) return;
138 holder_map_ = 98 holder_map_ =
139 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); 99 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value);
140 JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_); 100 JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_);
141 ReloadPropertyInformation(); 101 ReloadPropertyInformation();
142 } 102 }
143 103
144 104
145 void LookupIterator::ReconfigureDataProperty(Handle<Object> value, 105 void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
146 PropertyAttributes attributes) { 106 PropertyAttributes attributes) {
147 DCHECK(has_property_); 107 DCHECK(state_ == DATA || state_ == ACCESSOR);
148 DCHECK(HolderIsReceiverOrHiddenPrototype()); 108 DCHECK(HolderIsReceiverOrHiddenPrototype());
149 Handle<JSObject> holder = GetHolder<JSObject>(); 109 Handle<JSObject> holder = GetHolder<JSObject>();
150 if (property_encoding_ != DICTIONARY) { 110 if (property_encoding_ != DICTIONARY) {
151 holder_map_ = Map::ReconfigureDataProperty(holder_map_, descriptor_number(), 111 holder_map_ = Map::ReconfigureDataProperty(holder_map_, descriptor_number(),
152 attributes); 112 attributes);
153 JSObject::MigrateToMap(holder, holder_map_); 113 JSObject::MigrateToMap(holder, holder_map_);
154 } 114 }
155 115
156 if (holder_map_->is_dictionary_map()) { 116 if (holder_map_->is_dictionary_map()) {
157 PropertyDetails details(attributes, NORMAL, 0); 117 PropertyDetails details(attributes, NORMAL, 0);
158 JSObject::SetNormalizedProperty(holder, name(), value, details); 118 JSObject::SetNormalizedProperty(holder, name(), value, details);
159 } 119 }
160 120
161 ReloadPropertyInformation(); 121 ReloadPropertyInformation();
162 } 122 }
163 123
164 124
165 void LookupIterator::PrepareTransitionToDataProperty( 125 void LookupIterator::PrepareTransitionToDataProperty(
166 Handle<Object> value, PropertyAttributes attributes, 126 Handle<Object> value, PropertyAttributes attributes,
167 Object::StoreFromKeyed store_mode) { 127 Object::StoreFromKeyed store_mode) {
168 if (state_ == TRANSITION) return; 128 if (state_ == TRANSITION) return;
169 DCHECK(!has_property_ || property_kind_ != ACCESSOR); 129 DCHECK(state_ != LookupIterator::ACCESSOR ||
170 DCHECK(!(has_property_ || state_ == JSPROXY) || 130 GetAccessors()->IsDeclaredAccessorInfo());
171 !HolderIsReceiverOrHiddenPrototype()); 131 DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype());
172 132
173 // Can only be called when the receiver is a JSObject. JSProxy has to be 133 // Can only be called when the receiver is a JSObject. JSProxy has to be
174 // handled via a trap. Adding properties to primitive values is not 134 // handled via a trap. Adding properties to primitive values is not
175 // observable. 135 // observable.
176 Handle<JSObject> receiver = GetStoreTarget(); 136 Handle<JSObject> receiver = GetStoreTarget();
177 137
178 if (!name().is_identical_to(isolate()->factory()->hidden_string()) && 138 if (!name().is_identical_to(isolate()->factory()->hidden_string()) &&
179 !receiver->map()->is_extensible()) { 139 !receiver->map()->is_extensible()) {
180 return; 140 return;
181 } 141 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 177
218 // We have to deoptimize since accesses to data properties may have been 178 // We have to deoptimize since accesses to data properties may have been
219 // inlined without a corresponding map-check. 179 // inlined without a corresponding map-check.
220 if (holder_map_->IsGlobalObjectMap()) { 180 if (holder_map_->IsGlobalObjectMap()) {
221 Deoptimizer::DeoptimizeGlobalObject(*receiver); 181 Deoptimizer::DeoptimizeGlobalObject(*receiver);
222 } 182 }
223 183
224 // Install the accessor into the dictionary-mode object. 184 // Install the accessor into the dictionary-mode object.
225 PropertyDetails details(attributes, CALLBACKS, 0); 185 PropertyDetails details(attributes, CALLBACKS, 0);
226 Handle<AccessorPair> pair; 186 Handle<AccessorPair> pair;
227 if (IsFound() && HasProperty() && property_kind() == ACCESSOR && 187 if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) {
228 GetAccessors()->IsAccessorPair()) {
229 pair = Handle<AccessorPair>::cast(GetAccessors()); 188 pair = Handle<AccessorPair>::cast(GetAccessors());
230 // If the component and attributes are identical, nothing has to be done. 189 // If the component and attributes are identical, nothing has to be done.
231 if (pair->get(component) == *accessor) { 190 if (pair->get(component) == *accessor) {
232 if (property_details().attributes() == attributes) return; 191 if (property_details().attributes() == attributes) return;
233 } else { 192 } else {
234 pair = AccessorPair::Copy(pair); 193 pair = AccessorPair::Copy(pair);
235 pair->set(component, *accessor); 194 pair->set(component, *accessor);
236 } 195 }
237 } else { 196 } else {
238 pair = isolate()->factory()->NewAccessorPair(); 197 pair = isolate()->factory()->NewAccessorPair();
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 283
325 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { 284 Handle<PropertyCell> LookupIterator::GetPropertyCell() const {
326 Handle<JSObject> holder = GetHolder<JSObject>(); 285 Handle<JSObject> holder = GetHolder<JSObject>();
327 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); 286 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
328 Object* value = global->property_dictionary()->ValueAt(dictionary_entry()); 287 Object* value = global->property_dictionary()->ValueAt(dictionary_entry());
329 return Handle<PropertyCell>(PropertyCell::cast(value)); 288 return Handle<PropertyCell>(PropertyCell::cast(value));
330 } 289 }
331 290
332 291
333 Handle<Object> LookupIterator::GetAccessors() const { 292 Handle<Object> LookupIterator::GetAccessors() const {
334 DCHECK(has_property_); 293 DCHECK_EQ(ACCESSOR, state_);
335 DCHECK_EQ(ACCESSOR, property_kind_);
336 return FetchValue(); 294 return FetchValue();
337 } 295 }
338 296
339 297
340 Handle<Object> LookupIterator::GetDataValue() const { 298 Handle<Object> LookupIterator::GetDataValue() const {
341 DCHECK(has_property_); 299 DCHECK_EQ(DATA, state_);
342 DCHECK_EQ(DATA, property_kind_);
343 Handle<Object> value = FetchValue(); 300 Handle<Object> value = FetchValue();
344 return value; 301 return value;
345 } 302 }
346 303
347 304
348 void LookupIterator::WriteDataValue(Handle<Object> value) { 305 void LookupIterator::WriteDataValue(Handle<Object> value) {
349 DCHECK(is_guaranteed_to_have_holder()); 306 DCHECK(is_guaranteed_to_have_holder());
350 DCHECK(has_property_); 307 DCHECK_EQ(DATA, state_);
351 Handle<JSObject> holder = GetHolder<JSObject>(); 308 Handle<JSObject> holder = GetHolder<JSObject>();
352 if (property_encoding_ == DICTIONARY) { 309 if (property_encoding_ == DICTIONARY) {
353 NameDictionary* property_dictionary = holder->property_dictionary(); 310 NameDictionary* property_dictionary = holder->property_dictionary();
354 if (holder->IsGlobalObject()) { 311 if (holder->IsGlobalObject()) {
355 Handle<PropertyCell> cell( 312 Handle<PropertyCell> cell(
356 PropertyCell::cast(property_dictionary->ValueAt(dictionary_entry()))); 313 PropertyCell::cast(property_dictionary->ValueAt(dictionary_entry())));
357 PropertyCell::SetValueInferType(cell, value); 314 PropertyCell::SetValueInferType(cell, value);
358 } else { 315 } else {
359 property_dictionary->ValueAtPut(dictionary_entry(), *value); 316 property_dictionary->ValueAtPut(dictionary_entry(), *value);
360 } 317 }
361 } else if (property_details_.type() == v8::internal::FIELD) { 318 } else if (property_details_.type() == v8::internal::FIELD) {
362 holder->WriteToField(descriptor_number(), *value); 319 holder->WriteToField(descriptor_number(), *value);
363 } else { 320 } else {
364 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); 321 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type());
365 } 322 }
366 } 323 }
367 324
368 325
369 void LookupIterator::InternalizeName() { 326 void LookupIterator::InternalizeName() {
370 if (name_->IsUniqueName()) return; 327 if (name_->IsUniqueName()) return;
371 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); 328 name_ = factory()->InternalizeString(Handle<String>::cast(name_));
372 } 329 }
373 } } // namespace v8::internal 330 } } // 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