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