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

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: fixing tests Created 4 years, 8 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 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 2460 matching lines...) Expand 10 before | Expand all | Expand 10 after
2471 return nullptr; 2471 return nullptr;
2472 } 2472 }
2473 2473
2474 2474
2475 bool Isolate::use_crankshaft() const { 2475 bool Isolate::use_crankshaft() const {
2476 return FLAG_crankshaft && 2476 return FLAG_crankshaft &&
2477 !serializer_enabled_ && 2477 !serializer_enabled_ &&
2478 CpuFeatures::SupportsCrankshaft(); 2478 CpuFeatures::SupportsCrankshaft();
2479 } 2479 }
2480 2480
2481 bool Isolate::IsArrayOrObjectPrototype(Object* object) {
2482 Object* context = heap()->native_contexts_list();
2483 while (context != heap()->undefined_value()) {
2484 Context* current_context = Context::cast(context);
2485 if (current_context->initial_object_prototype() == object ||
2486 current_context->initial_array_prototype() == object) {
2487 return true;
2488 }
2489 context = current_context->next_context_link();
2490 }
2491 return false;
2492 }
2493
2494 bool Isolate::IsInContextIndex(Object* object, uint32_t index) {
2495 DisallowHeapAllocation no_gc;
2496 Object* context = heap()->native_contexts_list();
2497 while (context != heap()->undefined_value()) {
2498 Context* current_context = Context::cast(context);
2499 if (current_context->get(index) == object) {
2500 return true;
2501 }
2502 context = current_context->next_context_link();
2503 }
2504 return false;
2505 }
2481 2506
2482 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() { 2507 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
2483 PropertyCell* no_elements_cell = heap()->array_protector(); 2508 PropertyCell* no_elements_cell = heap()->array_protector();
2484 bool cell_reports_intact = 2509 bool cell_reports_intact =
2485 no_elements_cell->value()->IsSmi() && 2510 no_elements_cell->value()->IsSmi() &&
2486 Smi::cast(no_elements_cell->value())->value() == kArrayProtectorValid; 2511 Smi::cast(no_elements_cell->value())->value() == kArrayProtectorValid;
2487 2512
2488 #ifdef DEBUG 2513 #ifdef DEBUG
2489 Map* root_array_map = 2514 Map* root_array_map =
2490 get_initial_js_array_map(GetInitialFastElementsKind()); 2515 get_initial_js_array_map(GetInitialFastElementsKind());
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2544 // what the protector stands for: 2569 // what the protector stands for:
2545 // - You'd need to traverse the heap to check that no Array instance has 2570 // - You'd need to traverse the heap to check that no Array instance has
2546 // a constructor property or a modified __proto__ 2571 // a constructor property or a modified __proto__
2547 // - To check that Array[Symbol.species] == Array, JS code has to execute, 2572 // - To check that Array[Symbol.species] == Array, JS code has to execute,
2548 // but JS cannot be invoked in callstack overflow situations 2573 // but JS cannot be invoked in callstack overflow situations
2549 // All that could be checked reliably is that 2574 // All that could be checked reliably is that
2550 // Array.prototype.constructor == Array. Given that limitation, no check is 2575 // Array.prototype.constructor == Array. Given that limitation, no check is
2551 // done here. In place, there are mjsunit tests harmony/array-species* which 2576 // done here. In place, there are mjsunit tests harmony/array-species* which
2552 // ensure that behavior is correct in various invalid protector cases. 2577 // ensure that behavior is correct in various invalid protector cases.
2553 2578
2554 PropertyCell* species_cell = heap()->species_protector(); 2579 Cell* species_cell = heap()->species_protector();
2555 return species_cell->value()->IsSmi() && 2580 return Smi::cast(species_cell->value())->value() == kArrayProtectorValid;
2556 Smi::cast(species_cell->value())->value() == kArrayProtectorValid; 2581 }
2582
2583 bool Isolate::IsArrayIsConcatSpreadableLookupChainIntact() {
2584 Cell* is_concat_spreadable_cell =
2585 heap()->array_is_concat_spreadable_protector();
2586 bool is_concat_spreadable_set =
2587 Smi::cast(is_concat_spreadable_cell->value())->value() ==
2588 kArrayProtectorInvalid;
2589 #ifdef DEBUG
2590 Map* root_array_map = get_initial_js_array_map(GetInitialFastElementsKind());
2591 if (root_array_map == NULL) {
2592 // Ignore the value of is_concat_spreadable during bootstrap.
2593 return !is_concat_spreadable_set;
2594 }
2595 Handle<Object> array_prototype(array_function()->prototype(), this);
2596 Handle<Symbol> key = factory()->is_concat_spreadable_symbol();
2597 Handle<Object> value;
2598 LookupIterator it(array_prototype, key);
2599 if (it.IsFound() && !JSReceiver::GetDataProperty(&it)->IsUndefined()) {
2600 // TODO(cbruni): Currently we do not revert if we unset the
2601 // @@isConcatSpreadable property on Array.prototype or Object.prototype
2602 // hence the reverse implication doesn't hold.
2603 DCHECK(is_concat_spreadable_set);
2604 return false;
2605 }
2606 #endif // DEBUG
2607
2608 return !is_concat_spreadable_set;
2609 }
2610
2611 void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) {
2612 DisallowHeapAllocation no_gc;
2613 if (!object->map()->is_prototype_map()) return;
2614 if (!IsFastArrayConstructorPrototypeChainIntact()) return;
2615 if (!IsArrayOrObjectPrototype(*object)) return;
2616 PropertyCell::SetValueWithInvalidation(
2617 factory()->array_protector(),
2618 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2619 }
2620
2621 void Isolate::InvalidateArrayIsConcatSpreadableProtector() {
2622 DCHECK(factory()->array_is_concat_spreadable_protector()->value()->IsSmi());
2623 DCHECK(IsArrayIsConcatSpreadableLookupChainIntact());
2624 factory()->array_is_concat_spreadable_protector()->set_value(
2625 Smi::FromInt(kArrayProtectorInvalid));
2626 DCHECK(!IsArrayIsConcatSpreadableLookupChainIntact());
2557 } 2627 }
2558 2628
2559 void Isolate::InvalidateArraySpeciesProtector() { 2629 void Isolate::InvalidateArraySpeciesProtector() {
2560 DCHECK(factory()->species_protector()->value()->IsSmi()); 2630 DCHECK(factory()->species_protector()->value()->IsSmi());
2561 DCHECK(IsArraySpeciesLookupChainIntact()); 2631 DCHECK(IsArraySpeciesLookupChainIntact());
2562 PropertyCell::SetValueWithInvalidation( 2632 factory()->species_protector()->set_value(
2563 factory()->species_protector(), 2633 Smi::FromInt(kArrayProtectorInvalid));
2564 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2565 DCHECK(!IsArraySpeciesLookupChainIntact()); 2634 DCHECK(!IsArraySpeciesLookupChainIntact());
2566 } 2635 }
2567 2636
2568 void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) { 2637 bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
2569 DisallowHeapAllocation no_gc; 2638 DisallowHeapAllocation no_gc;
2570 if (IsFastArrayConstructorPrototypeChainIntact() && 2639 return IsInContextIndex(*array, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
2571 object->map()->is_prototype_map()) {
2572 Object* context = heap()->native_contexts_list();
2573 while (!context->IsUndefined()) {
2574 Context* current_context = Context::cast(context);
2575 if (current_context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX) ==
2576 *object ||
2577 current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ==
2578 *object) {
2579 CountUsage(v8::Isolate::UseCounterFeature::kArrayProtectorDirtied);
2580 PropertyCell::SetValueWithInvalidation(
2581 factory()->array_protector(),
2582 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2583 break;
2584 }
2585 context = current_context->get(Context::NEXT_CONTEXT_LINK);
2586 }
2587 }
2588 } 2640 }
2589 2641
2590 2642
2591 bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
2592 if (array->map()->is_prototype_map()) {
2593 Object* context = heap()->native_contexts_list();
2594 while (!context->IsUndefined()) {
2595 Context* current_context = Context::cast(context);
2596 if (current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ==
2597 *array) {
2598 return true;
2599 }
2600 context = current_context->get(Context::NEXT_CONTEXT_LINK);
2601 }
2602 }
2603 return false;
2604 }
2605
2606
2607 CallInterfaceDescriptorData* Isolate::call_descriptor_data(int index) { 2643 CallInterfaceDescriptorData* Isolate::call_descriptor_data(int index) {
2608 DCHECK(0 <= index && index < CallDescriptors::NUMBER_OF_DESCRIPTORS); 2644 DCHECK(0 <= index && index < CallDescriptors::NUMBER_OF_DESCRIPTORS);
2609 return &call_descriptor_data_[index]; 2645 return &call_descriptor_data_[index];
2610 } 2646 }
2611 2647
2612 2648
2613 base::RandomNumberGenerator* Isolate::random_number_generator() { 2649 base::RandomNumberGenerator* Isolate::random_number_generator() {
2614 if (random_number_generator_ == NULL) { 2650 if (random_number_generator_ == NULL) {
2615 if (FLAG_random_seed != 0) { 2651 if (FLAG_random_seed != 0) {
2616 random_number_generator_ = 2652 random_number_generator_ =
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
2980 // Then check whether this scope intercepts. 3016 // Then check whether this scope intercepts.
2981 if ((flag & intercept_mask_)) { 3017 if ((flag & intercept_mask_)) {
2982 intercepted_flags_ |= flag; 3018 intercepted_flags_ |= flag;
2983 return true; 3019 return true;
2984 } 3020 }
2985 return false; 3021 return false;
2986 } 3022 }
2987 3023
2988 } // namespace internal 3024 } // namespace internal
2989 } // namespace v8 3025 } // namespace v8
OLDNEW
« src/builtins.cc ('K') | « src/isolate.h ('k') | src/lookup.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698