Skip to content

Commit c478884

Browse files
targosBridgeAR
authored andcommitted
deps: V8: cherry-pick 94c87fe
Original commit message: [ic] Fix handling of +0/-0 when constant field tracking is enabled ... and ensure that runtime behaviour is in sync with the IC code. Bug: chromium:950747, v8:9113 Change-Id: Ied66c9514cbe3a4d75fc71d4fc3b19ea1538f9b2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1561319 Reviewed-by: Toon Verwaest <[email protected]> Commit-Queue: Igor Sheludko <[email protected]> Cr-Commit-Position: refs/heads/master@{#60768} PR-URL: #27792 Fixes: #27784 Refs: v8/v8@94c87fe Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Gus Caplan <[email protected]>
1 parent 7438a55 commit c478884

File tree

10 files changed

+328
-93
lines changed

10 files changed

+328
-93
lines changed

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
# Reset this number to 0 on major V8 upgrades.
4040
# Increment by one for each non-official patch applied to deps/v8.
41-
'v8_embedder_string': '-node.17',
41+
'v8_embedder_string': '-node.18',
4242

4343
##### V8 defaults for Node.js #####
4444

deps/v8/src/code-stub-assembler.cc

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12367,7 +12367,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs,
1236712367
// This algorithm differs from the Strict Equality Comparison Algorithm in its
1236812368
// treatment of signed zeroes and NaNs.
1236912369
void CodeStubAssembler::BranchIfSameValue(Node* lhs, Node* rhs, Label* if_true,
12370-
Label* if_false) {
12370+
Label* if_false, SameValueMode mode) {
1237112371
VARIABLE(var_lhs_value, MachineRepresentation::kFloat64);
1237212372
VARIABLE(var_rhs_value, MachineRepresentation::kFloat64);
1237312373
Label do_fcmp(this);
@@ -12413,10 +12413,12 @@ void CodeStubAssembler::BranchIfSameValue(Node* lhs, Node* rhs, Label* if_true,
1241312413
if_lhsisbigint(this);
1241412414
Node* const lhs_map = LoadMap(lhs);
1241512415
GotoIf(IsHeapNumberMap(lhs_map), &if_lhsisheapnumber);
12416-
Node* const lhs_instance_type = LoadMapInstanceType(lhs_map);
12417-
GotoIf(IsStringInstanceType(lhs_instance_type), &if_lhsisstring);
12418-
Branch(IsBigIntInstanceType(lhs_instance_type), &if_lhsisbigint,
12419-
if_false);
12416+
if (mode != SameValueMode::kNumbersOnly) {
12417+
Node* const lhs_instance_type = LoadMapInstanceType(lhs_map);
12418+
GotoIf(IsStringInstanceType(lhs_instance_type), &if_lhsisstring);
12419+
GotoIf(IsBigIntInstanceType(lhs_instance_type), &if_lhsisbigint);
12420+
}
12421+
Goto(if_false);
1242012422

1242112423
BIND(&if_lhsisheapnumber);
1242212424
{
@@ -12426,53 +12428,62 @@ void CodeStubAssembler::BranchIfSameValue(Node* lhs, Node* rhs, Label* if_true,
1242612428
Goto(&do_fcmp);
1242712429
}
1242812430

12429-
BIND(&if_lhsisstring);
12430-
{
12431-
// Now we can only yield true if {rhs} is also a String
12432-
// with the same sequence of characters.
12433-
GotoIfNot(IsString(rhs), if_false);
12434-
Node* const result = CallBuiltin(Builtins::kStringEqual,
12435-
NoContextConstant(), lhs, rhs);
12436-
Branch(IsTrue(result), if_true, if_false);
12437-
}
12438-
12439-
BIND(&if_lhsisbigint);
12440-
{
12441-
GotoIfNot(IsBigInt(rhs), if_false);
12442-
Node* const result = CallRuntime(Runtime::kBigIntEqualToBigInt,
12443-
NoContextConstant(), lhs, rhs);
12444-
Branch(IsTrue(result), if_true, if_false);
12431+
if (mode != SameValueMode::kNumbersOnly) {
12432+
BIND(&if_lhsisstring);
12433+
{
12434+
// Now we can only yield true if {rhs} is also a String
12435+
// with the same sequence of characters.
12436+
GotoIfNot(IsString(rhs), if_false);
12437+
Node* const result = CallBuiltin(
12438+
Builtins::kStringEqual, NoContextConstant(), lhs, rhs);
12439+
Branch(IsTrue(result), if_true, if_false);
12440+
}
12441+
12442+
BIND(&if_lhsisbigint);
12443+
{
12444+
GotoIfNot(IsBigInt(rhs), if_false);
12445+
Node* const result =
12446+
CallRuntime(Runtime::kBigIntEqualToBigInt,
12447+
NoContextConstant(), lhs, rhs);
12448+
Branch(IsTrue(result), if_true, if_false);
12449+
}
1244512450
}
1244612451
});
1244712452
}
1244812453

1244912454
BIND(&do_fcmp);
1245012455
{
12451-
Node* const lhs_value = var_lhs_value.value();
12452-
Node* const rhs_value = var_rhs_value.value();
12456+
TNode<Float64T> lhs_value = UncheckedCast<Float64T>(var_lhs_value.value());
12457+
TNode<Float64T> rhs_value = UncheckedCast<Float64T>(var_rhs_value.value());
12458+
BranchIfSameNumberValue(lhs_value, rhs_value, if_true, if_false);
12459+
}
12460+
}
1245312461

12454-
Label if_equal(this), if_notequal(this);
12455-
Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal);
12462+
void CodeStubAssembler::BranchIfSameNumberValue(TNode<Float64T> lhs_value,
12463+
TNode<Float64T> rhs_value,
12464+
Label* if_true,
12465+
Label* if_false) {
12466+
Label if_equal(this), if_notequal(this);
12467+
Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal);
1245612468

