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 2460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |