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

Side by Side Diff: src/lookup.cc

Issue 1651913005: [runtime] Fix integer indexed property handling (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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
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/isolate-inl.h" 10 #include "src/isolate-inl.h"
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 JSObject::ReoptimizeIfPrototype(receiver); 383 JSObject::ReoptimizeIfPrototype(receiver);
384 } 384 }
385 385
386 holder_map_ = handle(receiver->map(), isolate_); 386 holder_map_ = handle(receiver->map(), isolate_);
387 ReloadPropertyInformation(); 387 ReloadPropertyInformation();
388 } 388 }
389 389
390 390
391 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { 391 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
392 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); 392 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
393 return InternalHolderIsReceiverOrHiddenPrototype(); 393 return IsReceiverOrHiddenPrototype(*holder_);
394 } 394 }
395 395
396 bool LookupIterator::InternalHolderIsReceiverOrHiddenPrototype() const { 396 bool LookupIterator::IsReceiverOrHiddenPrototype(JSReceiver* object) const {
397 // Optimization that only works if configuration_ is not mutable. 397 // Optimization that only works if configuration_ is not mutable.
398 if (!check_prototype_chain()) return true; 398 if (!check_prototype_chain()) return true;
399 DisallowHeapAllocation no_gc; 399 DisallowHeapAllocation no_gc;
400 if (!receiver_->IsJSReceiver()) return false; 400 if (!receiver_->IsJSReceiver()) return false;
401 JSReceiver* current = JSReceiver::cast(*receiver_); 401 JSReceiver* current = JSReceiver::cast(*receiver_);
402 JSReceiver* holder = *holder_; 402 if (current == object) return true;
403 if (current == holder) return true; 403 if (!object->map()->is_hidden_prototype()) return false;
404 if (!holder->map()->is_hidden_prototype()) return false;
405 // JSProxy do not occur as hidden prototypes. 404 // JSProxy do not occur as hidden prototypes.
406 if (current->IsJSProxy()) return false; 405 if (current->IsJSProxy()) return false;
407 PrototypeIterator iter(isolate(), current); 406 PrototypeIterator iter(isolate(), current);
408 while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { 407 while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
409 if (iter.GetCurrent<JSReceiver>() == holder) return true; 408 if (iter.GetCurrent<JSReceiver>() == object) return true;
410 iter.Advance(); 409 iter.Advance();
411 } 410 }
412 return false; 411 return false;
413 } 412 }
414 413
415 414
416 Handle<Object> LookupIterator::FetchValue() const { 415 Handle<Object> LookupIterator::FetchValue() const {
417 Object* result = NULL; 416 Object* result = NULL;
418 if (IsElement()) { 417 if (IsElement()) {
419 Handle<JSObject> holder = GetHolder<JSObject>(); 418 Handle<JSObject> holder = GetHolder<JSObject>();
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 property_dictionary->ValueAtPut(dictionary_entry(), *value); 515 property_dictionary->ValueAtPut(dictionary_entry(), *value);
517 } else if (property_details_.type() == v8::internal::DATA) { 516 } else if (property_details_.type() == v8::internal::DATA) {
518 JSObject::cast(*holder)->WriteToField(descriptor_number(), *value); 517 JSObject::cast(*holder)->WriteToField(descriptor_number(), *value);
519 } else { 518 } else {
520 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type()); 519 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type());
521 } 520 }
522 } 521 }
523 522
524 523
525 bool LookupIterator::IsIntegerIndexedExotic(JSReceiver* holder) { 524 bool LookupIterator::IsIntegerIndexedExotic(JSReceiver* holder) {
526 DCHECK(exotic_index_state_ != ExoticIndexState::kNotExotic); 525 DCHECK(!IsElement());
527 if (exotic_index_state_ == ExoticIndexState::kExotic) return true; 526 if (!name_->IsString()) return false;
528 if (!InternalHolderIsReceiverOrHiddenPrototype()) { 527 if (!IsReceiverOrHiddenPrototype(holder)) return false;
529 exotic_index_state_ = ExoticIndexState::kNotExotic; 528
530 return false; 529 Handle<String> name_string = Handle<String>::cast(name_);
531 } 530 if (name_string->length() == 0) return false;
532 DCHECK(exotic_index_state_ == ExoticIndexState::kUninitialized); 531
533 bool result = false; 532 return IsSpecialIndex(isolate_->unicode_cache(), *name_string);
534 // Compute and cache result.
535 if (IsElement()) {
536 result = index_ >= JSTypedArray::cast(holder)->length_value();
537 } else if (name()->IsString()) {
538 Handle<String> name_string = Handle<String>::cast(name());
539 if (name_string->length() != 0) {
540 result = IsSpecialIndex(isolate_->unicode_cache(), *name_string);
541 }
542 }
543 exotic_index_state_ =
544 result ? ExoticIndexState::kExotic : ExoticIndexState::kNotExotic;
545 return result;
546 } 533 }
547 534
548 535
549 void LookupIterator::InternalizeName() { 536 void LookupIterator::InternalizeName() {
550 if (name_->IsUniqueName()) return; 537 if (name_->IsUniqueName()) return;
551 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); 538 name_ = factory()->InternalizeString(Handle<String>::cast(name_));
552 } 539 }
553 540
554 541
555 bool LookupIterator::HasInterceptor(Map* map) const { 542 bool LookupIterator::HasInterceptor(Map* map) const {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 ElementsAccessor* accessor = js_object->GetElementsAccessor(); 615 ElementsAccessor* accessor = js_object->GetElementsAccessor();
629 FixedArrayBase* backing_store = js_object->elements(); 616 FixedArrayBase* backing_store = js_object->elements();
630 number_ = accessor->GetEntryForIndex(js_object, backing_store, index_); 617 number_ = accessor->GetEntryForIndex(js_object, backing_store, index_);
631 if (number_ == kMaxUInt32) { 618 if (number_ == kMaxUInt32) {
632 if (*receiver_ == Object::cast(holder) && holder->IsJSTypedArray()) { 619 if (*receiver_ == Object::cast(holder) && holder->IsJSTypedArray()) {
633 return INTEGER_INDEXED_EXOTIC; 620 return INTEGER_INDEXED_EXOTIC;
634 } 621 }
635 return NOT_FOUND; 622 return NOT_FOUND;
636 } 623 }
637 property_details_ = accessor->GetDetails(js_object, number_); 624 property_details_ = accessor->GetDetails(js_object, number_);
638 } else if (exotic_index_state_ != ExoticIndexState::kNotExotic && 625 } else if (holder->IsJSTypedArray() && IsIntegerIndexedExotic(holder)) {
639 holder->IsJSTypedArray() && IsIntegerIndexedExotic(holder)) {
640 return INTEGER_INDEXED_EXOTIC; 626 return INTEGER_INDEXED_EXOTIC;
641 } else if (!map->is_dictionary_map()) { 627 } else if (!map->is_dictionary_map()) {
642 DescriptorArray* descriptors = map->instance_descriptors(); 628 DescriptorArray* descriptors = map->instance_descriptors();
643 int number = descriptors->SearchWithCache(*name_, map); 629 int number = descriptors->SearchWithCache(*name_, map);
644 if (number == DescriptorArray::kNotFound) return NOT_FOUND; 630 if (number == DescriptorArray::kNotFound) return NOT_FOUND;
645 number_ = static_cast<uint32_t>(number); 631 number_ = static_cast<uint32_t>(number);
646 property_details_ = descriptors->GetDetails(number_); 632 property_details_ = descriptors->GetDetails(number_);
647 } else if (map->IsJSGlobalObjectMap()) { 633 } else if (map->IsJSGlobalObjectMap()) {
648 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary(); 634 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary();
649 int number = dict->FindEntry(name_); 635 int number = dict->FindEntry(name_);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 // Fall through. 677 // Fall through.
692 default: 678 default:
693 return NOT_FOUND; 679 return NOT_FOUND;
694 } 680 }
695 UNREACHABLE(); 681 UNREACHABLE();
696 return state_; 682 return state_;
697 } 683 }
698 684
699 } // namespace internal 685 } // namespace internal
700 } // namespace v8 686 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698