| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f62e35f commit 201cf97
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,7 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | 31 | # Reset this number to 0 on major V8 upgrades. | |
| 32 | 32 | # Increment by one for each non-official patch applied to deps/v8. | |
| 33 | - 'v8_embedder_string': '-node.13', | ||
| 33 | + 'v8_embedder_string': '-node.14', | ||
| 34 | 34 | ||
| 35 | 35 | # Enable disassembler for `--print-code` v8 options | |
| 36 | 36 | 'v8_enable_disassembler': 1, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2984,6 +2984,24 @@ TNode<MutableHeapNumber> CodeStubAssembler::AllocateMutableHeapNumber() { | |||
| 2984 | 2984 | return UncheckedCast<MutableHeapNumber>(result); | |
| 2985 | 2985 | } | |
| 2986 | 2986 | ||
| 2987 | + TNode<Object> CodeStubAssembler::CloneIfMutablePrimitive(TNode<Object> object) { | ||
| 2988 | + TVARIABLE(Object, result, object); | ||
| 2989 | + Label done(this); | ||
| 2990 | + | ||
| 2991 | + GotoIf(TaggedIsSmi(object), &done); | ||
| 2992 | + GotoIfNot(IsMutableHeapNumber(UncheckedCast<HeapObject>(object)), &done); | ||
| 2993 | + { | ||
| 2994 | + // Mutable heap number found --- allocate a clone. | ||
| 2995 | + TNode<Float64T> value = | ||
| 2996 | + LoadHeapNumberValue(UncheckedCast<HeapNumber>(object)); | ||
| 2997 | + result = AllocateMutableHeapNumberWithValue(value); | ||
| 2998 | + Goto(&done); | ||
| 2999 | + } | ||
| 3000 | + | ||
| 3001 | + BIND(&done); | ||
| 3002 | + return result.value(); | ||
| 3003 | + } | ||
| 3004 | + | ||
| 2987 | 3005 | TNode<MutableHeapNumber> CodeStubAssembler::AllocateMutableHeapNumberWithValue( | |
| 2988 | 3006 | SloppyTNode<Float64T> value) { | |
| 2989 | 3007 | TNode<MutableHeapNumber> result = AllocateMutableHeapNumber(); | |
@@ -4405,7 +4423,8 @@ void CodeStubAssembler::CopyPropertyArrayValues(Node* from_array, | |||
| 4405 | 4423 | Node* to_array, | |
| 4406 | 4424 | Node* property_count, | |
| 4407 | 4425 | WriteBarrierMode barrier_mode, | |
| 4408 | - ParameterMode mode) { | ||
| 4426 | + ParameterMode mode, | ||
| 4427 | + DestroySource destroy_source) { | ||
| 4409 | 4428 | CSA_SLOW_ASSERT(this, MatchesParameterMode(property_count, mode)); | |
| 4410 | 4429 | CSA_SLOW_ASSERT(this, Word32Or(IsPropertyArray(from_array), | |
| 4411 | 4430 | IsEmptyFixedArray(from_array))); | |
@@ -4417,9 +4436,14 @@ void CodeStubAssembler::CopyPropertyArrayValues(Node* from_array, | |||
| 4417 | 4436 | ElementsKind kind = PACKED_ELEMENTS; | |
| 4418 | 4437 | BuildFastFixedArrayForEach( | |
| 4419 | 4438 | from_array, kind, start, property_count, | |
| 4420 | - [this, to_array, needs_write_barrier](Node* array, Node* offset) { | ||
| 4439 | + [this, to_array, needs_write_barrier, destroy_source](Node* array, | ||
| 4440 | + Node* offset) { | ||
| 4421 | 4441 | Node* value = Load(MachineType::AnyTagged(), array, offset); | |
| 4422 | 4442 | ||
| 4443 | + if (destroy_source == DestroySource::kNo) { | ||
| 4444 | + value = CloneIfMutablePrimitive(CAST(value)); | ||
| 4445 | + } | ||
| 4446 | + | ||
| 4423 | 4447 | if (needs_write_barrier) { | |
| 4424 | 4448 | Store(to_array, offset, value); | |
| 4425 | 4449 | } else { | |
@@ -4428,6 +4452,18 @@ void CodeStubAssembler::CopyPropertyArrayValues(Node* from_array, | |||
| 4428 | 4452 | } | |
| 4429 | 4453 | }, | |
| 4430 | 4454 | mode); | |
| 4455 | + | ||
| 4456 | + #ifdef DEBUG | ||
| 4457 | + // Zap {from_array} if the copying above has made it invalid. | ||
| 4458 | + if (destroy_source == DestroySource::kYes) { | ||
| 4459 | + Label did_zap(this); | ||
| 4460 | + GotoIf(IsEmptyFixedArray(from_array), &did_zap); | ||
| 4461 | + FillPropertyArrayWithUndefined(from_array, start, property_count, mode); | ||
| 4462 | + | ||
| 4463 | + Goto(&did_zap); | ||
| 4464 | + BIND(&did_zap); | ||
| 4465 | + } | ||
| 4466 | + #endif | ||
| 4431 | 4467 | Comment("] CopyPropertyArrayValues"); | |
| 4432 | 4468 | } | |
| 4433 | 4469 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1454,10 +1454,19 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { | |||
| 1454 | 1454 | Node* to_index, | |
| 1455 | 1455 | ParameterMode mode = INTPTR_PARAMETERS); | |
| 1456 | 1456 | ||
| 1457 | - void CopyPropertyArrayValues( | ||
| 1458 | - Node* from_array, Node* to_array, Node* length, | ||
| 1459 | - WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER, | ||
| 1460 | - ParameterMode mode = INTPTR_PARAMETERS); | ||
| 1457 | + enum class DestroySource { kNo, kYes }; | ||
| 1458 | + | ||
| 1459 | + // Specify DestroySource::kYes if {from_array} is being supplanted by | ||
| 1460 | + // {to_array}. This offers a slight performance benefit by simply copying the | ||
| 1461 | + // array word by word. The source may be destroyed at the end of this macro. | ||
| 1462 | + // | ||
| 1463 | + // Otherwise, specify DestroySource::kNo for operations where an Object is | ||
| 1464 | + // being cloned, to ensure that MutableHeapNumbers are unique between the | ||
| 1465 | + // source and cloned object. | ||
| 1466 | + void CopyPropertyArrayValues(Node* from_array, Node* to_array, Node* length, | ||
| 1467 | + WriteBarrierMode barrier_mode, | ||
| 1468 | + ParameterMode mode, | ||
| 1469 | + DestroySource destroy_source); | ||
| 1461 | 1470 | ||
| 1462 | 1471 | // Copies all elements from |from_array| of |length| size to | |
| 1463 | 1472 | // |to_array| of the same size respecting the elements kind. | |
@@ -2864,6 +2873,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { | |||
| 2864 | 2873 | void InitializeFunctionContext(Node* native_context, Node* context, | |
| 2865 | 2874 | int slots); | |
| 2866 | 2875 | ||
| 2876 | + // Allocate a clone of a mutable primitive, if {object} is a | ||
| 2877 | + // MutableHeapNumber. | ||
| 2878 | + TNode<Object> CloneIfMutablePrimitive(TNode<Object> object); | ||
| 2879 | + | ||
| 2867 | 2880 | private: | |
| 2868 | 2881 | friend class CodeStubArguments; | |
| 2869 | 2882 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1667,7 +1667,8 @@ Node* AccessorAssembler::ExtendPropertiesBackingStore(Node* object, | |||
| 1667 | 1667 | // |new_properties| is guaranteed to be in new space, so we can skip | |
| 1668 | 1668 | // the write barrier. | |
| 1669 | 1669 | CopyPropertyArrayValues(var_properties.value(), new_properties, | |
| 1670 | - var_length.value(), SKIP_WRITE_BARRIER, mode); | ||
| 1670 | + var_length.value(), SKIP_WRITE_BARRIER, mode, | ||
| 1671 | + DestroySource::kYes); | ||
| 1671 | 1672 | ||
| 1672 | 1673 | // TODO(gsathya): Clean up the type conversions by creating smarter | |
| 1673 | 1674 | // helpers that do the correct op based on the mode. | |
@@ -3471,7 +3472,7 @@ void AccessorAssembler::GenerateCloneObjectIC() { | |||
| 3471 | 3472 | auto mode = INTPTR_PARAMETERS; | |
| 3472 | 3473 | var_properties = CAST(AllocatePropertyArray(length, mode)); | |
| 3473 | 3474 | CopyPropertyArrayValues(source_properties, var_properties.value(), length, | |
| 3474 | - SKIP_WRITE_BARRIER, mode); | ||
| 3475 | + SKIP_WRITE_BARRIER, mode, DestroySource::kNo); | ||
| 3475 | 3476 | } | |
| 3476 | 3477 | ||
| 3477 | 3478 | Goto(&allocate_object); | |
@@ -3491,7 +3492,8 @@ void AccessorAssembler::GenerateCloneObjectIC() { | |||
| 3491 | 3492 | BuildFastLoop(source_start, source_size, | |
| 3492 | 3493 | [=](Node* field_index) { | |
| 3493 | 3494 | Node* field_offset = TimesPointerSize(field_index); | |
| 3494 | - Node* field = LoadObjectField(source, field_offset); | ||
| 3495 | + TNode<Object> field = LoadObjectField(source, field_offset); | ||
| 3496 | + field = CloneIfMutablePrimitive(field); | ||
| 3495 | 3497 | Node* result_offset = | |
| 3496 | 3498 | IntPtrAdd(field_offset, field_offset_difference); | |
| 3497 | 3499 | StoreObjectFieldNoWriteBarrier(object, result_offset, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -99,3 +99,25 @@ | |||
| 99 | 99 | // Megamorphic | |
| 100 | 100 | assertEquals({ boop: 1 }, f({ boop: 1 })); | |
| 101 | 101 | })(); | |
| 102 | + | ||
| 103 | + // There are 2 paths in CloneObjectIC's handler which need to handle double | ||
| 104 | + // fields specially --- in object properties, and copying the property array. | ||
| 105 | + function testMutableInlineProperties() { | ||
| 106 | + function inobject() { "use strict"; this.x = 1.1; } | ||
| 107 | + const src = new inobject(); | ||
| 108 | + const x0 = src.x; | ||
| 109 | + const clone = { ...src, x: x0 + 1 }; | ||
| 110 | + assertEquals(x0, src.x); | ||
| 111 | + assertEquals({ x: 2.1 }, clone); | ||
| 112 | + } | ||
| 113 | + testMutableInlineProperties() | ||
| 114 | + | ||
| 115 | + function testMutableOutOfLineProperties() { | ||
| 116 | + const src = { a: 1, b: 2, c: 3 }; | ||
| 117 | + src.x = 2.3; | ||
| 118 | + const x0 = src.x; | ||
| 119 | + const clone = { ...src, x: x0 + 1 }; | ||
| 120 | + assertEquals(x0, src.x); | ||
| 121 | + assertEquals({ a: 1, b: 2, c: 3, x: 3.3 }, clone); | ||
| 122 | + } | ||
| 123 | + testMutableOutOfLineProperties(); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments