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

Side by Side Diff: src/lookup.cc

Issue 1612323003: Introduce {FAST,SLOW}_STRING_WRAPPER_ELEMENTS (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: one more DCHECK fix 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
« no previous file with comments | « src/key-accumulator.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/isolate-inl.h" 10 #include "src/isolate-inl.h"
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 InternalHolderIsReceiverOrHiddenPrototype();
394 } 394 }
395 395
396 bool LookupIterator::InternalHolderIsReceiverOrHiddenPrototype() const { 396 bool LookupIterator::InternalHolderIsReceiverOrHiddenPrototype() 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 Object* current = *receiver_; 401 JSReceiver* current = JSReceiver::cast(*receiver_);
402 JSReceiver* holder = *holder_; 402 JSReceiver* holder = *holder_;
403 if (current == holder) return true;
404 if (!holder->map()->is_hidden_prototype()) return false;
403 // JSProxy do not occur as hidden prototypes. 405 // JSProxy do not occur as hidden prototypes.
404 if (current->IsJSProxy()) { 406 if (current->IsJSProxy()) return false;
405 return JSReceiver::cast(current) == holder; 407 PrototypeIterator iter(isolate(), current);
408 while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
409 if (iter.GetCurrent<JSReceiver>() == holder) return true;
410 iter.Advance();
406 } 411 }
407 PrototypeIterator iter(isolate(), current,
408 PrototypeIterator::START_AT_RECEIVER);
409 do {
410 if (iter.GetCurrent<JSReceiver>() == holder) return true;
411 DCHECK(!current->IsJSProxy());
412 iter.Advance();
413 } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
414 return false; 412 return false;
415 } 413 }
416 414
417 415
418 Handle<Object> LookupIterator::FetchValue() const { 416 Handle<Object> LookupIterator::FetchValue() const {
419 Object* result = NULL; 417 Object* result = NULL;
420 if (IsElement()) { 418 if (IsElement()) {
421 Handle<JSObject> holder = GetHolder<JSObject>(); 419 Handle<JSObject> holder = GetHolder<JSObject>();
422 // TODO(verwaest): Optimize.
423 if (holder->IsStringObjectWithCharacterAt(index_)) {
424 Handle<JSValue> js_value = Handle<JSValue>::cast(holder);
425 Handle<String> string(String::cast(js_value->value()));
426 return factory()->LookupSingleCharacterStringFromCode(
427 String::Flatten(string)->Get(index_));
428 }
429
430 ElementsAccessor* accessor = holder->GetElementsAccessor(); 420 ElementsAccessor* accessor = holder->GetElementsAccessor();
431 return accessor->Get(handle(holder->elements()), number_); 421 return accessor->Get(holder, number_);
432 } else if (holder_map_->IsJSGlobalObjectMap()) { 422 } else if (holder_map_->IsJSGlobalObjectMap()) {
433 Handle<JSObject> holder = GetHolder<JSObject>(); 423 Handle<JSObject> holder = GetHolder<JSObject>();
434 result = holder->global_dictionary()->ValueAt(number_); 424 result = holder->global_dictionary()->ValueAt(number_);
435 DCHECK(result->IsPropertyCell()); 425 DCHECK(result->IsPropertyCell());
436 result = PropertyCell::cast(result)->value(); 426 result = PropertyCell::cast(result)->value();
437 } else if (holder_map_->is_dictionary_map()) { 427 } else if (holder_map_->is_dictionary_map()) {
438 result = holder_->property_dictionary()->ValueAt(number_); 428 result = holder_->property_dictionary()->ValueAt(number_);
439 } else if (property_details_.type() == v8::internal::DATA) { 429 } else if (property_details_.type() == v8::internal::DATA) {
440 Handle<JSObject> holder = GetHolder<JSObject>(); 430 Handle<JSObject> holder = GetHolder<JSObject>();
441 FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_); 431 FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 return value; 498 return value;
509 } 499 }
510 500
511 501
512 void LookupIterator::WriteDataValue(Handle<Object> value) { 502 void LookupIterator::WriteDataValue(Handle<Object> value) {
513 DCHECK_EQ(DATA, state_); 503 DCHECK_EQ(DATA, state_);
514 Handle<JSReceiver> holder = GetHolder<JSReceiver>(); 504 Handle<JSReceiver> holder = GetHolder<JSReceiver>();
515 if (IsElement()) { 505 if (IsElement()) {
516 Handle<JSObject> object = Handle<JSObject>::cast(holder); 506 Handle<JSObject> object = Handle<JSObject>::cast(holder);
517 ElementsAccessor* accessor = object->GetElementsAccessor(); 507 ElementsAccessor* accessor = object->GetElementsAccessor();
518 accessor->Set(object->elements(), number_, *value); 508 accessor->Set(object, number_, *value);
519 } else if (holder->IsJSGlobalObject()) { 509 } else if (holder->IsJSGlobalObject()) {
520 Handle<GlobalDictionary> property_dictionary = 510 Handle<GlobalDictionary> property_dictionary =
521 handle(JSObject::cast(*holder)->global_dictionary()); 511 handle(JSObject::cast(*holder)->global_dictionary());
522 PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value, 512 PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value,
523 property_details_); 513 property_details_);
524 } else if (holder_map_->is_dictionary_map()) { 514 } else if (holder_map_->is_dictionary_map()) {
525 NameDictionary* property_dictionary = holder->property_dictionary(); 515 NameDictionary* property_dictionary = holder->property_dictionary();
526 property_dictionary->ValueAtPut(dictionary_entry(), *value); 516 property_dictionary->ValueAtPut(dictionary_entry(), *value);
527 } else if (property_details_.type() == v8::internal::DATA) { 517 } else if (property_details_.type() == v8::internal::DATA) {
528 JSObject::cast(*holder)->WriteToField(descriptor_number(), *value); 518 JSObject::cast(*holder)->WriteToField(descriptor_number(), *value);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 if (map->IsJSProxyMap()) { 608 if (map->IsJSProxyMap()) {
619 // Do not leak private property names. 609 // Do not leak private property names.
620 if (IsElement() || !name_->IsPrivate()) return JSPROXY; 610 if (IsElement() || !name_->IsPrivate()) return JSPROXY;
621 } 611 }
622 if (map->is_access_check_needed() && 612 if (map->is_access_check_needed() &&
623 (IsElement() || !isolate_->IsInternallyUsedPropertyName(name_))) { 613 (IsElement() || !isolate_->IsInternallyUsedPropertyName(name_))) {
624 return ACCESS_CHECK; 614 return ACCESS_CHECK;
625 } 615 }
626 // Fall through. 616 // Fall through.
627 case ACCESS_CHECK: 617 case ACCESS_CHECK:
628 if (exotic_index_state_ != ExoticIndexState::kNotExotic &&
629 holder->IsJSTypedArray() && IsIntegerIndexedExotic(holder)) {
630 return INTEGER_INDEXED_EXOTIC;
631 }
632 if (check_interceptor() && HasInterceptor(map) && 618 if (check_interceptor() && HasInterceptor(map) &&
633 !SkipInterceptor(JSObject::cast(holder))) { 619 !SkipInterceptor(JSObject::cast(holder))) {
634 // Do not leak private property names. 620 // Do not leak private property names.
635 if (!name_.is_null() && name_->IsPrivate()) return NOT_FOUND; 621 if (!name_.is_null() && name_->IsPrivate()) return NOT_FOUND;
636 return INTERCEPTOR; 622 return INTERCEPTOR;
637 } 623 }
638 // Fall through. 624 // Fall through.
639 case INTERCEPTOR: 625 case INTERCEPTOR:
640 if (IsElement()) { 626 if (IsElement()) {
641 // TODO(verwaest): Optimize. 627 JSObject* js_object = JSObject::cast(holder);
642 if (holder->IsStringObjectWithCharacterAt(index_)) { 628 ElementsAccessor* accessor = js_object->GetElementsAccessor();
643 PropertyAttributes attributes = 629 FixedArrayBase* backing_store = js_object->elements();
644 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); 630 number_ = accessor->GetEntryForIndex(js_object, backing_store, index_);
645 property_details_ = PropertyDetails(attributes, v8::internal::DATA, 0, 631 if (number_ == kMaxUInt32) {
646 PropertyCellType::kNoCell); 632 if (*receiver_ == Object::cast(holder) && holder->IsJSTypedArray()) {
647 } else { 633 return INTEGER_INDEXED_EXOTIC;
648 JSObject* js_object = JSObject::cast(holder);
649 if (js_object->elements() == isolate()->heap()->empty_fixed_array()) {
650 return NOT_FOUND;
651 } 634 }
652 635 return NOT_FOUND;
653 ElementsAccessor* accessor = js_object->GetElementsAccessor();
654 FixedArrayBase* backing_store = js_object->elements();
655 number_ =
656 accessor->GetEntryForIndex(js_object, backing_store, index_);
657 if (number_ == kMaxUInt32) return NOT_FOUND;
658 property_details_ = accessor->GetDetails(backing_store, number_);
659 } 636 }
637 property_details_ = accessor->GetDetails(js_object, number_);
638 } else if (exotic_index_state_ != ExoticIndexState::kNotExotic &&
639 holder->IsJSTypedArray() && IsIntegerIndexedExotic(holder)) {
640 return INTEGER_INDEXED_EXOTIC;
660 } else if (!map->is_dictionary_map()) { 641 } else if (!map->is_dictionary_map()) {
661 DescriptorArray* descriptors = map->instance_descriptors(); 642 DescriptorArray* descriptors = map->instance_descriptors();
662 int number = descriptors->SearchWithCache(*name_, map); 643 int number = descriptors->SearchWithCache(*name_, map);
663 if (number == DescriptorArray::kNotFound) return NOT_FOUND; 644 if (number == DescriptorArray::kNotFound) return NOT_FOUND;
664 number_ = static_cast<uint32_t>(number); 645 number_ = static_cast<uint32_t>(number);
665 property_details_ = descriptors->GetDetails(number_); 646 property_details_ = descriptors->GetDetails(number_);
666 } else if (map->IsJSGlobalObjectMap()) { 647 } else if (map->IsJSGlobalObjectMap()) {
667 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary(); 648 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary();
668 int number = dict->FindEntry(name_); 649 int number = dict->FindEntry(name_);
669 if (number == GlobalDictionary::kNotFound) return NOT_FOUND; 650 if (number == GlobalDictionary::kNotFound) return NOT_FOUND;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 // Fall through. 691 // Fall through.
711 default: 692 default:
712 return NOT_FOUND; 693 return NOT_FOUND;
713 } 694 }
714 UNREACHABLE(); 695 UNREACHABLE();
715 return state_; 696 return state_;
716 } 697 }
717 698
718 } // namespace internal 699 } // namespace internal
719 } // namespace v8 700 } // namespace v8
OLDNEW
« no previous file with comments | « src/key-accumulator.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698