Bug 1393011 - Part 1: Rename skipPool() to maybeSkipAutomaticInstructions(). r=bbouvier
authorSean Stangl <sstangl@mozilla.com>
Wed, 13 Dec 2017 15:55:11 -0600
changeset 396317 d467fdda8dae4be1842f57767c94cdeb28beae7a
parent 396316 b949944f17b0cae7d3d24c2cf9f8a177fe571956
child 396318 5c155dd29e4c069cb8959021bdaf24c1d1c4805a
push id56975
push userdluca@mozilla.com
push dateThu, 14 Dec 2017 09:59:07 +0000
treeherderautoland@16bcfaad13e1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1393011
milestone59.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 1393011 - Part 1: Rename skipPool() to maybeSkipAutomaticInstructions(). r=bbouvier The greater verbosity more accurately describes skipPool()'s behavior.
js/src/jit/arm/Assembler-arm.cpp
js/src/jit/arm/Assembler-arm.h
js/src/jit/arm/MacroAssembler-arm.cpp
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -3258,51 +3258,51 @@ InstIsArtificialGuard(Instruction* inst,
 {
     if (!InstIsGuard(inst, ph))
         return false;
     return !(*ph)->isNatural();
 }
 
 // If the instruction points to a artificial pool guard then skip the pool.
 Instruction*
-Instruction::skipPool()
+Instruction::maybeSkipAutomaticInstructions()
 {
     const PoolHeader* ph;
     // If this is a guard, and the next instruction is a header, always work
     // around the pool. If it isn't a guard, then start looking ahead.
     if (InstIsGuard(this, &ph)) {
         // Don't skip a natural guard.
         if (ph->isNatural())
             return this;
-        return (this + 1 + ph->size())->skipPool();
+        return (this + 1 + ph->size())->maybeSkipAutomaticInstructions();
     }
     if (InstIsBNop(this))
-        return (this + 1)->skipPool();
+        return (this + 1)->maybeSkipAutomaticInstructions();
     return this;
 }
 
 void
-BufferInstructionIterator::skipPool()
+BufferInstructionIterator::maybeSkipAutomaticInstructions()
 {
     // If this is a guard, and the next instruction is a header, always work
     // around the pool. If it isn't a guard, then start looking ahead.
 
     const PoolHeader* ph;
     if (InstIsGuard(*this, &ph)) {
         // Don't skip a natural guard.
         if (ph->isNatural())
             return;
         advance(sizeof(Instruction) * (1 + ph->size()));
-        skipPool();
+        maybeSkipAutomaticInstructions();
         return;
     }
 
     if (InstIsBNop(cur())) {
         next();
-        skipPool();
+        maybeSkipAutomaticInstructions();
     }
 }
 
 // Cases to be handled:
 // 1) no pools or branches in sight => return this+1
 // 2) branch to next instruction => return this+2, because a nop needed to be inserted into the stream.
 // 3) this+1 is an artificial guard for a pool => return first instruction after the pool
 // 4) this+1 is a natural guard => return the branch
@@ -3335,20 +3335,20 @@ BufferInstructionIterator::skipPool()
 Instruction*
 Instruction::next()
 {
     Instruction* ret = this+1;
     const PoolHeader* ph;
     // If this is a guard, and the next instruction is a header, always work
     // around the pool. If it isn't a guard, then start looking ahead.
     if (InstIsGuard(this, &ph))
-        return (ret + ph->size())->skipPool();
+        return (ret + ph->size())->maybeSkipAutomaticInstructions();
     if (InstIsArtificialGuard(ret, &ph))
-        return (ret + 1 + ph->size())->skipPool();
-    return ret->skipPool();
+        return (ret + 1 + ph->size())->maybeSkipAutomaticInstructions();
+    return ret->maybeSkipAutomaticInstructions();
 }
 
 void
 Assembler::ToggleToJmp(CodeLocationLabel inst_)
 {
     uint32_t* ptr = (uint32_t*)inst_.raw();
 
     DebugOnly<Instruction*> inst = (Instruction*)inst_.raw();
@@ -3382,18 +3382,17 @@ Assembler::ToggleToCmp(CodeLocationLabel
 
     AutoFlushICache::flush(uintptr_t(ptr), 4);
 }
 
 void
 Assembler::ToggleCall(CodeLocationLabel inst_, bool enabled)
 {
     Instruction* inst = (Instruction*)inst_.raw();
-    // Skip a pool with an artificial guard.
-    inst = inst->skipPool();
+    inst = inst->maybeSkipAutomaticInstructions();
     MOZ_ASSERT(inst->is<InstMovW>() || inst->is<InstLDR>());
 
     if (inst->is<InstMovW>()) {
         // If it looks like the start of a movw/movt sequence, then make sure we
         // have all of it (and advance the iterator past the full sequence).
         inst = inst->next();
         MOZ_ASSERT(inst->is<InstMovT>());
     }
@@ -3413,18 +3412,17 @@ Assembler::ToggleCall(CodeLocationLabel 
 
     AutoFlushICache::flush(uintptr_t(inst), 4);
 }
 
 size_t
 Assembler::ToggledCallSize(uint8_t* code)
 {
     Instruction* inst = (Instruction*)code;
-    // Skip a pool with an artificial guard.
-    inst = inst->skipPool();
+    inst = inst->maybeSkipAutomaticInstructions();
     MOZ_ASSERT(inst->is<InstMovW>() || inst->is<InstLDR>());
 
     if (inst->is<InstMovW>()) {
         // If it looks like the start of a movw/movt sequence, then make sure we
         // have all of it (and advance the iterator past the full sequence).
         inst = inst->next();
         MOZ_ASSERT(inst->is<InstMovT>());
     }
@@ -3434,17 +3432,17 @@ Assembler::ToggledCallSize(uint8_t* code
     return uintptr_t(inst) + 4 - uintptr_t(code);
 }
 
 uint8_t*
 Assembler::BailoutTableStart(uint8_t* code)
 {
     Instruction* inst = (Instruction*)code;
     // Skip a pool with an artificial guard or NOP fill.
-    inst = inst->skipPool();
+    inst = inst->maybeSkipAutomaticInstructions();
     MOZ_ASSERT(inst->is<InstBLImm>());
     return (uint8_t*) inst;
 }
 
 uint32_t Assembler::NopFill = 0;
 
 uint32_t
 Assembler::GetNopFill()
--- a/js/src/jit/arm/Assembler-arm.h
+++ b/js/src/jit/arm/Assembler-arm.h
@@ -2001,22 +2001,24 @@ class Instruction
         return *this;
     }
     // Since almost all instructions have condition codes, the condition code
     // extractor resides in the base class.
     Assembler::Condition extractCond() {
         MOZ_ASSERT(data >> 28 != 0xf, "The instruction does not have condition code");
         return (Assembler::Condition)(data & 0xf0000000);
     }
-    // Get the next instruction in the instruction stream.
-    // This does neat things like ignoreconstant pools and their guards.
+
+    // Get the next intentionally-placed instruction in the instruction stream.
+    // Artificial pool guards and automatically-placed NOP instructions are skipped.
     Instruction* next();
 
-    // Skipping pools with artificial guards.
-    Instruction* skipPool();
+    // If the current instruction was automatically-inserted (pool guards and NOPs),
+    // advance to the next instruction that was inserted intentionally.
+    Instruction* maybeSkipAutomaticInstructions();
 
     // Sometimes, an api wants a uint32_t (or a pointer to it) rather than an
     // instruction. raw() just coerces this into a pointer to a uint32_t.
     const uint32_t* raw() const { return &data; }
     uint32_t size() const { return 4; }
 }; // Instruction
 
 // Make sure that it is the right size.
@@ -2261,39 +2263,45 @@ class InstMOV : public InstALU
     static bool IsTHIS (const Instruction& i);
     static InstMOV* AsTHIS (const Instruction& i);
 };
 
 class InstructionIterator
 {
   private:
     Instruction* inst_;
+
   public:
-    explicit InstructionIterator(Instruction* inst) : inst_(inst) {
-        skipPool();
+    explicit InstructionIterator(Instruction* inst)
+      : inst_(inst)
+    {
+        maybeSkipAutomaticInstructions();
     }
-    void skipPool() {
-        inst_ = inst_->skipPool();
+
+    void maybeSkipAutomaticInstructions() {
+        inst_ = inst_->maybeSkipAutomaticInstructions();
     }
+
     Instruction* next() {
         inst_ = inst_->next();
-        return cur();
+        return inst_;
     }
+
     Instruction* cur() const {
         return inst_;
     }
 };
 
 class BufferInstructionIterator : public ARMBuffer::AssemblerBufferInstIterator
 {
   public:
     BufferInstructionIterator(BufferOffset bo, ARMBuffer* buffer)
       : ARMBuffer::AssemblerBufferInstIterator(bo, buffer)
     {}
-    void skipPool();
+    void maybeSkipAutomaticInstructions();
 };
 
 static const uint32_t NumIntArgRegs = 4;
 
 // There are 16 *float* registers available for arguments
 // If doubles are used, only half the number of registers are available.
 static const uint32_t NumFloatArgRegs = 16;
 
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -352,17 +352,17 @@ template<class Iter>
 void
 MacroAssemblerARM::ma_mov_patch(Imm32 imm32, Register dest, Assembler::Condition c,
                                 RelocStyle rs, Iter iter)
 {
     MOZ_ASSERT(iter.cur());
 
     // Make sure the current instruction is not an artificial guard inserted
     // by the assembler buffer.
-    iter.skipPool();
+    iter.maybeSkipAutomaticInstructions();
 
     int32_t imm = imm32.value;
     switch(rs) {
       case L_MOVWT:
         Assembler::as_movw_patch(dest, Imm16(imm & 0xffff), c, iter.cur());
         Assembler::as_movt_patch(dest, Imm16(imm >> 16 & 0xffff), c, iter.next());
         break;
       case L_LDR: