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

Side by Side Diff: src/lookup.cc

Issue 478043006: Rewrite StoreIC handling using the LookupIterator. Continued from patch 494153002 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 } 50 }
51 51
52 52
53 Handle<Map> LookupIterator::GetReceiverMap() const { 53 Handle<Map> LookupIterator::GetReceiverMap() const {
54 Handle<Object> receiver = GetReceiver(); 54 Handle<Object> receiver = GetReceiver();
55 if (receiver->IsNumber()) return isolate_->factory()->heap_number_map(); 55 if (receiver->IsNumber()) return isolate_->factory()->heap_number_map();
56 return handle(Handle<HeapObject>::cast(receiver)->map()); 56 return handle(Handle<HeapObject>::cast(receiver)->map());
57 } 57 }
58 58
59 59
60 Handle<JSObject> LookupIterator::GetStoreTarget() const {
61 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver());
62
63 if (receiver->IsJSGlobalProxy()) {
64 PrototypeIterator iter(isolate(), receiver);
65 if (iter.IsAtEnd()) return receiver;
66 return Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
67 }
68 return receiver;
69 }
70
71
60 bool LookupIterator::IsBootstrapping() const { 72 bool LookupIterator::IsBootstrapping() const {
61 return isolate_->bootstrapper()->IsActive(); 73 return isolate_->bootstrapper()->IsActive();
62 } 74 }
63 75
64 76
65 bool LookupIterator::HasAccess(v8::AccessType access_type) const { 77 bool LookupIterator::HasAccess(v8::AccessType access_type) const {
66 DCHECK_EQ(ACCESS_CHECK, state_); 78 DCHECK_EQ(ACCESS_CHECK, state_);
67 DCHECK(is_guaranteed_to_have_holder()); 79 DCHECK(is_guaranteed_to_have_holder());
68 return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type); 80 return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type);
69 } 81 }
(...skipping 13 matching lines...) Expand all
83 if (holder->IsGlobalObject() && 95 if (holder->IsGlobalObject() &&
84 (property_details_.IsDeleted() || FetchValue()->IsTheHole())) { 96 (property_details_.IsDeleted() || FetchValue()->IsTheHole())) {
85 return false; 97 return false;
86 } 98 }
87 } else { 99 } else {
88 // Can't use descriptor_number() yet because has_property_ is still false. 100 // Can't use descriptor_number() yet because has_property_ is still false.
89 property_details_ = 101 property_details_ =
90 holder_map_->instance_descriptors()->GetDetails(number_); 102 holder_map_->instance_descriptors()->GetDetails(number_);
91 } 103 }
92 104
105 LoadPropertyKind();
106
107 has_property_ = true;
108 return true;
109 }
110
111
112 void LookupIterator::LoadPropertyKind() {
93 switch (property_details_.type()) { 113 switch (property_details_.type()) {
94 case v8::internal::FIELD: 114 case v8::internal::FIELD:
95 case v8::internal::NORMAL: 115 case v8::internal::NORMAL:
96 case v8::internal::CONSTANT: 116 case v8::internal::CONSTANT:
97 property_kind_ = DATA; 117 property_kind_ = DATA;
98 break; 118 break;
99 case v8::internal::CALLBACKS: 119 case v8::internal::CALLBACKS:
100 property_kind_ = ACCESSOR; 120 property_kind_ = ACCESSOR;
101 break; 121 break;
102 case v8::internal::HANDLER: 122 case v8::internal::HANDLER:
103 case v8::internal::INTERCEPTOR: 123 case v8::internal::INTERCEPTOR:
104 UNREACHABLE(); 124 UNREACHABLE();
105 } 125 }
106
107 has_property_ = true;
108 return true;
109 } 126 }
110 127
111 128
112 void LookupIterator::ReloadPropertyInformation() { 129 void LookupIterator::ReloadPropertyInformation() {
113 state_ = BEFORE_PROPERTY; 130 state_ = BEFORE_PROPERTY;
114 state_ = LookupInHolder(*holder_map_); 131 state_ = LookupInHolder(*holder_map_);
115 DCHECK(IsFound()); 132 DCHECK(IsFound());
116 HasProperty(); 133 HasProperty();
117 } 134 }
118 135
(...skipping 22 matching lines...) Expand all
141 158
142 if (holder_map_->is_dictionary_map()) { 159 if (holder_map_->is_dictionary_map()) {
143 PropertyDetails details(attributes, NORMAL, 0); 160 PropertyDetails details(attributes, NORMAL, 0);
144 JSObject::SetNormalizedProperty(holder, name(), value, details); 161 JSObject::SetNormalizedProperty(holder, name(), value, details);
145 } 162 }
146 163
147 ReloadPropertyInformation(); 164 ReloadPropertyInformation();
148 } 165 }
149 166
150 167
151 void LookupIterator::TransitionToDataProperty( 168 void LookupIterator::PrepareTransitionToDataProperty(
152 Handle<Object> value, PropertyAttributes attributes, 169 Handle<Object> value, PropertyAttributes attributes,
153 Object::StoreFromKeyed store_mode) { 170 Object::StoreFromKeyed store_mode) {
154 DCHECK(!has_property_ || !HolderIsReceiverOrHiddenPrototype()); 171 if (state_ == TRANSITION) return;
172 DCHECK(!has_property_ || property_kind_ != ACCESSOR);
173 DCHECK(!(has_property_ || state_ == JSPROXY) ||
174 !HolderIsReceiverOrHiddenPrototype());
155 175
156 // Can only be called when the receiver is a JSObject. JSProxy has to be 176 // Can only be called when the receiver is a JSObject. JSProxy has to be
157 // handled via a trap. Adding properties to primitive values is not 177 // handled via a trap. Adding properties to primitive values is not
158 // observable. 178 // observable.
159 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver()); 179 Handle<JSObject> receiver = GetStoreTarget();
160 180
161 if (receiver->IsJSGlobalProxy()) { 181 if (!name().is_identical_to(isolate()->factory()->hidden_string()) &&
162 PrototypeIterator iter(isolate(), receiver); 182 !receiver->map()->is_extensible()) {
163 receiver = 183 return;
164 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
165 } 184 }
166 185
186 transition_map_ = Map::TransitionToDataProperty(
187 handle(receiver->map()), name_, value, attributes, store_mode);
188 state_ = TRANSITION;
189 }
190
191
192 void LookupIterator::ApplyTransitionToDataProperty() {
193 DCHECK_EQ(TRANSITION, state_);
194
195 Handle<JSObject> receiver = GetStoreTarget();
167 maybe_holder_ = receiver; 196 maybe_holder_ = receiver;
168 holder_map_ = Map::TransitionToDataProperty(handle(receiver->map()), name_, 197 holder_map_ = transition_map_;
169 value, attributes, store_mode);
170 JSObject::MigrateToMap(receiver, holder_map_); 198 JSObject::MigrateToMap(receiver, holder_map_);
171
172 ReloadPropertyInformation(); 199 ReloadPropertyInformation();
173 } 200 }
174 201
175 202
176 void LookupIterator::TransitionToAccessorProperty( 203 void LookupIterator::TransitionToAccessorProperty(
177 AccessorComponent component, Handle<Object> accessor, 204 AccessorComponent component, Handle<Object> accessor,
178 PropertyAttributes attributes) { 205 PropertyAttributes attributes) {
179 DCHECK(!accessor->IsNull()); 206 DCHECK(!accessor->IsNull());
180 // Can only be called when the receiver is a JSObject. JSProxy has to be 207 // Can only be called when the receiver is a JSObject. JSProxy has to be
181 // handled via a trap. Adding properties to primitive values is not 208 // handled via a trap. Adding properties to primitive values is not
182 // observable. 209 // observable.
183 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver()); 210 Handle<JSObject> receiver = GetStoreTarget();
184
185 if (receiver->IsJSGlobalProxy()) {
186 PrototypeIterator iter(isolate(), receiver);
187 receiver =
188 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
189 }
190
191 maybe_holder_ = receiver; 211 maybe_holder_ = receiver;
192 holder_map_ = Map::TransitionToAccessorProperty( 212 holder_map_ = Map::TransitionToAccessorProperty(
193 handle(receiver->map()), name_, component, accessor, attributes); 213 handle(receiver->map()), name_, component, accessor, attributes);
194 JSObject::MigrateToMap(receiver, holder_map_); 214 JSObject::MigrateToMap(receiver, holder_map_);
195 215
196 ReloadPropertyInformation(); 216 ReloadPropertyInformation();
197 217
198 if (!holder_map_->is_dictionary_map()) return; 218 if (!holder_map_->is_dictionary_map()) return;
199 219
200 // We have to deoptimize since accesses to data properties may have been 220 // We have to deoptimize since accesses to data properties may have been
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 DCHECK(has_property_); 317 DCHECK(has_property_);
298 DCHECK_EQ(DESCRIPTOR, property_encoding_); 318 DCHECK_EQ(DESCRIPTOR, property_encoding_);
299 DCHECK_EQ(v8::internal::FIELD, property_details_.type()); 319 DCHECK_EQ(v8::internal::FIELD, property_details_.type());
300 int index = 320 int index =
301 holder_map()->instance_descriptors()->GetFieldIndex(descriptor_number()); 321 holder_map()->instance_descriptors()->GetFieldIndex(descriptor_number());
302 bool is_double = representation().IsDouble(); 322 bool is_double = representation().IsDouble();
303 return FieldIndex::ForPropertyIndex(*holder_map(), index, is_double); 323 return FieldIndex::ForPropertyIndex(*holder_map(), index, is_double);
304 } 324 }
305 325
306 326
327 Handle<HeapType> LookupIterator::GetFieldType() const {
328 DCHECK(has_property_);
329 DCHECK_EQ(DESCRIPTOR, property_encoding_);
330 DCHECK_EQ(v8::internal::FIELD, property_details_.type());
331 return handle(
332 holder_map()->instance_descriptors()->GetFieldType(descriptor_number()),
333 isolate_);
334 }
335
336
307 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { 337 Handle<PropertyCell> LookupIterator::GetPropertyCell() const {
308 Handle<JSObject> holder = GetHolder<JSObject>(); 338 Handle<JSObject> holder = GetHolder<JSObject>();
309 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); 339 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
310 Object* value = global->property_dictionary()->ValueAt(dictionary_entry()); 340 Object* value = global->property_dictionary()->ValueAt(dictionary_entry());
311 return Handle<PropertyCell>(PropertyCell::cast(value)); 341 return Handle<PropertyCell>(PropertyCell::cast(value));
312 } 342 }
313 343
314 344
315 Handle<Object> LookupIterator::GetAccessors() const { 345 Handle<Object> LookupIterator::GetAccessors() const {
316 DCHECK(has_property_); 346 DCHECK(has_property_);
(...skipping 29 matching lines...) Expand all
346 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); 376 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type());
347 } 377 }
348 } 378 }
349 379
350 380
351 void LookupIterator::InternalizeName() { 381 void LookupIterator::InternalizeName() {
352 if (name_->IsUniqueName()) return; 382 if (name_->IsUniqueName()) return;
353 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); 383 name_ = factory()->InternalizeString(Handle<String>::cast(name_));
354 } 384 }
355 } } // namespace v8::internal 385 } } // 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