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

Side by Side Diff: src/isolate.cc

Issue 1409123003: [runtime] Avoid @@isConcatSpreadable lookup for fast path Array.prototype.concat (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: merging with master Created 4 years, 7 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/isolate.h ('k') | src/isolate-inl.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 #include "src/isolate.h" 5 #include "src/isolate.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include <fstream> // NOLINT(readability/streams) 9 #include <fstream> // NOLINT(readability/streams)
10 #include <sstream> 10 #include <sstream>
(...skipping 2515 matching lines...) Expand 10 before | Expand all | Expand 10 after
2526 return nullptr; 2526 return nullptr;
2527 } 2527 }
2528 2528
2529 2529
2530 bool Isolate::use_crankshaft() const { 2530 bool Isolate::use_crankshaft() const {
2531 return FLAG_crankshaft && 2531 return FLAG_crankshaft &&
2532 !serializer_enabled_ && 2532 !serializer_enabled_ &&
2533 CpuFeatures::SupportsCrankshaft(); 2533 CpuFeatures::SupportsCrankshaft();
2534 } 2534 }
2535 2535
2536 bool Isolate::IsArrayOrObjectPrototype(Object* object) {
2537 Object* context = heap()->native_contexts_list();
2538 while (context != heap()->undefined_value()) {
2539 Context* current_context = Context::cast(context);
2540 if (current_context->initial_object_prototype() == object ||
2541 current_context->initial_array_prototype() == object) {
2542 return true;
2543 }
2544 context = current_context->next_context_link();
2545 }
2546 return false;
2547 }
2548
2549 bool Isolate::IsInAnyContext(Object* object, uint32_t index) {
2550 DisallowHeapAllocation no_gc;
2551 Object* context = heap()->native_contexts_list();
2552 while (context != heap()->undefined_value()) {
2553 Context* current_context = Context::cast(context);
2554 if (current_context->get(index) == object) {
2555 return true;
2556 }
2557 context = current_context->next_context_link();
2558 }
2559 return false;
2560 }
2536 2561
2537 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() { 2562 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
2538 PropertyCell* no_elements_cell = heap()->array_protector(); 2563 PropertyCell* no_elements_cell = heap()->array_protector();
2539 bool cell_reports_intact = 2564 bool cell_reports_intact =
2540 no_elements_cell->value()->IsSmi() && 2565 no_elements_cell->value()->IsSmi() &&
2541 Smi::cast(no_elements_cell->value())->value() == kArrayProtectorValid; 2566 Smi::cast(no_elements_cell->value())->value() == kArrayProtectorValid;
2542 2567
2543 #ifdef DEBUG 2568 #ifdef DEBUG
2544 Map* root_array_map = 2569 Map* root_array_map =
2545 get_initial_js_array_map(GetInitialFastElementsKind()); 2570 get_initial_js_array_map(GetInitialFastElementsKind());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2586 if (!iter.IsAtEnd()) { 2611 if (!iter.IsAtEnd()) {
2587 DCHECK_EQ(false, cell_reports_intact); 2612 DCHECK_EQ(false, cell_reports_intact);
2588 return cell_reports_intact; 2613 return cell_reports_intact;
2589 } 2614 }
2590 2615
2591 #endif 2616 #endif
2592 2617
2593 return cell_reports_intact; 2618 return cell_reports_intact;
2594 } 2619 }
2595 2620
2621 bool Isolate::IsIsConcatSpreadableLookupChainIntact() {
2622 Cell* is_concat_spreadable_cell = heap()->is_concat_spreadable_protector();
2623 bool is_is_concat_spreadable_set =
2624 Smi::cast(is_concat_spreadable_cell->value())->value() ==
2625 kArrayProtectorInvalid;
2626 #ifdef DEBUG
2627 Map* root_array_map = get_initial_js_array_map(GetInitialFastElementsKind());
2628 if (root_array_map == NULL) {
2629 // Ignore the value of is_concat_spreadable during bootstrap.
2630 return !is_is_concat_spreadable_set;
2631 }
2632 Handle<Object> array_prototype(array_function()->prototype(), this);
2633 Handle<Symbol> key = factory()->is_concat_spreadable_symbol();
2634 Handle<Object> value;
2635 LookupIterator it(array_prototype, key);
2636 if (it.IsFound() && !JSReceiver::GetDataProperty(&it)->IsUndefined()) {
2637 // TODO(cbruni): Currently we do not revert if we unset the
2638 // @@isConcatSpreadable property on Array.prototype or Object.prototype
2639 // hence the reverse implication doesn't hold.
2640 DCHECK(is_is_concat_spreadable_set);
2641 return false;
2642 }
2643 #endif // DEBUG
2644
2645 return !is_is_concat_spreadable_set;
2646 }
2647
2648 void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) {
2649 DisallowHeapAllocation no_gc;
2650 if (!object->map()->is_prototype_map()) return;
2651 if (!IsFastArrayConstructorPrototypeChainIntact()) return;
2652 if (!IsArrayOrObjectPrototype(*object)) return;
2653 PropertyCell::SetValueWithInvalidation(
2654 factory()->array_protector(),
2655 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2656 }
2657
2658 void Isolate::InvalidateIsConcatSpreadableProtector() {
2659 DCHECK(factory()->is_concat_spreadable_protector()->value()->IsSmi());
2660 DCHECK(IsIsConcatSpreadableLookupChainIntact());
2661 factory()->is_concat_spreadable_protector()->set_value(
2662 Smi::FromInt(kArrayProtectorInvalid));
2663 DCHECK(!IsIsConcatSpreadableLookupChainIntact());
2664 }
2665
2596 void Isolate::InvalidateArraySpeciesProtector() { 2666 void Isolate::InvalidateArraySpeciesProtector() {
2597 if (!FLAG_harmony_species) return; 2667 if (!FLAG_harmony_species) return;
2598 DCHECK(factory()->species_protector()->value()->IsSmi()); 2668 DCHECK(factory()->species_protector()->value()->IsSmi());
2599 DCHECK(IsArraySpeciesLookupChainIntact()); 2669 DCHECK(IsArraySpeciesLookupChainIntact());
2600 PropertyCell::SetValueWithInvalidation( 2670 factory()->species_protector()->set_value(
2601 factory()->species_protector(), 2671 Smi::FromInt(kArrayProtectorInvalid));
2602 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2603 DCHECK(!IsArraySpeciesLookupChainIntact()); 2672 DCHECK(!IsArraySpeciesLookupChainIntact());
2604 } 2673 }
2605 2674
2606 void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) { 2675 bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
2607 DisallowHeapAllocation no_gc; 2676 DisallowHeapAllocation no_gc;
2608 if (IsFastArrayConstructorPrototypeChainIntact() && 2677 return IsInAnyContext(*array, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
2609 object->map()->is_prototype_map()) {
2610 Object* context = heap()->native_contexts_list();
2611 while (!context->IsUndefined()) {
2612 Context* current_context = Context::cast(context);
2613 if (current_context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX) ==
2614 *object ||
2615 current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ==
2616 *object) {
2617 CountUsage(v8::Isolate::UseCounterFeature::kArrayProtectorDirtied);
2618 PropertyCell::SetValueWithInvalidation(
2619 factory()->array_protector(),
2620 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2621 break;
2622 }
2623 context = current_context->get(Context::NEXT_CONTEXT_LINK);
2624 }
2625 }
2626 } 2678 }
2627 2679
2628 2680
2629 bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
2630 if (array->map()->is_prototype_map()) {
2631 Object* context = heap()->native_contexts_list();
2632 while (!context->IsUndefined()) {
2633 Context* current_context = Context::cast(context);
2634 if (current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ==
2635 *array) {
2636 return true;
2637 }
2638 context = current_context->get(Context::NEXT_CONTEXT_LINK);
2639 }
2640 }
2641 return false;
2642 }
2643
2644
2645 CallInterfaceDescriptorData* Isolate::call_descriptor_data(int index) { 2681 CallInterfaceDescriptorData* Isolate::call_descriptor_data(int index) {
2646 DCHECK(0 <= index && index < CallDescriptors::NUMBER_OF_DESCRIPTORS); 2682 DCHECK(0 <= index && index < CallDescriptors::NUMBER_OF_DESCRIPTORS);
2647 return &call_descriptor_data_[index]; 2683 return &call_descriptor_data_[index];
2648 } 2684 }
2649 2685
2650 2686
2651 base::RandomNumberGenerator* Isolate::random_number_generator() { 2687 base::RandomNumberGenerator* Isolate::random_number_generator() {
2652 if (random_number_generator_ == NULL) { 2688 if (random_number_generator_ == NULL) {
2653 if (FLAG_random_seed != 0) { 2689 if (FLAG_random_seed != 0) {
2654 random_number_generator_ = 2690 random_number_generator_ =
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
3020 // Then check whether this scope intercepts. 3056 // Then check whether this scope intercepts.
3021 if ((flag & intercept_mask_)) { 3057 if ((flag & intercept_mask_)) {
3022 intercepted_flags_ |= flag; 3058 intercepted_flags_ |= flag;
3023 return true; 3059 return true;
3024 } 3060 }
3025 return false; 3061 return false;
3026 } 3062 }
3027 3063
3028 } // namespace internal 3064 } // namespace internal
3029 } // namespace v8 3065 } // namespace v8
OLDNEW
« no previous file with comments | « src/isolate.h ('k') | src/isolate-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698