@@ -3417,7 +3417,7 @@ void AccessorAssembler::GenerateStoreInArrayLiteralIC() {
3417
3417
3418
3418
void AccessorAssembler::GenerateCloneObjectIC () {
3419
3419
typedef CloneObjectWithVectorDescriptor Descriptor;
3420
- Node* source = Parameter (Descriptor::kSource );
3420
+ TNode<HeapObject> source = CAST ( Parameter (Descriptor::kSource ) );
3421
3421
Node* flags = Parameter (Descriptor::kFlags );
3422
3422
Node* slot = Parameter (Descriptor::kSlot );
3423
3423
Node* vector = Parameter (Descriptor::kVector );
@@ -3427,8 +3427,7 @@ void AccessorAssembler::GenerateCloneObjectIC() {
3427
3427
Label miss (this , Label::kDeferred ), try_polymorphic (this , Label::kDeferred ),
3428
3428
try_megamorphic (this , Label::kDeferred );
3429
3429
3430
- CSA_SLOW_ASSERT (this , TaggedIsNotSmi (source));
3431
- Node* source_map = LoadMap (UncheckedCast<HeapObject>(source));
3430
+ TNode<Map> source_map = LoadMap (UncheckedCast<HeapObject>(source));
3432
3431
GotoIf (IsDeprecatedMap (source_map), &miss);
3433
3432
TNode<MaybeObject> feedback = TryMonomorphicCase (
3434
3433
slot, vector, source_map, &if_handler, &var_handler, &try_polymorphic);
@@ -3449,7 +3448,7 @@ void AccessorAssembler::GenerateCloneObjectIC() {
3449
3448
3450
3449
// The IC fast case should only be taken if the result map a compatible
3451
3450
// elements kind with the source object.
3452
- TNode<FixedArrayBase> source_elements = LoadElements (source);
3451
+ TNode<FixedArrayBase> source_elements = LoadElements (CAST ( source) );
3453
3452
3454
3453
auto flags = ExtractFixedArrayFlag::kAllFixedArraysDontCopyCOW ;
3455
3454
var_elements = CAST (CloneFixedArray (source_elements, flags));
@@ -3484,22 +3483,45 @@ void AccessorAssembler::GenerateCloneObjectIC() {
3484
3483
// Lastly, clone any in-object properties.
3485
3484
// Determine the inobject property capacity of both objects, and copy the
3486
3485
// smaller number into the resulting object.
3487
- Node* source_start = LoadMapInobjectPropertiesStartInWords (source_map);
3488
- Node* source_size = LoadMapInstanceSizeInWords (source_map);
3489
- Node* result_start = LoadMapInobjectPropertiesStartInWords (result_map);
3490
- Node* field_offset_difference =
3486
+ TNode<IntPtrT> source_start =
3487
+ LoadMapInobjectPropertiesStartInWords (source_map);
3488
+ TNode<IntPtrT> source_size = LoadMapInstanceSizeInWords (source_map);
3489
+ TNode<IntPtrT> result_start =
3490
+ LoadMapInobjectPropertiesStartInWords (result_map);
3491
+ TNode<IntPtrT> field_offset_difference =
3491
3492
TimesPointerSize (IntPtrSub (result_start, source_start));
3492
- BuildFastLoop (source_start, source_size,
3493
- [=](Node* field_index) {
3494
- Node* field_offset = TimesPointerSize (field_index);
3495
- TNode<Object> field = LoadObjectField (source, field_offset);
3496
- field = CloneIfMutablePrimitive (field);
3497
- Node* result_offset =
3498
- IntPtrAdd (field_offset, field_offset_difference);
3499
- StoreObjectFieldNoWriteBarrier (object, result_offset,
3500
- field);
3501
- },
3502
- 1 , INTPTR_PARAMETERS, IndexAdvanceMode::kPost );
3493
+
3494
+ // If MutableHeapNumbers may be present in-object, allocations may occur
3495
+ // within this loop, thus the write barrier is required.
3496
+ //
3497
+ // TODO(caitp): skip the write barrier until the first MutableHeapNumber
3498
+ // field is found
3499
+ const bool may_use_mutable_heap_numbers = !FLAG_unbox_double_fields;
3500
+
3501
+ BuildFastLoop (
3502
+ source_start, source_size,
3503
+ [=](Node* field_index) {
3504
+ TNode<IntPtrT> field_offset =
3505
+ TimesPointerSize (UncheckedCast<IntPtrT>(field_index));
3506
+
3507
+ if (may_use_mutable_heap_numbers) {
3508
+ TNode<Object> field = LoadObjectField (source, field_offset);
3509
+ field = CloneIfMutablePrimitive (field);
3510
+ TNode<IntPtrT> result_offset =
3511
+ IntPtrAdd (field_offset, field_offset_difference);
3512
+ StoreObjectField (object, result_offset, field);
3513
+ } else {
3514
+ // Copy fields as raw data.
3515
+ TNode<IntPtrT> field = UncheckedCast<IntPtrT>(
3516
+ LoadObjectField (source, field_offset, MachineType::IntPtr ()));
3517
+ TNode<IntPtrT> result_offset =
3518
+ IntPtrAdd (field_offset, field_offset_difference);
3519
+ StoreObjectFieldNoWriteBarrier (
3520
+ object, result_offset, field,
3521
+ MachineType::IntPtr ().representation ());
3522
+ }
3523
+ },
3524
+ 1 , INTPTR_PARAMETERS, IndexAdvanceMode::kPost );
3503
3525
Return (object);
3504
3526
}
3505
3527
0 commit comments