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

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: adding more 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
« no previous file with comments | « src/isolate.h ('k') | src/lookup.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 2468 matching lines...) Expand 10 before | Expand all | Expand 10 after
2479 return nullptr; 2479 return nullptr;
2480 } 2480 }
2481 2481
2482 2482
2483 bool Isolate::use_crankshaft() const { 2483 bool Isolate::use_crankshaft() const {
2484 return FLAG_crankshaft && 2484 return FLAG_crankshaft &&
2485 !serializer_enabled_ && 2485 !serializer_enabled_ &&
2486 CpuFeatures::SupportsCrankshaft(); 2486 CpuFeatures::SupportsCrankshaft();
2487 } 2487 }
2488 2488
2489 bool Isolate::ArrayOrObjectPrototypeIsInContext(Object* object) {
Toon Verwaest 2016/04/05 12:57:26 IsArrayOrObjectPrototype
2490 Object* context = heap()->native_contexts_list();
2491 while (context != heap()->undefined_value()) {
2492 Context* current_context = Context::cast(context);
2493 if (current_context->initial_object_prototype() == object ||
2494 current_context->initial_array_prototype() == object) {
2495 return true;
2496 }
2497 context = current_context->next_context_link();
2498 }
2499 return false;
2500 }
2501
2502 bool Isolate::IsInContextIndex(Object* object, uint32_t index) {
2503 DisallowHeapAllocation no_gc;
2504 Object* context = heap()->native_contexts_list();
2505 while (context == heap()->undefined_value()) {
2506 Context* current_context = Context::cast(context);
2507 if (current_context->get(index) == object) {
2508 return true;
2509 }
2510 context = current_context->next_context_link();
2511 }
2512 return false;
2513 }
2489 2514
2490 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() { 2515 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
2491 PropertyCell* no_elements_cell = heap()->array_protector(); 2516 PropertyCell* no_elements_cell = heap()->array_protector();
2492 bool cell_reports_intact = 2517 bool cell_reports_intact =
2493 no_elements_cell->value()->IsSmi() && 2518 no_elements_cell->value()->IsSmi() &&
2494 Smi::cast(no_elements_cell->value())->value() == kArrayProtectorValid; 2519 Smi::cast(no_elements_cell->value())->value() == kArrayProtectorValid;
2495 2520
2496 #ifdef DEBUG 2521 #ifdef DEBUG
2497 Map* root_array_map = 2522 Map* root_array_map =
2498 get_initial_js_array_map(GetInitialFastElementsKind()); 2523 get_initial_js_array_map(GetInitialFastElementsKind());
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2552 // what the protector stands for: 2577 // what the protector stands for:
2553 // - You'd need to traverse the heap to check that no Array instance has 2578 // - You'd need to traverse the heap to check that no Array instance has
2554 // a constructor property or a modified __proto__ 2579 // a constructor property or a modified __proto__
2555 // - To check that Array[Symbol.species] == Array, JS code has to execute, 2580 // - To check that Array[Symbol.species] == Array, JS code has to execute,
2556 // but JS cannot be invoked in callstack overflow situations 2581 // but JS cannot be invoked in callstack overflow situations
2557 // All that could be checked reliably is that 2582 // All that could be checked reliably is that
2558 // Array.prototype.constructor == Array. Given that limitation, no check is 2583 // Array.prototype.constructor == Array. Given that limitation, no check is
2559 // done here. In place, there are mjsunit tests harmony/array-species* which 2584 // done here. In place, there are mjsunit tests harmony/array-species* which
2560 // ensure that behavior is correct in various invalid protector cases. 2585 // ensure that behavior is correct in various invalid protector cases.
2561 2586
2562 PropertyCell* species_cell = heap()->species_protector(); 2587 Cell* species_cell = heap()->species_protector();
2563 return species_cell->value()->IsSmi() && 2588 return Smi::cast(species_cell->value())->value() == kArrayProtectorValid;
2564 Smi::cast(species_cell->value())->value() == kArrayProtectorValid; 2589 }
2590
2591 bool Isolate::IsArrayIsConcatSpreadableLookupChainIntact() {
2592 Cell* is_concat_spreadable_cell =
2593 heap()->array_is_concat_spreadable_protector();
2594 bool is_concat_spreadable_set =
2595 Smi::cast(is_concat_spreadable_cell->value())->value() ==
2596 kArrayProtectorInvalid;
2597 #ifdef DEBUG
2598 Map* root_array_map = get_initial_js_array_map(GetInitialFastElementsKind());
2599 if (root_array_map == NULL) {
2600 // Ignore the value of is_concat_spreadable during bootstrap.
2601 return !is_concat_spreadable_set;
2602 }
2603 Handle<Object> array_prototype(array_function()->prototype(), this);
2604 Handle<Symbol> key = factory()->is_concat_spreadable_symbol();
2605 Handle<Object> value;
2606 LookupIterator it(array_prototype, key);
2607 if (it.IsFound() && it.state() != LookupIterator::JSPROXY) {
2608 MaybeHandle<Object> maybe_value = Object::GetProperty(&it);
Toon Verwaest 2016/04/05 12:57:26 GetDataProperty avoids side effects. You can't jus
2609 if (maybe_value.ToHandle(&value) && !value->IsUndefined()) {
2610 // TODO(cbruni): Currently we do not revert if we unset the
2611 // @@isConcatSpreadable property on Array.prototype or Object.prototype
2612 // hence the reverse implication doesn't hold.
2613 DCHECK(is_concat_spreadable_set);
2614 return false;
2615 }
2616 }
2617 #endif // DEBUG
2618
2619 return !is_concat_spreadable_set;
2620 }
2621
2622 void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) {
2623 DisallowHeapAllocation no_gc;
2624 if (!IsFastArrayConstructorPrototypeChainIntact()) return;
2625 if (!object->map()->is_prototype_map()) return;
Toon Verwaest 2016/04/05 12:57:26 This check is probably faster (and will generally
2626 if (!ArrayOrObjectPrototypeIsInContext(*object)) return;
2627 PropertyCell::SetValueWithInvalidation(
2628 factory()->array_protector(),
2629 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2630 }
2631
2632 void Isolate::InvalidateArrayIsConcatSpreadableProtector() {
2633 DCHECK(factory()->array_is_concat_spreadable_protector()->value()->IsSmi());
2634 DCHECK(IsArrayIsConcatSpreadableLookupChainIntact());
2635 factory()->array_is_concat_spreadable_protector()->set_value(
2636 Smi::FromInt(kArrayProtectorInvalid));
2637 DCHECK(!IsArrayIsConcatSpreadableLookupChainIntact());
2565 } 2638 }
2566 2639
2567 void Isolate::InvalidateArraySpeciesProtector() { 2640 void Isolate::InvalidateArraySpeciesProtector() {
2568 DCHECK(factory()->species_protector()->value()->IsSmi()); 2641 DCHECK(factory()->species_protector()->value()->IsSmi());
2569 DCHECK(IsArraySpeciesLookupChainIntact()); 2642 DCHECK(IsArraySpeciesLookupChainIntact());
2570 PropertyCell::SetValueWithInvalidation( 2643 factory()->species_protector()->set_value(
2571 factory()->species_protector(), 2644 Smi::FromInt(kArrayProtectorInvalid));
2572 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2573 DCHECK(!IsArraySpeciesLookupChainIntact()); 2645 DCHECK(!IsArraySpeciesLookupChainIntact());
2574 } 2646 }
2575 2647
2576 void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) { 2648 bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
2577 DisallowHeapAllocation no_gc; 2649 DisallowHeapAllocation no_gc;
2578 if (IsFastArrayConstructorPrototypeChainIntact() && 2650 return IsInContextIndex(*array, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
2579 object->map()->is_prototype_map()) {
2580 Object* context = heap()->native_contexts_list();
2581 while (!context->IsUndefined()) {
2582 Context* current_context = Context::cast(context);
2583 if (current_context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX) ==
2584 *object ||
2585 current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ==
2586 *object) {
2587 CountUsage(v8::Isolate::UseCounterFeature::kArrayProtectorDirtied);
2588 PropertyCell::SetValueWithInvalidation(
2589 factory()->array_protector(),
2590 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2591 break;
2592 }
2593 context = current_context->get(Context::NEXT_CONTEXT_LINK);
2594 }
2595 }
2596 } 2651 }
2597 2652
2598 2653
2599 bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
2600 if (array->map()->is_prototype_map()) {
2601 Object* context = heap()->native_contexts_list();
2602 while (!context->IsUndefined()) {
2603 Context* current_context = Context::cast(context);
2604 if (current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ==
2605 *array) {
2606 return true;
2607 }
2608 context = current_context->get(Context::NEXT_CONTEXT_LINK);
2609 }
2610 }
2611 return false;
2612 }
2613
2614
2615 CallInterfaceDescriptorData* Isolate::call_descriptor_data(int index) { 2654 CallInterfaceDescriptorData* Isolate::call_descriptor_data(int index) {
2616 DCHECK(0 <= index && index < CallDescriptors::NUMBER_OF_DESCRIPTORS); 2655 DCHECK(0 <= index && index < CallDescriptors::NUMBER_OF_DESCRIPTORS);
2617 return &call_descriptor_data_[index]; 2656 return &call_descriptor_data_[index];
2618 } 2657 }
2619 2658
2620 2659
2621 base::RandomNumberGenerator* Isolate::random_number_generator() { 2660 base::RandomNumberGenerator* Isolate::random_number_generator() {
2622 if (random_number_generator_ == NULL) { 2661 if (random_number_generator_ == NULL) {
2623 if (FLAG_random_seed != 0) { 2662 if (FLAG_random_seed != 0) {
2624 random_number_generator_ = 2663 random_number_generator_ =
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
2988 // Then check whether this scope intercepts. 3027 // Then check whether this scope intercepts.
2989 if ((flag & intercept_mask_)) { 3028 if ((flag & intercept_mask_)) {
2990 intercepted_flags_ |= flag; 3029 intercepted_flags_ |= flag;
2991 return true; 3030 return true;
2992 } 3031 }
2993 return false; 3032 return false;
2994 } 3033 }
2995 3034
2996 } // namespace internal 3035 } // namespace internal
2997 } // namespace v8 3036 } // namespace v8
OLDNEW
« no previous file with comments | « src/isolate.h ('k') | src/lookup.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698