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

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, 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 2464 matching lines...) Expand 10 before | Expand all | Expand 10 after
2475 return nullptr; 2475 return nullptr;
2476 } 2476 }
2477 2477
2478 2478
2479 bool Isolate::use_crankshaft() const { 2479 bool Isolate::use_crankshaft() const {
2480 return FLAG_crankshaft && 2480 return FLAG_crankshaft &&
2481 !serializer_enabled_ && 2481 !serializer_enabled_ &&
2482 CpuFeatures::SupportsCrankshaft(); 2482 CpuFeatures::SupportsCrankshaft();
2483 } 2483 }
2484 2484
2485 Context* Isolate::ContextForArrayOrObjectPrototype(Handle<JSObject> object) {
2486 Object* context = heap()->native_contexts_list();
2487 while (!context->IsUndefined()) {
2488 Context* current_context = Context::cast(context);
2489 if (current_context->initial_object_prototype() == *object ||
2490 current_context->initial_array_prototype() == *object) {
2491 return current_context;
2492 }
2493 context = current_context->get(Context::NEXT_CONTEXT_LINK);
2494 }
2495 return NULL;
2496 }
2497
2498 bool Isolate::IsArrayIsConcatSpreadableSet() {
2499 PropertyCell* is_concat_spreadable_cell =
2500 heap()->array_is_concat_spreadable_protector();
2501 bool is_concat_spreadable_set =
2502 is_concat_spreadable_cell->value()->IsSmi() &&
2503 Smi::cast(is_concat_spreadable_cell->value())->value() ==
2504 kArrayIsConcatSpreadableProtectorInvalid;
2505 #ifdef DEBUG
2506 Map* root_array_map = get_initial_js_array_map(GetInitialFastElementsKind());
2507 if (root_array_map == NULL) {
2508 // Ignore the value of is_concat_spreadable during bootstrap.
2509 return is_concat_spreadable_set;
2510 }
2511 Handle<Object> array_prototype(array_function()->prototype(), this);
2512 Handle<Symbol> key = factory()->is_concat_spreadable_symbol();
2513 Handle<Object> value;
2514 LookupIterator it(array_prototype, key);
2515 if (it.IsFound() && it.state() != LookupIterator::JSPROXY) {
2516 MaybeHandle<Object> maybe_value = Object::GetProperty(&it);
2517 if (maybe_value.ToHandle(&value) && !value->IsUndefined()) {
2518 // TODO(cbruni): Currently we do not revert if we unset the
2519 // @@isConcatSpreadable property on Array.prototype or Object.prototype
2520 // hence the reverse implication doesn't hold.
2521 DCHECK(is_concat_spreadable_set);
2522 return true;
2523 }
2524 }
2525 #endif // DEBUG
2526 return is_concat_spreadable_set;
2527 }
2528
2529 void Isolate::UpdateArrayIsConcatSpreadableProtectorOnAddProperty(
2530 Handle<JSObject> object, Handle<Name> name) {
2531 // The invalidate the is_concat_spreadable_protector invalidation is a one-way
2532 // action.
2533 if (IsArrayIsConcatSpreadableSet()) return;
2534 if (!object->map()->is_prototype_map()) return;
2535 Handle<Name> key = factory()->is_concat_spreadable_symbol();
2536 if (!Name::Equals(name, key)) return;
2537 Context* context = ContextForArrayOrObjectPrototype(object);
2538 if (context == NULL) return;
2539 PropertyCell::SetValueWithInvalidation(
2540 factory()->array_is_concat_spreadable_protector(),
2541 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2542 }
2485 2543
2486 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() { 2544 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
2487 PropertyCell* no_elements_cell = heap()->array_protector(); 2545 PropertyCell* no_elements_cell = heap()->array_protector();
2488 bool cell_reports_intact = 2546 bool cell_reports_intact =
2489 no_elements_cell->value()->IsSmi() && 2547 no_elements_cell->value()->IsSmi() &&
2490 Smi::cast(no_elements_cell->value())->value() == kArrayProtectorValid; 2548 Smi::cast(no_elements_cell->value())->value() == kArrayProtectorValid;
2491 2549
2492 #ifdef DEBUG 2550 #ifdef DEBUG
2493 Map* root_array_map = 2551 Map* root_array_map =
2494 get_initial_js_array_map(GetInitialFastElementsKind()); 2552 get_initial_js_array_map(GetInitialFastElementsKind());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2564 DCHECK(factory()->species_protector()->value()->IsSmi()); 2622 DCHECK(factory()->species_protector()->value()->IsSmi());
2565 DCHECK(IsArraySpeciesLookupChainIntact()); 2623 DCHECK(IsArraySpeciesLookupChainIntact());
2566 PropertyCell::SetValueWithInvalidation( 2624 PropertyCell::SetValueWithInvalidation(
2567 factory()->species_protector(), 2625 factory()->species_protector(),
2568 handle(Smi::FromInt(kArrayProtectorInvalid), this)); 2626 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2569 DCHECK(!IsArraySpeciesLookupChainIntact()); 2627 DCHECK(!IsArraySpeciesLookupChainIntact());
2570 } 2628 }
2571 2629
2572 void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) { 2630 void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) {
2573 DisallowHeapAllocation no_gc; 2631 DisallowHeapAllocation no_gc;
2574 if (IsFastArrayConstructorPrototypeChainIntact() && 2632 if (!IsFastArrayConstructorPrototypeChainIntact()) return;
2575 object->map()->is_prototype_map()) { 2633 if (!object->map()->is_prototype_map()) return;
2576 Object* context = heap()->native_contexts_list(); 2634 Context* context = ContextForArrayOrObjectPrototype(object);
2577 while (!context->IsUndefined()) { 2635 if (context == NULL) return;
2578 Context* current_context = Context::cast(context); 2636 PropertyCell::SetValueWithInvalidation(
2579 if (current_context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX) == 2637 factory()->array_protector(),
2580 *object || 2638 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2581 current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ==
2582 *object) {
2583 CountUsage(v8::Isolate::UseCounterFeature::kArrayProtectorDirtied);
2584 PropertyCell::SetValueWithInvalidation(
2585 factory()->array_protector(),
2586 handle(Smi::FromInt(kArrayProtectorInvalid), this));
2587 break;
2588 }
2589 context = current_context->get(Context::NEXT_CONTEXT_LINK);
2590 }
2591 }
2592 } 2639 }
2593 2640
2594 2641
2595 bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) { 2642 bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
2596 if (array->map()->is_prototype_map()) { 2643 DisallowHeapAllocation no_gc;
2597 Object* context = heap()->native_contexts_list(); 2644 JSArray* raw_array = *array;
2598 while (!context->IsUndefined()) { 2645 if (!raw_array->map()->is_prototype_map()) return false;
2599 Context* current_context = Context::cast(context); 2646 Object* context = heap()->native_contexts_list();
2600 if (current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) == 2647 while (!context->IsUndefined()) {
2601 *array) { 2648 Context* current_context = Context::cast(context);
2602 return true; 2649 if (current_context->initial_array_prototype() == raw_array) {
2603 } 2650 return true;
2604 context = current_context->get(Context::NEXT_CONTEXT_LINK);
2605 } 2651 }
2652 context = current_context->get(Context::NEXT_CONTEXT_LINK);
2606 } 2653 }
2607 return false; 2654 return false;
2608 } 2655 }
2609 2656
2610 2657
2611 CallInterfaceDescriptorData* Isolate::call_descriptor_data(int index) { 2658 CallInterfaceDescriptorData* Isolate::call_descriptor_data(int index) {
2612 DCHECK(0 <= index && index < CallDescriptors::NUMBER_OF_DESCRIPTORS); 2659 DCHECK(0 <= index && index < CallDescriptors::NUMBER_OF_DESCRIPTORS);
2613 return &call_descriptor_data_[index]; 2660 return &call_descriptor_data_[index];
2614 } 2661 }
2615 2662
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
2976 // Then check whether this scope intercepts. 3023 // Then check whether this scope intercepts.
2977 if ((flag & intercept_mask_)) { 3024 if ((flag & intercept_mask_)) {
2978 intercepted_flags_ |= flag; 3025 intercepted_flags_ |= flag;
2979 return true; 3026 return true;
2980 } 3027 }
2981 return false; 3028 return false;
2982 } 3029 }
2983 3030
2984 } // namespace internal 3031 } // namespace internal
2985 } // namespace v8 3032 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698