12457-
BIND(&if_equal);
12458-
{
12459-
// We still need to handle the case when {lhs} and {rhs} are -0.0 and
12460-
// 0.0 (or vice versa). Compare the high word to
12461-
// distinguish between the two.
12462-
Node* const lhs_hi_word = Float64ExtractHighWord32(lhs_value);
12463-
Node* const rhs_hi_word = Float64ExtractHighWord32(rhs_value);
12464-
12465-
// If x is +0 and y is -0, return false.
12466-
// If x is -0 and y is +0, return false.
12467-
Branch(Word32Equal(lhs_hi_word, rhs_hi_word), if_true, if_false);
12468-
}
12469+
BIND(&if_equal);
12470+
{
12471+
// We still need to handle the case when {lhs} and {rhs} are -0.0 and
12472+
// 0.0 (or vice versa). Compare the high word to
12473+
// distinguish between the two.
12474+
Node* const lhs_hi_word = Float64ExtractHighWord32(lhs_value);
12475+
Node* const rhs_hi_word = Float64ExtractHighWord32(rhs_value);
1246912476

12470-
BIND(&if_notequal);
12471-
{
12472-
// Return true iff both {rhs} and {lhs} are NaN.
12473-
GotoIf(Float64Equal(lhs_value, lhs_value), if_false);
12474-
Branch(Float64Equal(rhs_value, rhs_value), if_false, if_true);
12475-
}
12477+
// If x is +0 and y is -0, return false.
12478+
// If x is -0 and y is +0, return false.
12479+
Branch(Word32Equal(lhs_hi_word, rhs_hi_word), if_true, if_false);
12480+
}
12481+
12482+
BIND(&if_notequal);
12483+
{
12484+
// Return true iff both {rhs} and {lhs} are NaN.
12485+
GotoIf(Float64Equal(lhs_value, lhs_value), if_false);
12486+
Branch(Float64Equal(rhs_value, rhs_value), if_false, if_true);
1247612487
}
1247712488
}
1247812489

deps/v8/src/code-stub-assembler.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3095,7 +3095,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
30953095
// ECMA#sec-samevalue
30963096
// Similar to StrictEqual except that NaNs are treated as equal and minus zero
30973097
// differs from positive zero.
3098-
void BranchIfSameValue(Node* lhs, Node* rhs, Label* if_true, Label* if_false);
3098+
enum class SameValueMode { kNumbersOnly, kFull };
3099+
void BranchIfSameValue(Node* lhs, Node* rhs, Label* if_true, Label* if_false,
3100+
SameValueMode mode = SameValueMode::kFull);
3101+
// A part of BranchIfSameValue() that handles two double values.
3102+
// Treats NaN == NaN and +0 != -0.
3103+
void BranchIfSameNumberValue(TNode<Float64T> lhs_value,
3104+
TNode<Float64T> rhs_value, Label* if_true,
3105+
Label* if_false);
30993106

