Bug 1636916 part 3 - Optimize branchValueIsNurseryCell using branchTestGCThing. r=jonco
authorJan de Mooij <jdemooij@mozilla.com>
Mon, 11 May 2020 17:24:27 +0000
changeset 529281 dbeae97866271549a144aa5a21a4c6a22523bdb0
parent 529280 b1daef8344369667663fcc349337da8b8642f439
child 529282 af5b7413b76209816f665a17dbd231167bf79912
push id37406
push userdluca@mozilla.com
push dateTue, 12 May 2020 09:34:21 +0000
treeherdermozilla-central@1706d4d54ec6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1636916
milestone78.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1636916 part 3 - Optimize branchValueIsNurseryCell using branchTestGCThing. r=jonco It's more efficient now to check for all GC things with a single branch instead of checking for object/string/BigInt separately. This generates more compact code with fewer branches and is also more maintainable. Depends on D74648 Differential Revision: https://phabricator.services.mozilla.com/D74649
js/src/jit/arm/MacroAssembler-arm.cpp
js/src/jit/arm64/MacroAssembler-arm64.cpp
js/src/jit/mips32/MacroAssembler-mips32.cpp
js/src/jit/mips64/MacroAssembler-mips64.cpp
js/src/jit/x64/MacroAssembler-x64.cpp
js/src/jit/x86/MacroAssembler-x86.cpp
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -4587,45 +4587,38 @@ void MacroAssembler::branchPtrInNurseryC
   load32(Address(temp, gc::ChunkLocationOffset), temp);
   branch32(cond, temp, Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
 }
 
 void MacroAssembler::branchValueIsNurseryCell(Condition cond,
                                               const Address& address,
                                               Register temp, Label* label) {
   MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-  Label done, checkAddress;
-
-  Register tag = temp;
-  tag = extractTag(address, tag);
-  branchTestObject(Assembler::Equal, tag, &checkAddress);
-  branchTestString(Assembler::Equal, tag, &checkAddress);
-  branchTestBigInt(Assembler::NotEqual, tag,
-                   cond == Assembler::Equal ? &done : label);
-
-  bind(&checkAddress);
+
+  Label done;
+
+  branchTestGCThing(Assembler::NotEqual, address,
+                    cond == Assembler::Equal ? &done : label);
+
   loadPtr(ToPayload(address), temp);
   SecondScratchRegisterScope scratch2(*this);
   branchPtrInNurseryChunk(cond, temp, scratch2, label);
 
   bind(&done);
 }
 
 void MacroAssembler::branchValueIsNurseryCell(Condition cond,
                                               ValueOperand value, Register temp,
                                               Label* label) {
   MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-  Label done, checkAddress;
-
-  branchTestObject(Assembler::Equal, value.typeReg(), &checkAddress);
-  branchTestString(Assembler::Equal, value.typeReg(), &checkAddress);
-  branchTestBigInt(Assembler::NotEqual, value.typeReg(),
-                   cond == Assembler::Equal ? &done : label);
-
-  bind(&checkAddress);
+
+  Label done;
+
+  branchTestGCThing(Assembler::NotEqual, value,
+                    cond == Assembler::Equal ? &done : label);
   branchPtrInNurseryChunk(cond, value.payloadReg(), temp, label);
 
   bind(&done);
 }
 
 void MacroAssembler::branchValueIsNurseryObject(Condition cond,
                                                 ValueOperand value,
                                                 Register temp, Label* label) {
--- a/js/src/jit/arm64/MacroAssembler-arm64.cpp
+++ b/js/src/jit/arm64/MacroAssembler-arm64.cpp
@@ -991,33 +991,21 @@ void MacroAssembler::branchValueIsNurser
 template <typename T>
 void MacroAssembler::branchValueIsNurseryCellImpl(Condition cond,
                                                   const T& value, Register temp,
                                                   Label* label) {
   MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
   MOZ_ASSERT(temp != ScratchReg &&
              temp != ScratchReg2);  // Both may be used internally.
 
-  Label done, checkAddress, checkObjectAddress, checkStringAddress;
-  bool testNursery = (cond == Assembler::Equal);
-  branchTestObject(Assembler::Equal, value, &checkObjectAddress);
-  branchTestString(Assembler::Equal, value, &checkStringAddress);
-  branchTestBigInt(Assembler::NotEqual, value, testNursery ? &done : label);
-
-  unboxBigInt(value, temp);
-  jump(&checkAddress);
+  Label done;
+  branchTestGCThing(Assembler::NotEqual, value,
+                    cond == Assembler::Equal ? &done : label);
 
-  bind(&checkStringAddress);
-  unboxString(value, temp);
-  jump(&checkAddress);
-
-  bind(&checkObjectAddress);
-  unboxObject(value, temp);
-
-  bind(&checkAddress);
+  unboxGCThingForGCBarrier(value, temp);
   orPtr(Imm32(gc::ChunkMask), temp);
   branch32(cond, Address(temp, gc::ChunkLocationOffsetFromLastByte),
            Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
 
   bind(&done);
 }
 
 void MacroAssembler::branchValueIsNurseryObject(Condition cond,
--- a/js/src/jit/mips32/MacroAssembler-mips32.cpp
+++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp
@@ -2193,42 +2193,37 @@ void MacroAssembler::moveValue(const Val
 
 // ===============================================================
 // Branch functions
 
 void MacroAssembler::branchValueIsNurseryCell(Condition cond,
                                               const Address& address,
                                               Register temp, Label* label) {
   MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-  Label done, checkAddress;
-
-  branchTestObject(Assembler::Equal, address, &checkAddress);
-  branchTestString(Assembler::Equal, address, &checkAddress);
-  branchTestBigInt(Assembler::NotEqual, address,
-                   cond == Assembler::Equal ? &done : label);
-
-  bind(&checkAddress);
+
+  Label done;
+
+  branchTestGCThing(Assembler::NotEqual, address,
+                    cond == Assembler::Equal ? &done : label);
+
   loadPtr(address, temp);
   branchPtrInNurseryChunk(cond, temp, InvalidReg, label);
 
   bind(&done);
 }
 
 void MacroAssembler::branchValueIsNurseryCell(Condition cond,
                                               ValueOperand value, Register temp,
                                               Label* label) {
   MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
 
-  Label done, checkAddress;
-  branchTestObject(Assembler::Equal, value, &checkAddress);
-  branchTestString(Assembler::Equal, value, &checkAddress);
-  branchTestBigInt(Assembler::NotEqual, value,
-                   cond == Assembler::Equal ? &done : label);
-
-  bind(&checkAddress);
+  Label done;
+
+  branchTestGCThing(Assembler::NotEqual, value,
+                    cond == Assembler::Equal ? &done : label);
   branchPtrInNurseryChunk(cond, value.payloadReg(), temp, label);
 
   bind(&done);
 }
 
 void MacroAssembler::branchValueIsNurseryObject(Condition cond,
                                                 ValueOperand value,
                                                 Register temp, Label* label) {
--- a/js/src/jit/mips64/MacroAssembler-mips64.cpp
+++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp
@@ -2027,36 +2027,21 @@ void MacroAssembler::branchValueIsNurser
   branchValueIsNurseryCell(cond, ValueOperand(temp), InvalidReg, label);
 }
 
 void MacroAssembler::branchValueIsNurseryCell(Condition cond,
                                               ValueOperand value, Register temp,
                                               Label* label) {
   MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
 
-  Label done, checkAddress, checkObjectAddress, checkStringAddress;
-  SecondScratchRegisterScope scratch2(*this);
-
-  splitTag(value, scratch2);
-  branchTestObject(Assembler::Equal, scratch2, &checkObjectAddress);
-  branchTestString(Assembler::Equal, scratch2, &checkStringAddress);
-  branchTestBigInt(Assembler::NotEqual, scratch2,
-                   cond == Assembler::Equal ? &done : label);
+  Label done;
+  branchTestGCThing(Assembler::NotEqual, value,
+                    cond == Assembler::Equal ? &done : label);
 
-  unboxBigInt(value, scratch2);
-  jump(&checkAddress);
-
-  bind(&checkStringAddress);
-  unboxString(value, scratch2);
-  jump(&checkAddress);
-
-  bind(&checkObjectAddress);
-  unboxObject(value, scratch2);
-
-  bind(&checkAddress);
+  unboxGCThingForGCBarrier(value, temp);
   orPtr(Imm32(gc::ChunkMask), scratch2);
   load32(Address(scratch2, gc::ChunkLocationOffsetFromLastByte), scratch2);
   branch32(cond, scratch2, Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
 
   bind(&done);
 }
 
 void MacroAssembler::branchTestValue(Condition cond, const ValueOperand& lhs,
--- a/js/src/jit/x64/MacroAssembler-x64.cpp
+++ b/js/src/jit/x64/MacroAssembler-x64.cpp
@@ -488,36 +488,22 @@ void MacroAssembler::branchValueIsNurser
 }
 
 template <typename T>
 void MacroAssembler::branchValueIsNurseryCellImpl(Condition cond,
                                                   const T& value, Register temp,
                                                   Label* label) {
   MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
   MOZ_ASSERT(temp != InvalidReg);
-  Label done, checkAddress, checkObjectAddress, checkStringAddress;
-
-  Register tag = temp;
-  splitTag(value, tag);
-  branchTestObject(Assembler::Equal, tag, &checkObjectAddress);
-  branchTestString(Assembler::Equal, tag, &checkStringAddress);
-  branchTestBigInt(Assembler::NotEqual, tag,
-                   cond == Assembler::Equal ? &done : label);
 
-  unboxBigInt(value, temp);
-  jump(&checkAddress);
+  Label done;
+  branchTestGCThing(Assembler::NotEqual, value,
+                    cond == Assembler::Equal ? &done : label);
 
-  bind(&checkStringAddress);
-  unboxString(value, temp);
-  jump(&checkAddress);
-
-  bind(&checkObjectAddress);
-  unboxObject(value, temp);
-
-  bind(&checkAddress);
+  unboxGCThingForGCBarrier(value, temp);
   orPtr(Imm32(gc::ChunkMask), temp);
   branch32(cond, Address(temp, gc::ChunkLocationOffsetFromLastByte),
            Imm32(int32_t(gc::ChunkLocation::Nursery)), label);
 
   bind(&done);
 }
 
 void MacroAssembler::branchValueIsNurseryCell(Condition cond,
--- a/js/src/jit/x86/MacroAssembler-x86.cpp
+++ b/js/src/jit/x86/MacroAssembler-x86.cpp
@@ -504,43 +504,35 @@ void MacroAssembler::branchValueIsNurser
 
   bind(&done);
 }
 
 void MacroAssembler::branchValueIsNurseryCell(Condition cond,
                                               const Address& address,
                                               Register temp, Label* label) {
   MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-  Label done, checkAddress;
+
+  Label done;
 
-  Register tag = extractTag(address, temp);
-  MOZ_ASSERT(tag == temp);
-  branchTestObject(Assembler::Equal, tag, &checkAddress);
-  branchTestString(Assembler::Equal, tag, &checkAddress);
-  branchTestBigInt(Assembler::NotEqual, tag,
-                   cond == Assembler::Equal ? &done : label);
-
-  bind(&checkAddress);
+  branchTestGCThing(Assembler::NotEqual, address,
+                    cond == Assembler::Equal ? &done : label);
   branchPtrInNurseryChunk(cond, ToPayload(address), temp, label);
 
   bind(&done);
 }
 
 void MacroAssembler::branchValueIsNurseryCell(Condition cond,
                                               ValueOperand value, Register temp,
                                               Label* label) {
   MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
-  Label done, checkAddress;
+
+  Label done;
 
-  branchTestObject(Assembler::Equal, value, &checkAddress);
-  branchTestString(Assembler::Equal, value, &checkAddress);
-  branchTestBigInt(Assembler::NotEqual, value,
-                   cond == Assembler::Equal ? &done : label);
-
-  bind(&checkAddress);
+  branchTestGCThing(Assembler::NotEqual, value,
+                    cond == Assembler::Equal ? &done : label);
   branchPtrInNurseryChunk(cond, value.payloadReg(), temp, label);
 
   bind(&done);
 }
 
 void MacroAssembler::branchTestValue(Condition cond, const ValueOperand& lhs,
                                      const Value& rhs, Label* label) {
   MOZ_ASSERT(cond == Equal || cond == NotEqual);