| 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 |