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

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: 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 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;
Jakob Kummerow 2016/01/26 14:21:24 Unrelated to the rest of this CL: avoid instantiat
403 // JSProxy do not occur as hidden prototypes. 404 // JSProxy do not occur as hidden prototypes.
Toon Verwaest 2016/01/27 15:02:22 What about adding if (!holder->map()->is_hidden_pr
Jakob Kummerow 2016/01/29 14:31:26 Done.
404 if (current->IsJSProxy()) { 405 if (current->IsJSProxy()) return false;
405 return JSReceiver::cast(current) == holder; 406 PrototypeIterator iter(isolate(), current);
407 while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
408 if (iter.GetCurrent<JSReceiver>() == holder) return true;
409 iter.Advance();
406 } 410 }
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; 411 return false;
415 } 412 }
416 413
417 414
418 Handle<Object> LookupIterator::FetchValue() const { 415 Handle<Object> LookupIterator::FetchValue() const {
419 Object* result = NULL; 416 Object* result = NULL;
420 if (IsElement()) { 417 if (IsElement()) {
421 Handle<JSObject> holder = GetHolder<JSObject>(); 418 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(); 419 ElementsAccessor* accessor = holder->GetElementsAccessor();
431 return accessor->Get(handle(holder->elements()), number_); 420 return accessor->Get(holder, number_);
432 } else if (holder_map_->IsJSGlobalObjectMap()) { 421 } else if (holder_map_->IsJSGlobalObjectMap()) {
433 Handle<JSObject> holder = GetHolder<JSObject>(); 422 Handle<JSObject> holder = GetHolder<JSObject>();
434 result = holder->global_dictionary()->ValueAt(number_); 423 result = holder->global_dictionary()->ValueAt(number_);
435 DCHECK(result->IsPropertyCell()); 424 DCHECK(result->IsPropertyCell());
436 result = PropertyCell::cast(result)->value(); 425 result = PropertyCell::cast(result)->value();
437 } else if (holder_map_->is_dictionary_map()) { 426 } else if (holder_map_->is_dictionary_map()) {
438 result = holder_->property_dictionary()->ValueAt(number_); 427 result = holder_->property_dictionary()->ValueAt(number_);
439 } else if (property_details_.type() == v8::internal::DATA) { 428 } else if (property_details_.type() == v8::internal::DATA) {
440 Handle<JSObject> holder = GetHolder<JSObject>(); 429 Handle<JSObject> holder = GetHolder<JSObject>();
441 FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_); 430 FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 return value; 498 return value;
510 } 499 }
511 500
512 501
513 void LookupIterator::WriteDataValue(Handle<Object> value) { 502 void LookupIterator::WriteDataValue(Handle<Object> value) {
514 DCHECK_EQ(DATA, state_); 503 DCHECK_EQ(DATA, state_);
515 Handle<JSReceiver> holder = GetHolder<JSReceiver>(); 504 Handle<JSReceiver> holder = GetHolder<JSReceiver>();
516 if (IsElement()) { 505 if (IsElement()) {
517 Handle<JSObject> object = Handle<JSObject>::cast(holder); 506 Handle<JSObject> object = Handle<JSObject>::cast(holder);
518 ElementsAccessor* accessor = object->GetElementsAccessor(); 507 ElementsAccessor* accessor = object->GetElementsAccessor();
519 accessor->Set(object->elements(), number_, *value); 508 accessor->Set(object, number_, *value);
520 } else if (holder->IsJSGlobalObject()) { 509 } else if (holder->IsJSGlobalObject()) {
521 Handle<GlobalDictionary> property_dictionary = 510 Handle<GlobalDictionary> property_dictionary =
522 handle(JSObject::cast(*holder)->global_dictionary()); 511 handle(JSObject::cast(*holder)->global_dictionary());
523 PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value, 512 PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value,
524 property_details_); 513 property_details_);
525 } else if (holder_map_->is_dictionary_map()) { 514 } else if (holder_map_->is_dictionary_map()) {
526 NameDictionary* property_dictionary = holder->property_dictionary(); 515 NameDictionary* property_dictionary = holder->property_dictionary();
527 property_dictionary->ValueAtPut(dictionary_entry(), *value); 516 property_dictionary->ValueAtPut(dictionary_entry(), *value);
528 } else if (property_details_.type() == v8::internal::DATA) { 517 } else if (property_details_.type() == v8::internal::DATA) {
529 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
619 if (map->IsJSProxyMap()) { 608 if (map->IsJSProxyMap()) {
620 // Do not leak private property names. 609 // Do not leak private property names.
621 if (IsElement() || !name_->IsPrivate()) return JSPROXY; 610 if (IsElement() || !name_->IsPrivate()) return JSPROXY;
622 } 611 }
623 if (map->is_access_check_needed() && 612 if (map->is_access_check_needed() &&
624 (IsElement() || !isolate_->IsInternallyUsedPropertyName(name_))) { 613 (IsElement() || !isolate_->IsInternallyUsedPropertyName(name_))) {
625 return ACCESS_CHECK; 614 return ACCESS_CHECK;
626 } 615 }
627 // Fall through. 616 // Fall through.
628 case ACCESS_CHECK: 617 case ACCESS_CHECK:
629 if (exotic_index_state_ != ExoticIndexState::kNotExotic &&
630 holder->IsJSTypedArray() && IsIntegerIndexedExotic(holder)) {
631 return INTEGER_INDEXED_EXOTIC;
632 }
633 if (check_interceptor() && HasInterceptor(map) && 618 if (check_interceptor() && HasInterceptor(map) &&
634 !SkipInterceptor(JSObject::cast(holder))) { 619 !SkipInterceptor(JSObject::cast(holder))) {
635 // Do not leak private property names. 620 // Do not leak private property names.
636 if (!name_.is_null() && name_->IsPrivate()) return NOT_FOUND; 621 if (!name_.is_null() && name_->IsPrivate()) return NOT_FOUND;
637 return INTERCEPTOR; 622 return INTERCEPTOR;
638 } 623 }
639 // Fall through. 624 // Fall through.
640 case INTERCEPTOR: 625 case INTERCEPTOR:
641 if (IsElement()) { 626 if (IsElement()) {
642 // TODO(verwaest): Optimize. 627 JSObject* js_object = JSObject::cast(holder);
643 if (holder->IsStringObjectWithCharacterAt(index_)) { 628 ElementsAccessor* accessor = js_object->GetElementsAccessor();
644 PropertyAttributes attributes = 629 FixedArrayBase* backing_store = js_object->elements();
645 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); 630 number_ = accessor->GetEntryForIndex(js_object, backing_store, index_);
646 property_details_ = PropertyDetails(attributes, v8::internal::DATA, 0, 631 if (number_ == kMaxUInt32) {
647 PropertyCellType::kNoCell); 632 if (*receiver_ == Object::cast(holder) && holder->IsJSTypedArray()) {
648 } else { 633 return INTEGER_INDEXED_EXOTIC;
649 JSObject* js_object = JSObject::cast(holder);
650 if (js_object->elements() == isolate()->heap()->empty_fixed_array()) {
651 return NOT_FOUND;
652 } 634 }
653 635 return NOT_FOUND;
654 ElementsAccessor* accessor = js_object->GetElementsAccessor();
655 FixedArrayBase* backing_store = js_object->elements();
656 number_ =
657 accessor->GetEntryForIndex(js_object, backing_store, index_);
658 if (number_ == kMaxUInt32) return NOT_FOUND;
659 property_details_ = accessor->GetDetails(backing_store, number_);
660 } 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;
661 } else if (!map->is_dictionary_map()) { 641 } else if (!map->is_dictionary_map()) {
662 DescriptorArray* descriptors = map->instance_descriptors(); 642 DescriptorArray* descriptors = map->instance_descriptors();
663 int number = descriptors->SearchWithCache(*name_, map); 643 int number = descriptors->SearchWithCache(*name_, map);
664 if (number == DescriptorArray::kNotFound) return NOT_FOUND; 644 if (number == DescriptorArray::kNotFound) return NOT_FOUND;
665 number_ = static_cast<uint32_t>(number); 645 number_ = static_cast<uint32_t>(number);
666 property_details_ = descriptors->GetDetails(number_); 646 property_details_ = descriptors->GetDetails(number_);
667 } else if (map->IsJSGlobalObjectMap()) { 647 } else if (map->IsJSGlobalObjectMap()) {
668 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary(); 648 GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary();
669 int number = dict->FindEntry(name_); 649 int number = dict->FindEntry(name_);
670 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
711 // Fall through. 691 // Fall through.
712 default: 692 default:
713 return NOT_FOUND; 693 return NOT_FOUND;
714 } 694 }
715 UNREACHABLE(); 695 UNREACHABLE();
716 return state_; 696 return state_;
717 } 697 }
718 698
719 } // namespace internal 699 } // namespace internal
720 } // namespace v8 700 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698