OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <memory> | 9 #include <memory> |
10 #include <sstream> | 10 #include <sstream> |
(...skipping 3511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3522 return; | 3522 return; |
3523 } | 3523 } |
3524 | 3524 |
3525 // If there is still space in the object, we need to allocate a mutable | 3525 // If there is still space in the object, we need to allocate a mutable |
3526 // double box. | 3526 // double box. |
3527 if (old_map->unused_property_fields() > 0) { | 3527 if (old_map->unused_property_fields() > 0) { |
3528 FieldIndex index = | 3528 FieldIndex index = |
3529 FieldIndex::ForDescriptor(*new_map, new_map->LastAdded()); | 3529 FieldIndex::ForDescriptor(*new_map, new_map->LastAdded()); |
3530 DCHECK(details.representation().IsDouble()); | 3530 DCHECK(details.representation().IsDouble()); |
3531 DCHECK(!new_map->IsUnboxedDoubleField(index)); | 3531 DCHECK(!new_map->IsUnboxedDoubleField(index)); |
3532 Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 3532 Handle<Object> value = isolate->factory()->NewMutableHeapNumber(); |
3533 object->RawFastPropertyAtPut(index, *value); | 3533 object->RawFastPropertyAtPut(index, *value); |
3534 object->synchronized_set_map(*new_map); | 3534 object->synchronized_set_map(*new_map); |
3535 return; | 3535 return; |
3536 } | 3536 } |
3537 | 3537 |
3538 // This migration is a transition from a map that has run out of property | 3538 // This migration is a transition from a map that has run out of property |
3539 // space. Extend the backing store. | 3539 // space. Extend the backing store. |
3540 int grow_by = new_map->unused_property_fields() + 1; | 3540 int grow_by = new_map->unused_property_fields() + 1; |
3541 Handle<FixedArray> old_storage = handle(object->properties(), isolate); | 3541 Handle<FixedArray> old_storage = handle(object->properties(), isolate); |
3542 Handle<FixedArray> new_storage = | 3542 Handle<FixedArray> new_storage = |
3543 isolate->factory()->CopyFixedArrayAndGrow(old_storage, grow_by); | 3543 isolate->factory()->CopyFixedArrayAndGrow(old_storage, grow_by); |
3544 | 3544 |
3545 // Properly initialize newly added property. | 3545 // Properly initialize newly added property. |
3546 Handle<Object> value; | 3546 Handle<Object> value; |
3547 if (details.representation().IsDouble()) { | 3547 if (details.representation().IsDouble()) { |
3548 value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 3548 value = isolate->factory()->NewMutableHeapNumber(); |
3549 } else { | 3549 } else { |
3550 value = isolate->factory()->uninitialized_value(); | 3550 value = isolate->factory()->uninitialized_value(); |
3551 } | 3551 } |
3552 DCHECK_EQ(kField, details.location()); | 3552 DCHECK_EQ(kField, details.location()); |
3553 DCHECK_EQ(kData, details.kind()); | 3553 DCHECK_EQ(kData, details.kind()); |
3554 int target_index = details.field_index() - new_map->GetInObjectProperties(); | 3554 int target_index = details.field_index() - new_map->GetInObjectProperties(); |
3555 DCHECK(target_index >= 0); // Must be a backing store index. | 3555 DCHECK(target_index >= 0); // Must be a backing store index. |
3556 new_storage->set(target_index, *value); | 3556 new_storage->set(target_index, *value); |
3557 | 3557 |
3558 // From here on we cannot fail and we shouldn't GC anymore. | 3558 // From here on we cannot fail and we shouldn't GC anymore. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3598 PropertyDetails old_details = old_descriptors->GetDetails(i); | 3598 PropertyDetails old_details = old_descriptors->GetDetails(i); |
3599 Representation old_representation = old_details.representation(); | 3599 Representation old_representation = old_details.representation(); |
3600 Representation representation = details.representation(); | 3600 Representation representation = details.representation(); |
3601 Handle<Object> value; | 3601 Handle<Object> value; |
3602 if (old_details.location() == kDescriptor) { | 3602 if (old_details.location() == kDescriptor) { |
3603 if (old_details.kind() == kAccessor) { | 3603 if (old_details.kind() == kAccessor) { |
3604 // In case of kAccessor -> kData property reconfiguration, the property | 3604 // In case of kAccessor -> kData property reconfiguration, the property |
3605 // must already be prepared for data of certain type. | 3605 // must already be prepared for data of certain type. |
3606 DCHECK(!details.representation().IsNone()); | 3606 DCHECK(!details.representation().IsNone()); |
3607 if (details.representation().IsDouble()) { | 3607 if (details.representation().IsDouble()) { |
3608 value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 3608 value = isolate->factory()->NewMutableHeapNumber(); |
3609 } else { | 3609 } else { |
3610 value = isolate->factory()->uninitialized_value(); | 3610 value = isolate->factory()->uninitialized_value(); |
3611 } | 3611 } |
3612 } else { | 3612 } else { |
3613 DCHECK_EQ(kData, old_details.kind()); | 3613 DCHECK_EQ(kData, old_details.kind()); |
3614 value = handle(old_descriptors->GetValue(i), isolate); | 3614 value = handle(old_descriptors->GetValue(i), isolate); |
3615 DCHECK(!old_representation.IsDouble() && !representation.IsDouble()); | 3615 DCHECK(!old_representation.IsDouble() && !representation.IsDouble()); |
3616 } | 3616 } |
3617 } else { | 3617 } else { |
3618 DCHECK_EQ(kField, old_details.location()); | 3618 DCHECK_EQ(kField, old_details.location()); |
3619 FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); | 3619 FieldIndex index = FieldIndex::ForDescriptor(*old_map, i); |
3620 if (object->IsUnboxedDoubleField(index)) { | 3620 if (object->IsUnboxedDoubleField(index)) { |
3621 double old = object->RawFastDoublePropertyAt(index); | 3621 double old = object->RawFastDoublePropertyAt(index); |
3622 value = isolate->factory()->NewHeapNumber( | 3622 value = isolate->factory()->NewHeapNumber( |
3623 old, representation.IsDouble() ? MUTABLE : IMMUTABLE); | 3623 old, representation.IsDouble() ? MUTABLE : IMMUTABLE); |
3624 | 3624 |
3625 } else { | 3625 } else { |
3626 value = handle(object->RawFastPropertyAt(index), isolate); | 3626 value = handle(object->RawFastPropertyAt(index), isolate); |
3627 if (!old_representation.IsDouble() && representation.IsDouble()) { | 3627 if (!old_representation.IsDouble() && representation.IsDouble()) { |
3628 if (old_representation.IsNone()) { | 3628 DCHECK_IMPLIES(old_representation.IsNone(), |
3629 value = handle(Smi::kZero, isolate); | 3629 value->IsUninitialized(isolate)); |
3630 } | |
3631 value = Object::NewStorageFor(isolate, value, representation); | 3630 value = Object::NewStorageFor(isolate, value, representation); |
3632 } else if (old_representation.IsDouble() && | 3631 } else if (old_representation.IsDouble() && |
3633 !representation.IsDouble()) { | 3632 !representation.IsDouble()) { |
3634 value = Object::WrapForRead(isolate, value, old_representation); | 3633 value = Object::WrapForRead(isolate, value, old_representation); |
3635 } | 3634 } |
3636 } | 3635 } |
3637 } | 3636 } |
3638 DCHECK(!(representation.IsDouble() && value->IsSmi())); | 3637 DCHECK(!(representation.IsDouble() && value->IsSmi())); |
3639 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 3638 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
3640 if (target_index < 0) target_index += total_size; | 3639 if (target_index < 0) target_index += total_size; |
3641 array->set(target_index, *value); | 3640 array->set(target_index, *value); |
3642 } | 3641 } |
3643 | 3642 |
3644 for (int i = old_nof; i < new_nof; i++) { | 3643 for (int i = old_nof; i < new_nof; i++) { |
3645 PropertyDetails details = new_descriptors->GetDetails(i); | 3644 PropertyDetails details = new_descriptors->GetDetails(i); |
3646 if (details.location() != kField) continue; | 3645 if (details.location() != kField) continue; |
3647 DCHECK_EQ(kData, details.kind()); | 3646 DCHECK_EQ(kData, details.kind()); |
3648 Handle<Object> value; | 3647 Handle<Object> value; |
3649 if (details.representation().IsDouble()) { | 3648 if (details.representation().IsDouble()) { |
3650 value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 3649 value = isolate->factory()->NewMutableHeapNumber(); |
3651 } else { | 3650 } else { |
3652 value = isolate->factory()->uninitialized_value(); | 3651 value = isolate->factory()->uninitialized_value(); |
3653 } | 3652 } |
3654 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 3653 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
3655 if (target_index < 0) target_index += total_size; | 3654 if (target_index < 0) target_index += total_size; |
3656 array->set(target_index, *value); | 3655 array->set(target_index, *value); |
3657 } | 3656 } |
3658 | 3657 |
3659 // From here on we cannot fail and we shouldn't GC anymore. | 3658 // From here on we cannot fail and we shouldn't GC anymore. |
3660 DisallowHeapAllocation no_allocation; | 3659 DisallowHeapAllocation no_allocation; |
(...skipping 16240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19901 // depend on this. | 19900 // depend on this. |
19902 return DICTIONARY_ELEMENTS; | 19901 return DICTIONARY_ELEMENTS; |
19903 } | 19902 } |
19904 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 19903 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
19905 return kind; | 19904 return kind; |
19906 } | 19905 } |
19907 } | 19906 } |
19908 | 19907 |
19909 } // namespace internal | 19908 } // namespace internal |
19910 } // namespace v8 | 19909 } // namespace v8 |
OLD | NEW |