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

Side by Side Diff: src/lookup.cc

Issue 2127583002: [runtime] Better encapsulation of dictionary objects handling in lookup iterator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fixes Created 4 years, 5 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
« no previous file with comments | « src/lookup.h ('k') | src/objects.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/lookup.h" 5 #include "src/lookup.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/elements.h" 9 #include "src/elements.h"
10 #include "src/field-type.h" 10 #include "src/field-type.h"
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 JSObject::TransitionElementsKind(holder, to); 213 JSObject::TransitionElementsKind(holder, to);
214 } 214 }
215 215
216 // Copy the backing store if it is copy-on-write. 216 // Copy the backing store if it is copy-on-write.
217 if (IsFastSmiOrObjectElementsKind(to)) { 217 if (IsFastSmiOrObjectElementsKind(to)) {
218 JSObject::EnsureWritableFastElements(holder); 218 JSObject::EnsureWritableFastElements(holder);
219 } 219 }
220 return; 220 return;
221 } 221 }
222 222
223 if (holder->IsJSGlobalObject()) {
224 Handle<GlobalDictionary> dictionary(holder->global_dictionary());
225 Handle<PropertyCell> cell(
226 PropertyCell::cast(dictionary->ValueAt(dictionary_entry())));
227 DCHECK(!cell->IsTheHole(isolate_));
228 property_details_ = cell->property_details();
229 PropertyCell::PrepareForValue(dictionary, dictionary_entry(), value,
230 property_details_);
231 return;
232 }
223 if (!holder->HasFastProperties()) return; 233 if (!holder->HasFastProperties()) return;
224 234
225 Handle<Map> old_map(holder->map(), isolate_); 235 Handle<Map> old_map(holder->map(), isolate_);
226 Handle<Map> new_map = 236 Handle<Map> new_map =
227 Map::PrepareForDataProperty(old_map, descriptor_number(), value); 237 Map::PrepareForDataProperty(old_map, descriptor_number(), value);
228 238
229 if (old_map.is_identical_to(new_map)) { 239 if (old_map.is_identical_to(new_map)) {
230 // Update the property details if the representation was None. 240 // Update the property details if the representation was None.
231 if (representation().IsNone()) { 241 if (representation().IsNone()) {
232 property_details_ = 242 property_details_ =
(...skipping 12 matching lines...) Expand all
245 DCHECK(state_ == DATA || state_ == ACCESSOR); 255 DCHECK(state_ == DATA || state_ == ACCESSOR);
246 DCHECK(HolderIsReceiverOrHiddenPrototype()); 256 DCHECK(HolderIsReceiverOrHiddenPrototype());
247 Handle<JSObject> holder = GetHolder<JSObject>(); 257 Handle<JSObject> holder = GetHolder<JSObject>();
248 if (IsElement()) { 258 if (IsElement()) {
249 DCHECK(!holder->HasFixedTypedArrayElements()); 259 DCHECK(!holder->HasFixedTypedArrayElements());
250 DCHECK(attributes != NONE || !holder->HasFastElements()); 260 DCHECK(attributes != NONE || !holder->HasFastElements());
251 Handle<FixedArrayBase> elements(holder->elements()); 261 Handle<FixedArrayBase> elements(holder->elements());
252 holder->GetElementsAccessor()->Reconfigure(holder, elements, number_, value, 262 holder->GetElementsAccessor()->Reconfigure(holder, elements, number_, value,
253 attributes); 263 attributes);
254 ReloadPropertyInformation<true>(); 264 ReloadPropertyInformation<true>();
265 } else if (holder->HasFastProperties()) {
266 Handle<Map> old_map(holder->map(), isolate_);
267 Handle<Map> new_map = Map::ReconfigureExistingProperty(
268 old_map, descriptor_number(), i::kData, attributes);
269 new_map = Map::PrepareForDataProperty(new_map, descriptor_number(), value);
270 JSObject::MigrateToMap(holder, new_map);
271 ReloadPropertyInformation<false>();
255 } else { 272 } else {
256 if (!holder->HasFastProperties()) { 273 PropertyDetails details(attributes, v8::internal::DATA, 0,
257 PropertyDetails details(attributes, v8::internal::DATA, 0, 274 PropertyCellType::kMutable);
258 PropertyCellType::kMutable); 275 if (holder->IsJSGlobalObject()) {
259 JSObject::SetNormalizedProperty(holder, name(), value, details); 276 Handle<GlobalDictionary> dictionary(holder->global_dictionary());
277
278 Handle<PropertyCell> cell = PropertyCell::PrepareForValue(
279 dictionary, dictionary_entry(), value, details);
280 cell->set_value(*value);
281 property_details_ = cell->property_details();
260 } else { 282 } else {
261 Handle<Map> old_map(holder->map(), isolate_); 283 Handle<NameDictionary> dictionary(holder->property_dictionary());
262 Handle<Map> new_map = Map::ReconfigureExistingProperty( 284 PropertyDetails original_details =
263 old_map, descriptor_number(), i::kData, attributes); 285 dictionary->DetailsAt(dictionary_entry());
264 new_map = 286 int enumeration_index = original_details.dictionary_index();
265 Map::PrepareForDataProperty(new_map, descriptor_number(), value); 287 DCHECK(enumeration_index > 0);
266 JSObject::MigrateToMap(holder, new_map); 288 details = details.set_index(enumeration_index);
289 dictionary->SetEntry(dictionary_entry(), name(), value, details);
290 property_details_ = details;
267 } 291 }
268 ReloadPropertyInformation<false>(); 292 state_ = DATA;
269 } 293 }
270 294
271 WriteDataValue(value); 295 WriteDataValue(value);
272 296
273 #if VERIFY_HEAP 297 #if VERIFY_HEAP
274 if (FLAG_verify_heap) { 298 if (FLAG_verify_heap) {
275 holder->JSObjectVerify(); 299 holder->JSObjectVerify();
276 } 300 }
277 #endif 301 #endif
278 } 302 }
(...skipping 11 matching lines...) Expand all
290 DCHECK_NE(INTEGER_INDEXED_EXOTIC, state_); 314 DCHECK_NE(INTEGER_INDEXED_EXOTIC, state_);
291 DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype()); 315 DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype());
292 316
293 Handle<Map> map(receiver->map(), isolate_); 317 Handle<Map> map(receiver->map(), isolate_);
294 318
295 // Dictionary maps can always have additional data properties. 319 // Dictionary maps can always have additional data properties.
296 if (map->is_dictionary_map()) { 320 if (map->is_dictionary_map()) {
297 state_ = TRANSITION; 321 state_ = TRANSITION;
298 if (map->IsJSGlobalObjectMap()) { 322 if (map->IsJSGlobalObjectMap()) {
299 // Install a property cell. 323 // Install a property cell.
300 auto cell = JSGlobalObject::EnsurePropertyCell( 324 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(receiver);
301 Handle<JSGlobalObject>::cast(receiver), name()); 325 int entry;
326 Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell(
327 global, name(), PropertyCellType::kUninitialized, &entry);
328 Handle<GlobalDictionary> dictionary(global->global_dictionary(),
329 isolate_);
302 DCHECK(cell->value()->IsTheHole(isolate_)); 330 DCHECK(cell->value()->IsTheHole(isolate_));
331 DCHECK(!value->IsTheHole(isolate_));
303 transition_ = cell; 332 transition_ = cell;
333 // Assign an enumeration index to the property and update
334 // SetNextEnumerationIndex.
335 int index = dictionary->NextEnumerationIndex();
336 dictionary->SetNextEnumerationIndex(index + 1);
337 property_details_ = PropertyDetails(attributes, i::DATA, index,
338 PropertyCellType::kUninitialized);
339 PropertyCellType new_type =
340 PropertyCell::UpdatedType(cell, value, property_details_);
341 property_details_ = property_details_.set_cell_type(new_type);
342 cell->set_property_details(property_details_);
343 number_ = entry;
344 has_property_ = true;
304 } else { 345 } else {
346 // Don't set enumeration index (it will be set during value store).
347 property_details_ =
348 PropertyDetails(attributes, i::DATA, 0, PropertyCellType::kNoCell);
305 transition_ = map; 349 transition_ = map;
306 } 350 }
307 return; 351 return;
308 } 352 }
309 353
310 Handle<Map> transition = 354 Handle<Map> transition =
311 Map::TransitionToDataProperty(map, name_, value, attributes, store_mode); 355 Map::TransitionToDataProperty(map, name_, value, attributes, store_mode);
312 state_ = TRANSITION; 356 state_ = TRANSITION;
313 transition_ = transition; 357 transition_ = transition;
314 358
315 if (!transition->is_dictionary_map()) { 359 if (!transition->is_dictionary_map()) {
316 property_details_ = transition->GetLastDescriptorDetails(); 360 property_details_ = transition->GetLastDescriptorDetails();
317 has_property_ = true; 361 has_property_ = true;
318 } 362 }
319 } 363 }
320 364
321 void LookupIterator::ApplyTransitionToDataProperty(Handle<JSObject> receiver) { 365 void LookupIterator::ApplyTransitionToDataProperty(Handle<JSObject> receiver) {
322 DCHECK_EQ(TRANSITION, state_); 366 DCHECK_EQ(TRANSITION, state_);
323 367
324 DCHECK(receiver.is_identical_to(GetStoreTarget())); 368 DCHECK(receiver.is_identical_to(GetStoreTarget()));
325
326 if (receiver->IsJSGlobalObject()) return;
327 holder_ = receiver; 369 holder_ = receiver;
370 if (receiver->IsJSGlobalObject()) {
371 state_ = DATA;
372 return;
373 }
328 Handle<Map> transition = transition_map(); 374 Handle<Map> transition = transition_map();
329 bool simple_transition = transition->GetBackPointer() == receiver->map(); 375 bool simple_transition = transition->GetBackPointer() == receiver->map();
330 JSObject::MigrateToMap(receiver, transition); 376 JSObject::MigrateToMap(receiver, transition);
331 377
332 if (simple_transition) { 378 if (simple_transition) {
333 int number = transition->LastAdded(); 379 int number = transition->LastAdded();
334 number_ = static_cast<uint32_t>(number); 380 number_ = static_cast<uint32_t>(number);
335 property_details_ = transition->GetLastDescriptorDetails(); 381 property_details_ = transition->GetLastDescriptorDetails();
336 state_ = DATA; 382 state_ = DATA;
383 } else if (receiver->map()->is_dictionary_map()) {
384 Handle<NameDictionary> dictionary(receiver->property_dictionary(),
385 isolate_);
386 int entry;
387 dictionary = NameDictionary::Add(dictionary, name(),
388 isolate_->factory()->uninitialized_value(),
389 property_details_, &entry);
390 receiver->set_properties(*dictionary);
391 // Reload details containing proper enumeration index value.
392 property_details_ = dictionary->DetailsAt(entry);
393 number_ = entry;
394 has_property_ = true;
395 state_ = DATA;
396
337 } else { 397 } else {
338 ReloadPropertyInformation<false>(); 398 ReloadPropertyInformation<false>();
339 } 399 }
340 } 400 }
341 401
342 402
343 void LookupIterator::Delete() { 403 void LookupIterator::Delete() {
344 Handle<JSReceiver> holder = Handle<JSReceiver>::cast(holder_); 404 Handle<JSReceiver> holder = Handle<JSReceiver>::cast(holder_);
345 if (IsElement()) { 405 if (IsElement()) {
346 Handle<JSObject> object = Handle<JSObject>::cast(holder); 406 Handle<JSObject> object = Handle<JSObject>::cast(holder);
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 DCHECK(holder_->HasFastProperties()); 625 DCHECK(holder_->HasFastProperties());
566 DCHECK_EQ(v8::internal::DATA, property_details_.type()); 626 DCHECK_EQ(v8::internal::DATA, property_details_.type());
567 return handle( 627 return handle(
568 holder_->map()->instance_descriptors()->GetFieldType(descriptor_number()), 628 holder_->map()->instance_descriptors()->GetFieldType(descriptor_number()),
569 isolate_); 629 isolate_);
570 } 630 }
571 631
572 632
573 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { 633 Handle<PropertyCell> LookupIterator::GetPropertyCell() const {
574 DCHECK(!IsElement()); 634 DCHECK(!IsElement());
575 Handle<JSObject> holder = GetHolder<JSObject>(); 635 Handle<JSGlobalObject> holder = GetHolder<JSGlobalObject>();
576 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(holder); 636 Object* value = holder->global_dictionary()->ValueAt(dictionary_entry());
577 Object* value = global->global_dictionary()->ValueAt(dictionary_entry());
578 DCHECK(value->IsPropertyCell()); 637 DCHECK(value->IsPropertyCell());
579 return handle(PropertyCell::cast(value)); 638 return handle(PropertyCell::cast(value), isolate_);
580 } 639 }
581 640
582 641
583 Handle<Object> LookupIterator::GetAccessors() const { 642 Handle<Object> LookupIterator::GetAccessors() const {
584 DCHECK_EQ(ACCESSOR, state_); 643 DCHECK_EQ(ACCESSOR, state_);
585 return FetchValue(); 644 return FetchValue();
586 } 645 }
587 646
588 647
589 Handle<Object> LookupIterator::GetDataValue() const { 648 Handle<Object> LookupIterator::GetDataValue() const {
(...skipping 11 matching lines...) Expand all
601 ElementsAccessor* accessor = object->GetElementsAccessor(); 660 ElementsAccessor* accessor = object->GetElementsAccessor();
602 accessor->Set(object, number_, *value); 661 accessor->Set(object, number_, *value);
603 } else if (holder->HasFastProperties()) { 662 } else if (holder->HasFastProperties()) {
604 if (property_details_.type() == v8::internal::DATA) { 663 if (property_details_.type() == v8::internal::DATA) {
605 JSObject::cast(*holder)->WriteToField(descriptor_number(), 664 JSObject::cast(*holder)->WriteToField(descriptor_number(),
606 property_details_, *value); 665 property_details_, *value);
607 } else { 666 } else {
608 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type()); 667 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type());
609 } 668 }
610 } else if (holder->IsJSGlobalObject()) { 669 } else if (holder->IsJSGlobalObject()) {
611 Handle<GlobalDictionary> property_dictionary = 670 GlobalDictionary* dictionary = JSObject::cast(*holder)->global_dictionary();
612 handle(JSObject::cast(*holder)->global_dictionary()); 671 Object* cell = dictionary->ValueAt(dictionary_entry());
613 PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value, 672 DCHECK(cell->IsPropertyCell());
614 property_details_); 673 PropertyCell::cast(cell)->set_value(*value);
615 } else { 674 } else {
616 NameDictionary* property_dictionary = holder->property_dictionary(); 675 NameDictionary* dictionary = holder->property_dictionary();
617 property_dictionary->ValueAtPut(dictionary_entry(), *value); 676 dictionary->ValueAtPut(dictionary_entry(), *value);
618 } 677 }
619 } 678 }
620 679
621 template <bool is_element> 680 template <bool is_element>
622 bool LookupIterator::SkipInterceptor(JSObject* holder) { 681 bool LookupIterator::SkipInterceptor(JSObject* holder) {
623 auto info = GetInterceptor<is_element>(holder); 682 auto info = GetInterceptor<is_element>(holder);
624 // TODO(dcarney): check for symbol/can_intercept_symbols here as well. 683 // TODO(dcarney): check for symbol/can_intercept_symbols here as well.
625 if (info->non_masking()) { 684 if (info->non_masking()) {
626 switch (interceptor_state_) { 685 switch (interceptor_state_) {
627 case InterceptorState::kUninitialized: 686 case InterceptorState::kUninitialized:
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 : access_check_info->named_interceptor(); 827 : access_check_info->named_interceptor();
769 if (interceptor) { 828 if (interceptor) {
770 return handle(InterceptorInfo::cast(interceptor), isolate_); 829 return handle(InterceptorInfo::cast(interceptor), isolate_);
771 } 830 }
772 } 831 }
773 return Handle<InterceptorInfo>(); 832 return Handle<InterceptorInfo>();
774 } 833 }
775 834
776 } // namespace internal 835 } // namespace internal
777 } // namespace v8 836 } // namespace v8
OLDNEW
« no previous file with comments | « src/lookup.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698