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 3257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3268 case kDouble: return "d"; | 3268 case kDouble: return "d"; |
3269 case kInteger32: return "i"; | 3269 case kInteger32: return "i"; |
3270 case kHeapObject: return "h"; | 3270 case kHeapObject: return "h"; |
3271 case kExternal: return "x"; | 3271 case kExternal: return "x"; |
3272 default: | 3272 default: |
3273 UNREACHABLE(); | 3273 UNREACHABLE(); |
3274 return NULL; | 3274 return NULL; |
3275 } | 3275 } |
3276 } | 3276 } |
3277 | 3277 |
3278 bool Map::TransitionRemovesTaggedField(Map* target) { | |
3279 int inobject = GetInObjectProperties(); | |
3280 int target_inobject = target->GetInObjectProperties(); | |
3281 for (int i = target_inobject; i < inobject; i++) { | |
3282 FieldIndex index = FieldIndex::ForPropertyIndex(this, i); | |
3283 if (!IsUnboxedDoubleField(index)) return true; | |
3284 } | |
3285 return false; | |
3286 } | |
3287 | |
3288 bool Map::TransitionChangesTaggedFieldToUntaggedField(Map* target) { | |
3289 int inobject = GetInObjectProperties(); | |
3290 int target_inobject = target->GetInObjectProperties(); | |
3291 int limit = Min(inobject, target_inobject); | |
3292 for (int i = 0; i < limit; i++) { | |
3293 FieldIndex index = FieldIndex::ForPropertyIndex(target, i); | |
Igor Sheludko
2017/02/21 10:22:25
This will work only if target is a non-dictionary
Igor Sheludko
2017/02/21 10:36:37
Please ignore my comments.
| |
3294 if (!IsUnboxedDoubleField(index) && target->IsUnboxedDoubleField(index)) { | |
3295 return true; | |
3296 } | |
3297 } | |
3298 return false; | |
3299 } | |
3300 | |
3301 bool Map::TransitionRequiresSynchronizationWithGC(Map* target) { | |
3302 return TransitionRemovesTaggedField(target) || | |
Igor Sheludko
2017/02/21 10:22:25
... if a slow map does not contain inobject space
| |
3303 TransitionChangesTaggedFieldToUntaggedField(target); | |
3304 } | |
3305 | |
3278 bool Map::InstancesNeedRewriting(Map* target) { | 3306 bool Map::InstancesNeedRewriting(Map* target) { |
3279 int target_number_of_fields = target->NumberOfFields(); | 3307 int target_number_of_fields = target->NumberOfFields(); |
3280 int target_inobject = target->GetInObjectProperties(); | 3308 int target_inobject = target->GetInObjectProperties(); |
3281 int target_unused = target->unused_property_fields(); | 3309 int target_unused = target->unused_property_fields(); |
3282 int old_number_of_fields; | 3310 int old_number_of_fields; |
3283 | 3311 |
3284 return InstancesNeedRewriting(target, target_number_of_fields, | 3312 return InstancesNeedRewriting(target, target_number_of_fields, |
3285 target_inobject, target_unused, | 3313 target_inobject, target_unused, |
3286 &old_number_of_fields); | 3314 &old_number_of_fields); |
3287 } | 3315 } |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3518 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 3546 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
3519 if (target_index < 0) target_index += total_size; | 3547 if (target_index < 0) target_index += total_size; |
3520 array->set(target_index, *value); | 3548 array->set(target_index, *value); |
3521 } | 3549 } |
3522 | 3550 |
3523 // From here on we cannot fail and we shouldn't GC anymore. | 3551 // From here on we cannot fail and we shouldn't GC anymore. |
3524 DisallowHeapAllocation no_allocation; | 3552 DisallowHeapAllocation no_allocation; |
3525 | 3553 |
3526 Heap* heap = isolate->heap(); | 3554 Heap* heap = isolate->heap(); |
3527 | 3555 |
3556 heap->NotifyObjectLayoutChange(*object, no_allocation); | |
3557 | |
3528 // Copy (real) inobject properties. If necessary, stop at number_of_fields to | 3558 // Copy (real) inobject properties. If necessary, stop at number_of_fields to |
3529 // avoid overwriting |one_pointer_filler_map|. | 3559 // avoid overwriting |one_pointer_filler_map|. |
3530 int limit = Min(inobject, number_of_fields); | 3560 int limit = Min(inobject, number_of_fields); |
3531 for (int i = 0; i < limit; i++) { | 3561 for (int i = 0; i < limit; i++) { |
3532 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); | 3562 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); |
3533 Object* value = array->get(external + i); | 3563 Object* value = array->get(external + i); |
3534 // Can't use JSObject::FastPropertyAtPut() because proper map was not set | 3564 // Can't use JSObject::FastPropertyAtPut() because proper map was not set |
3535 // yet. | 3565 // yet. |
3536 if (new_map->IsUnboxedDoubleField(index)) { | 3566 if (new_map->IsUnboxedDoubleField(index)) { |
3537 DCHECK(value->IsMutableHeapNumber()); | 3567 DCHECK(value->IsMutableHeapNumber()); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3632 PropertyCellType::kNoCell); | 3662 PropertyCellType::kNoCell); |
3633 dictionary = NameDictionary::Add(dictionary, key, value, d); | 3663 dictionary = NameDictionary::Add(dictionary, key, value, d); |
3634 } | 3664 } |
3635 | 3665 |
3636 // Copy the next enumeration index from instance descriptor. | 3666 // Copy the next enumeration index from instance descriptor. |
3637 dictionary->SetNextEnumerationIndex(real_size + 1); | 3667 dictionary->SetNextEnumerationIndex(real_size + 1); |
3638 | 3668 |
3639 // From here on we cannot fail and we shouldn't GC anymore. | 3669 // From here on we cannot fail and we shouldn't GC anymore. |
3640 DisallowHeapAllocation no_allocation; | 3670 DisallowHeapAllocation no_allocation; |
3641 | 3671 |
3672 Heap* heap = isolate->heap(); | |
3673 heap->NotifyObjectLayoutChange(*object, no_allocation); | |
3674 | |
3642 // Resize the object in the heap if necessary. | 3675 // Resize the object in the heap if necessary. |
3643 int new_instance_size = new_map->instance_size(); | 3676 int new_instance_size = new_map->instance_size(); |
3644 int instance_size_delta = map->instance_size() - new_instance_size; | 3677 int instance_size_delta = map->instance_size() - new_instance_size; |
3645 DCHECK(instance_size_delta >= 0); | 3678 DCHECK(instance_size_delta >= 0); |
3646 | 3679 |
3647 if (instance_size_delta > 0) { | 3680 if (instance_size_delta > 0) { |
3648 Heap* heap = isolate->heap(); | |
3649 heap->CreateFillerObjectAt(object->address() + new_instance_size, | 3681 heap->CreateFillerObjectAt(object->address() + new_instance_size, |
3650 instance_size_delta, ClearRecordedSlots::kYes); | 3682 instance_size_delta, ClearRecordedSlots::kYes); |
3651 heap->AdjustLiveBytes(*object, -instance_size_delta); | 3683 heap->AdjustLiveBytes(*object, -instance_size_delta); |
3652 } | 3684 } |
3653 | 3685 |
3654 // We are storing the new map using release store after creating a filler for | 3686 // We are storing the new map using release store after creating a filler for |
3655 // the left-over space to avoid races with the sweeper thread. | 3687 // the left-over space to avoid races with the sweeper thread. |
3656 object->synchronized_set_map(*new_map); | 3688 object->synchronized_set_map(*new_map); |
3657 | 3689 |
3658 object->set_properties(*dictionary); | 3690 object->set_properties(*dictionary); |
(...skipping 16423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
20082 // depend on this. | 20114 // depend on this. |
20083 return DICTIONARY_ELEMENTS; | 20115 return DICTIONARY_ELEMENTS; |
20084 } | 20116 } |
20085 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20117 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
20086 return kind; | 20118 return kind; |
20087 } | 20119 } |
20088 } | 20120 } |
20089 | 20121 |
20090 } // namespace internal | 20122 } // namespace internal |
20091 } // namespace v8 | 20123 } // namespace v8 |
OLD | NEW |