@@ -3417,7 +3417,7 @@ void AccessorAssembler::GenerateStoreInArrayLiteralIC() {
34173417
34183418void AccessorAssembler::GenerateCloneObjectIC () {
34193419 typedef CloneObjectWithVectorDescriptor Descriptor;
3420- Node* source = Parameter (Descriptor::kSource );
3420+ TNode<HeapObject> source = CAST ( Parameter (Descriptor::kSource ) );
34213421 Node* flags = Parameter (Descriptor::kFlags );
34223422 Node* slot = Parameter (Descriptor::kSlot );
34233423 Node* vector = Parameter (Descriptor::kVector );
@@ -3427,8 +3427,7 @@ void AccessorAssembler::GenerateCloneObjectIC() {
34273427 Label miss (this , Label::kDeferred ), try_polymorphic (this , Label::kDeferred ),
34283428 try_megamorphic (this , Label::kDeferred );
34293429
3430- CSA_SLOW_ASSERT (this , TaggedIsNotSmi (source));
3431- Node* source_map = LoadMap (UncheckedCast<HeapObject>(source));
3430+ TNode<Map> source_map = LoadMap (UncheckedCast<HeapObject>(source));
34323431 GotoIf (IsDeprecatedMap (source_map), &miss);
34333432 TNode<MaybeObject> feedback = TryMonomorphicCase (
34343433 slot, vector, source_map, &if_handler, &var_handler, &try_polymorphic);
@@ -3449,7 +3448,7 @@ void AccessorAssembler::GenerateCloneObjectIC() {
34493448
34503449 // The IC fast case should only be taken if the result map a compatible
34513450 // elements kind with the source object.
3452- TNode<FixedArrayBase> source_elements = LoadElements (source);
3451+ TNode<FixedArrayBase> source_elements = LoadElements (CAST ( source) );
34533452
34543453 auto flags = ExtractFixedArrayFlag::kAllFixedArraysDontCopyCOW ;
34553454 var_elements = CAST (CloneFixedArray (source_elements, flags));
@@ -3484,22 +3483,45 @@ void AccessorAssembler::GenerateCloneObjectIC() {
34843483 // Lastly, clone any in-object properties.
34853484 // Determine the inobject property capacity of both objects, and copy the
34863485 // 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 =
34913492 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 );
35033525 Return (object);
35043526 }
35053527
0 commit comments