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