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

Side by Side Diff: src/objects-inl.h

Issue 1704353002: [runtime] Force internalize names used before lookup in in DescriptorArray and TransitionArray (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
« no previous file with comments | « src/objects.cc ('k') | src/property.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 // Review notes: 5 // Review notes:
6 // 6 //
7 // - The use of macros in these inline functions may seem superfluous 7 // - The use of macros in these inline functions may seem superfluous
8 // but it is absolutely needed to make sure gcc generates optimal 8 // but it is absolutely needed to make sure gcc generates optimal
9 // code. gcc is not happy when attempting to inline too deep. 9 // code. gcc is not happy when attempting to inline too deep.
10 // 10 //
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 165 }
166 166
167 bool HeapObject::IsName() const { 167 bool HeapObject::IsName() const {
168 return map()->instance_type() <= LAST_NAME_TYPE; 168 return map()->instance_type() <= LAST_NAME_TYPE;
169 } 169 }
170 170
171 bool HeapObject::IsUniqueName() const { 171 bool HeapObject::IsUniqueName() const {
172 return IsInternalizedString() || IsSymbol(); 172 return IsInternalizedString() || IsSymbol();
173 } 173 }
174 174
175 bool Name::IsUniqueName() const {
176 uint32_t type = map()->instance_type();
177 return (type & (kIsNotStringMask | kIsNotInternalizedMask)) !=
178 (kStringTag | kNotInternalizedTag);
179 }
180
175 bool HeapObject::IsFunction() const { 181 bool HeapObject::IsFunction() const {
176 STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE); 182 STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
177 return map()->instance_type() >= FIRST_FUNCTION_TYPE; 183 return map()->instance_type() >= FIRST_FUNCTION_TYPE;
178 } 184 }
179 185
180 bool HeapObject::IsCallable() const { return map()->is_callable(); } 186 bool HeapObject::IsCallable() const { return map()->is_callable(); }
181 187
182 bool HeapObject::IsConstructor() const { return map()->is_constructor(); } 188 bool HeapObject::IsConstructor() const { return map()->is_constructor(); }
183 189
184 bool HeapObject::IsTemplateInfo() const { 190 bool HeapObject::IsTemplateInfo() const {
(...skipping 2346 matching lines...) Expand 10 before | Expand all | Expand 10 after
2531 return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex)); 2537 return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex));
2532 } 2538 }
2533 2539
2534 2540
2535 Object** DescriptorArray::GetEnumCacheSlot() { 2541 Object** DescriptorArray::GetEnumCacheSlot() {
2536 DCHECK(HasEnumCache()); 2542 DCHECK(HasEnumCache());
2537 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), 2543 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
2538 kEnumCacheOffset); 2544 kEnumCacheOffset);
2539 } 2545 }
2540 2546
2541 2547 // Perform a binary search in a fixed array.
2542 // Perform a binary search in a fixed array. Low and high are entry indices. If
2543 // there are three entries in this array it should be called with low=0 and
2544 // high=2.
2545 template <SearchMode search_mode, typename T> 2548 template <SearchMode search_mode, typename T>
2546 int BinarySearch(T* array, Name* name, int low, int high, int valid_entries, 2549 int BinarySearch(T* array, Name* name, int valid_entries,
2547 int* out_insertion_index) { 2550 int* out_insertion_index) {
2548 DCHECK(search_mode == ALL_ENTRIES || out_insertion_index == NULL); 2551 DCHECK(search_mode == ALL_ENTRIES || out_insertion_index == NULL);
2549 uint32_t hash = name->Hash(); 2552 int low = 0;
2553 int high = array->number_of_entries() - 1;
2554 uint32_t hash = name->hash_field();
2550 int limit = high; 2555 int limit = high;
2551 2556
2552 DCHECK(low <= high); 2557 DCHECK(low <= high);
2553 2558
2554 while (low != high) { 2559 while (low != high) {
2555 int mid = low + (high - low) / 2; 2560 int mid = low + (high - low) / 2;
2556 Name* mid_name = array->GetSortedKey(mid); 2561 Name* mid_name = array->GetSortedKey(mid);
2557 uint32_t mid_hash = mid_name->Hash(); 2562 uint32_t mid_hash = mid_name->hash_field();
2558 2563
2559 if (mid_hash >= hash) { 2564 if (mid_hash >= hash) {
2560 high = mid; 2565 high = mid;
2561 } else { 2566 } else {
2562 low = mid + 1; 2567 low = mid + 1;
2563 } 2568 }
2564 } 2569 }
2565 2570
2566 for (; low <= limit; ++low) { 2571 for (; low <= limit; ++low) {
2567 int sort_index = array->GetSortedKeyIndex(low); 2572 int sort_index = array->GetSortedKeyIndex(low);
2568 Name* entry = array->GetKey(sort_index); 2573 Name* entry = array->GetKey(sort_index);
2569 uint32_t current_hash = entry->Hash(); 2574 uint32_t current_hash = entry->hash_field();
2570 if (current_hash != hash) { 2575 if (current_hash != hash) {
2571 if (out_insertion_index != NULL) { 2576 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
2572 *out_insertion_index = sort_index + (current_hash > hash ? 0 : 1); 2577 *out_insertion_index = sort_index + (current_hash > hash ? 0 : 1);
2573 } 2578 }
2574 return T::kNotFound; 2579 return T::kNotFound;
2575 } 2580 }
2576 if (entry->Equals(name)) { 2581 if (entry == name) {
2577 if (search_mode == ALL_ENTRIES || sort_index < valid_entries) { 2582 if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
2578 return sort_index; 2583 return sort_index;
2579 } 2584 }
2580 return T::kNotFound; 2585 return T::kNotFound;
2581 } 2586 }
2582 } 2587 }
2583 2588
2584 if (out_insertion_index != NULL) *out_insertion_index = limit + 1; 2589 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
2590 *out_insertion_index = limit + 1;
2591 }
2585 return T::kNotFound; 2592 return T::kNotFound;
2586 } 2593 }
2587 2594
2588 2595
2589 // Perform a linear search in this fixed array. len is the number of entry 2596 // Perform a linear search in this fixed array. len is the number of entry
2590 // indices that are valid. 2597 // indices that are valid.
2591 template <SearchMode search_mode, typename T> 2598 template <SearchMode search_mode, typename T>
2592 int LinearSearch(T* array, Name* name, int len, int valid_entries, 2599 int LinearSearch(T* array, Name* name, int valid_entries,
2593 int* out_insertion_index) { 2600 int* out_insertion_index) {
2594 if (search_mode == ALL_ENTRIES) { 2601 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
2595 uint32_t hash = name->Hash(); 2602 uint32_t hash = name->hash_field();
2603 int len = array->number_of_entries();
2596 for (int number = 0; number < len; number++) { 2604 for (int number = 0; number < len; number++) {
2597 int sorted_index = array->GetSortedKeyIndex(number); 2605 int sorted_index = array->GetSortedKeyIndex(number);
2598 Name* entry = array->GetKey(sorted_index); 2606 Name* entry = array->GetKey(sorted_index);
2599 uint32_t current_hash = entry->Hash(); 2607 uint32_t current_hash = entry->hash_field();
2600 if (current_hash > hash) { 2608 if (current_hash > hash) {
2601 if (out_insertion_index != NULL) *out_insertion_index = sorted_index; 2609 *out_insertion_index = sorted_index;
2602 return T::kNotFound; 2610 return T::kNotFound;
2603 } 2611 }
2604 if (current_hash == hash && entry->Equals(name)) return sorted_index; 2612 if (entry == name) return sorted_index;
2605 } 2613 }
2606 if (out_insertion_index != NULL) *out_insertion_index = len; 2614 *out_insertion_index = len;
2607 return T::kNotFound; 2615 return T::kNotFound;
2608 } else { 2616 } else {
2609 DCHECK(len >= valid_entries); 2617 DCHECK_LE(valid_entries, array->number_of_entries());
2610 DCHECK_NULL(out_insertion_index); // Not supported here. 2618 DCHECK_NULL(out_insertion_index); // Not supported here.
2611 for (int number = 0; number < valid_entries; number++) { 2619 for (int number = 0; number < valid_entries; number++) {
2612 if (array->GetKey(number)->Equals(name)) return number; 2620 if (array->GetKey(number) == name) return number;
2613 } 2621 }
2614 return T::kNotFound; 2622 return T::kNotFound;
2615 } 2623 }
2616 } 2624 }
2617 2625
2618 2626
2619 template <SearchMode search_mode, typename T> 2627 template <SearchMode search_mode, typename T>
2620 int Search(T* array, Name* name, int valid_entries, int* out_insertion_index) { 2628 int Search(T* array, Name* name, int valid_entries, int* out_insertion_index) {
2621 if (search_mode == VALID_ENTRIES) { 2629 SLOW_DCHECK(array->IsSortedNoDuplicates());
2622 SLOW_DCHECK(array->IsSortedNoDuplicates(valid_entries));
2623 } else {
2624 SLOW_DCHECK(array->IsSortedNoDuplicates());
2625 }
2626 2630
2627 int nof = array->number_of_entries(); 2631 if (valid_entries == 0) {
2628 if (nof == 0) { 2632 if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
2629 if (out_insertion_index != NULL) *out_insertion_index = 0; 2633 *out_insertion_index = 0;
2634 }
2630 return T::kNotFound; 2635 return T::kNotFound;
2631 } 2636 }
2632 2637
2633 // Fast case: do linear search for small arrays. 2638 // Fast case: do linear search for small arrays.
2634 const int kMaxElementsForLinearSearch = 8; 2639 const int kMaxElementsForLinearSearch = 8;
2635 if ((search_mode == ALL_ENTRIES && 2640 if (valid_entries <= kMaxElementsForLinearSearch) {
2636 nof <= kMaxElementsForLinearSearch) || 2641 return LinearSearch<search_mode>(array, name, valid_entries,
2637 (search_mode == VALID_ENTRIES &&
2638 valid_entries <= (kMaxElementsForLinearSearch * 3))) {
2639 return LinearSearch<search_mode>(array, name, nof, valid_entries,
2640 out_insertion_index); 2642 out_insertion_index);
2641 } 2643 }
2642 2644
2643 // Slow case: perform binary search. 2645 // Slow case: perform binary search.
2644 return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries, 2646 return BinarySearch<search_mode>(array, name, valid_entries,
2645 out_insertion_index); 2647 out_insertion_index);
2646 } 2648 }
2647 2649
2648 2650
2649 int DescriptorArray::Search(Name* name, int valid_descriptors) { 2651 int DescriptorArray::Search(Name* name, int valid_descriptors) {
2652 DCHECK(name->IsUniqueName());
2650 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors, NULL); 2653 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors, NULL);
2651 } 2654 }
2652 2655
2653 int DescriptorArray::SearchWithCache(Isolate* isolate, Name* name, Map* map) { 2656 int DescriptorArray::SearchWithCache(Isolate* isolate, Name* name, Map* map) {
2657 DCHECK(name->IsUniqueName());
2654 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); 2658 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2655 if (number_of_own_descriptors == 0) return kNotFound; 2659 if (number_of_own_descriptors == 0) return kNotFound;
2656 2660
2657 DescriptorLookupCache* cache = isolate->descriptor_lookup_cache(); 2661 DescriptorLookupCache* cache = isolate->descriptor_lookup_cache();
2658 int number = cache->Lookup(map, name); 2662 int number = cache->Lookup(map, name);
2659 2663
2660 if (number == DescriptorLookupCache::kAbsent) { 2664 if (number == DescriptorLookupCache::kAbsent) {
2661 number = Search(name, number_of_own_descriptors); 2665 number = Search(name, number_of_own_descriptors);
2662 cache->Update(map, name, number); 2666 cache->Update(map, name, number);
2663 } 2667 }
2664 2668
2665 return number; 2669 return number;
2666 } 2670 }
2667 2671
2668
2669 PropertyDetails Map::GetLastDescriptorDetails() { 2672 PropertyDetails Map::GetLastDescriptorDetails() {
2670 return instance_descriptors()->GetDetails(LastAdded()); 2673 return instance_descriptors()->GetDetails(LastAdded());
2671 } 2674 }
2672 2675
2673 2676
2674 int Map::LastAdded() { 2677 int Map::LastAdded() {
2675 int number_of_own_descriptors = NumberOfOwnDescriptors(); 2678 int number_of_own_descriptors = NumberOfOwnDescriptors();
2676 DCHECK(number_of_own_descriptors > 0); 2679 DCHECK(number_of_own_descriptors > 0);
2677 return number_of_own_descriptors - 1; 2680 return number_of_own_descriptors - 1;
2678 } 2681 }
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after
3415 3418
3416 3419
3417 Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) { 3420 Handle<String> String::Flatten(Handle<String> string, PretenureFlag pretenure) {
3418 if (!string->IsConsString()) return string; 3421 if (!string->IsConsString()) return string;
3419 Handle<ConsString> cons = Handle<ConsString>::cast(string); 3422 Handle<ConsString> cons = Handle<ConsString>::cast(string);
3420 if (cons->IsFlat()) return handle(cons->first()); 3423 if (cons->IsFlat()) return handle(cons->first());
3421 return SlowFlatten(cons, pretenure); 3424 return SlowFlatten(cons, pretenure);
3422 } 3425 }
3423 3426
3424 3427
3425 Handle<Name> Name::Flatten(Handle<Name> name, PretenureFlag pretenure) {
3426 if (name->IsSymbol()) return name;
3427 return String::Flatten(Handle<String>::cast(name));
3428 }
3429
3430
3431 uint16_t String::Get(int index) { 3428 uint16_t String::Get(int index) {
3432 DCHECK(index >= 0 && index < length()); 3429 DCHECK(index >= 0 && index < length());
3433 switch (StringShape(this).full_representation_tag()) { 3430 switch (StringShape(this).full_representation_tag()) {
3434 case kSeqStringTag | kOneByteStringTag: 3431 case kSeqStringTag | kOneByteStringTag:
3435 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index); 3432 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index);
3436 case kSeqStringTag | kTwoByteStringTag: 3433 case kSeqStringTag | kTwoByteStringTag:
3437 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index); 3434 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
3438 case kConsStringTag | kOneByteStringTag: 3435 case kConsStringTag | kOneByteStringTag:
3439 case kConsStringTag | kTwoByteStringTag: 3436 case kConsStringTag | kTwoByteStringTag:
3440 return ConsString::cast(this)->ConsStringGet(index); 3437 return ConsString::cast(this)->ConsStringGet(index);
(...skipping 4231 matching lines...) Expand 10 before | Expand all | Expand 10 after
7672 #undef WRITE_INT64_FIELD 7669 #undef WRITE_INT64_FIELD
7673 #undef READ_BYTE_FIELD 7670 #undef READ_BYTE_FIELD
7674 #undef WRITE_BYTE_FIELD 7671 #undef WRITE_BYTE_FIELD
7675 #undef NOBARRIER_READ_BYTE_FIELD 7672 #undef NOBARRIER_READ_BYTE_FIELD
7676 #undef NOBARRIER_WRITE_BYTE_FIELD 7673 #undef NOBARRIER_WRITE_BYTE_FIELD
7677 7674
7678 } // namespace internal 7675 } // namespace internal
7679 } // namespace v8 7676 } // namespace v8
7680 7677
7681 #endif // V8_OBJECTS_INL_H_ 7678 #endif // V8_OBJECTS_INL_H_
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | src/property.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698