31003107
enum HasPropertyLookupMode { kHasProperty, kForInHasProperty };
31013108

deps/v8/src/ic/accessor-assembler.cc

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,23 +1202,23 @@ void AccessorAssembler::OverwriteExistingFastDataProperty(
12021202

12031203
BIND(&inobject);
12041204
{
1205-
Node* field_offset = TimesTaggedSize(field_index);
1205+
TNode<IntPtrT> field_offset = Signed(TimesTaggedSize(field_index));
12061206
Label tagged_rep(this), double_rep(this);
12071207
Branch(
12081208
Word32Equal(representation, Int32Constant(Representation::kDouble)),
12091209
&double_rep, &tagged_rep);
12101210
BIND(&double_rep);
12111211
{
1212-
Node* double_value = ChangeNumberToFloat64(value);
1212+
TNode<Float64T> double_value = ChangeNumberToFloat64(value);
12131213
if (FLAG_unbox_double_fields) {
12141214
if (do_transitioning_store) {
12151215
StoreMap(object, object_map);
12161216
} else if (FLAG_track_constant_fields) {
12171217
Label if_mutable(this);
12181218
GotoIfNot(IsPropertyDetailsConst(details), &if_mutable);
1219-
Node* current_value =
1220-
LoadObjectField(object, field_offset, MachineType::Float64());
1221-
Branch(Float64Equal(current_value, double_value), &done, slow);
1219+
TNode<Float64T> current_value =
1220+
LoadObjectField<Float64T>(CAST(object), field_offset);
1221+
BranchIfSameNumberValue(current_value, double_value, &done, slow);
12221222
BIND(&if_mutable);
12231223
}
12241224
StoreObjectFieldNoWriteBarrier(object, field_offset, double_value,
@@ -1234,8 +1234,9 @@ void AccessorAssembler::OverwriteExistingFastDataProperty(
12341234
if (FLAG_track_constant_fields) {
12351235
Label if_mutable(this);
12361236
GotoIfNot(IsPropertyDetailsConst(details), &if_mutable);
1237-
Node* current_value = LoadHeapNumberValue(mutable_heap_number);
1238-
Branch(Float64Equal(current_value, double_value), &done, slow);
1237+
TNode<Float64T> current_value =
1238+
LoadHeapNumberValue(mutable_heap_number);
1239+
BranchIfSameNumberValue(current_value, double_value, &done, slow);
12391240
BIND(&if_mutable);
12401241
}
12411242
StoreHeapNumberValue(mutable_heap_number, double_value);
@@ -1251,9 +1252,10 @@ void AccessorAssembler::OverwriteExistingFastDataProperty(
12511252
} else if (FLAG_track_constant_fields) {
12521253
Label if_mutable(this);
12531254
GotoIfNot(IsPropertyDetailsConst(details), &if_mutable);
1254-
Node* current_value =
1255-
LoadObjectField(object, field_offset, MachineType::AnyTagged());
1256-
Branch(WordEqual(current_value, value), &done, slow);
1255+
TNode<Object> current_value =
1256+
LoadObjectField(CAST(object), field_offset);
1257+
BranchIfSameValue(current_value, value, &done, slow,
1258+
SameValueMode::kNumbersOnly);
12571259
BIND(&if_mutable);
12581260
}
12591261
StoreObjectField(object, field_offset, value);
@@ -1303,12 +1305,13 @@ void AccessorAssembler::OverwriteExistingFastDataProperty(
13031305
{
13041306
Node* mutable_heap_number =
13051307
LoadPropertyArrayElement(properties, backing_store_index);
1306-
Node* double_value = ChangeNumberToFloat64(value);
1308+
TNode<Float64T> double_value = ChangeNumberToFloat64(value);
13071309
if (FLAG_track_constant_fields) {
13081310
Label if_mutable(this);
13091311
GotoIfNot(IsPropertyDetailsConst(details), &if_mutable);
1310-
Node* current_value = LoadHeapNumberValue(mutable_heap_number);
1311-
Branch(Float64Equal(current_value, double_value), &done, slow);
1312+
TNode<Float64T> current_value =
1313+
LoadHeapNumberValue(mutable_heap_number);
1314+
BranchIfSameNumberValue(current_value, double_value, &done, slow);
13121315
BIND(&if_mutable);
13131316
}
13141317
StoreHeapNumberValue(mutable_heap_number, double_value);
@@ -1319,9 +1322,10 @@ void AccessorAssembler::OverwriteExistingFastDataProperty(
13191322
if (FLAG_track_constant_fields) {
13201323
Label if_mutable(this);
13211324
GotoIfNot(IsPropertyDetailsConst(details), &if_mutable);
1322-
Node* current_value =
1325+
TNode<Object> current_value =
13231326
LoadPropertyArrayElement(properties, backing_store_index);
1324-
Branch(WordEqual(current_value, value), &done, slow);
1327+
BranchIfSameValue(current_value, value, &done, slow,
1328+
SameValueMode::kNumbersOnly);
13251329
BIND(&if_mutable);
13261330
}
13271331
StorePropertyArrayElement(properties, backing_store_index, value);
@@ -1813,7 +1817,7 @@ void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object,
18131817
}
18141818

18151819
Node* index = DecodeWord<StoreHandler::FieldIndexBits>(handler_word);
1816-
Node* offset = IntPtrMul(index, IntPtrConstant(kTaggedSize));
1820+
TNode<IntPtrT> offset = Signed(TimesTaggedSize(index));
18171821
if (representation.IsDouble()) {
18181822
if (!FLAG_unbox_double_fields || !is_inobject) {
18191823
// Load the mutable heap number.
@@ -1831,14 +1835,14 @@ void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object,
18311835
&done);
18321836
{
18331837
if (store_value_as_double) {
1834-
Node* current_value =
1835-
LoadObjectField(property_storage, offset, MachineType::Float64());
1836-
GotoIfNot(Float64Equal(current_value, value), bailout);
1838+
TNode<Float64T> current_value =
1839+
LoadObjectField<Float64T>(CAST(property_storage), offset);
1840+
BranchIfSameNumberValue(current_value, UncheckedCast<Float64T>(value),
1841+
&done, bailout);
18371842
} else {
18381843
Node* current_value = LoadObjectField(property_storage, offset);
1839-
GotoIfNot(WordEqual(current_value, value), bailout);
1844+
Branch(WordEqual(current_value, value), &done, bailout);
18401845
}
1841-
Goto(&done);
18421846
}
18431847
BIND(&done);
18441848
}

deps/v8/src/lookup.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -934,10 +934,14 @@ bool LookupIterator::IsConstFieldValueEqualTo(Object value) const {
934934
// Uninitialized double field.
935935
return true;
936936
}
937-
return bit_cast<double>(bits) == value->Number();
937+
return Object::SameNumberValue(bit_cast<double>(bits), value->Number());
938938
} else {
939939
Object current_value = holder->RawFastPropertyAt(field_index);
940-
return current_value->IsUninitialized(isolate()) || current_value == value;
940+
if (current_value->IsUninitialized(isolate()) || current_value == value) {
941+
return true;
942+
}
943+
return current_value->IsNumber() && value->IsNumber() &&
944+
Object::SameNumberValue(current_value->Number(), value->Number());
941945
}
942946
}
943947

deps/v8/src/objects-inl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,16 @@ double Object::Number() const {
383383
: HeapNumber::unchecked_cast(*this)->value();
384384
}
385385

386+
// static
387+
bool Object::SameNumberValue(double value1, double value2) {
388+
// SameNumberValue(NaN, NaN) is true.
389+
if (value1 != value2) {
390+
return std::isnan(value1) && std::isnan(value2);
391+
}
392+
// SameNumberValue(0.0, -0.0) is false.
393+
return (std::signbit(value1) == std::signbit(value2));
394+
}
395+
386396
bool Object::IsNaN() const {
387397
return this->IsHeapNumber() && std::isnan(HeapNumber::cast(*this)->value());
388398
}

0 commit comments

Comments
 (0)