OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |