Chromium Code Reviews| 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 |