js/src/jit/EffectiveAddressAnalysis.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "jit/EffectiveAddressAnalysis.h"
     8 #include "jit/MIR.h"
     9 #include "jit/MIRGraph.h"
    11 using namespace js;
    12 using namespace jit;
    14 static void
    15 AnalyzeLsh(TempAllocator &alloc, MLsh *lsh)
    16 {
    17     if (lsh->specialization() != MIRType_Int32)
    18         return;
    20     MDefinition *index = lsh->lhs();
    21     JS_ASSERT(index->type() == MIRType_Int32);
    23     MDefinition *shift = lsh->rhs();
    24     if (!shift->isConstant())
    25         return;
    27     Value shiftValue = shift->toConstant()->value();
    28     if (!shiftValue.isInt32() || !IsShiftInScaleRange(shiftValue.toInt32()))
    29         return;
    31     Scale scale = ShiftToScale(shiftValue.toInt32());
    33     int32_t displacement = 0;
    34     MInstruction *last = lsh;
    35     MDefinition *base = nullptr;
    36     while (true) {
    37         if (!last->hasOneUse())
    38             break;
    40         MUseIterator use = last->usesBegin();
    41         if (!use->consumer()->isDefinition() || !use->consumer()->toDefinition()->isAdd())
    42             break;
    44         MAdd *add = use->consumer()->toDefinition()->toAdd();
    45         if (add->specialization() != MIRType_Int32 || !add->isTruncated())
    46             break;
    48         MDefinition *other = add->getOperand(1 - use->index());
    50         if (other->isConstant()) {
    51             displacement += other->toConstant()->value().toInt32();
    52         } else {
    53             if (base)
    54                 break;
    55             base = other;
    56         }
    58         last = add;
    59     }
    61     if (!base) {
    62         uint32_t elemSize = 1 << ScaleToShift(scale);
    63         if (displacement % elemSize != 0)
    64             return;
    66         if (!last->hasOneUse())
    67             return;
    69         MUseIterator use = last->usesBegin();
    70         if (!use->consumer()->isDefinition() || !use->consumer()->toDefinition()->isBitAnd())
    71             return;
    73         MBitAnd *bitAnd = use->consumer()->toDefinition()->toBitAnd();
    74         MDefinition *other = bitAnd->getOperand(1 - use->index());
    75         if (!other->isConstant() || !other->toConstant()->value().isInt32())
    76             return;
    78         uint32_t bitsClearedByShift = elemSize - 1;
    79         uint32_t bitsClearedByMask = ~uint32_t(other->toConstant()->value().toInt32());
    80         if ((bitsClearedByShift & bitsClearedByMask) != bitsClearedByMask)
    81             return;
    83         bitAnd->replaceAllUsesWith(last);
    84         return;
    85     }
    87     MEffectiveAddress *eaddr = MEffectiveAddress::New(alloc, base, index, scale, displacement);
    88     last->replaceAllUsesWith(eaddr);
    89     last->block()->insertAfter(last, eaddr);
    90 }
    92 // This analysis converts patterns of the form:
    93 //   truncate(x + (y << {0,1,2,3}))
    94 //   truncate(x + (y << {0,1,2,3}) + imm32)
    95 // into a single lea instruction, and patterns of the form:
    96 //   asmload(x + imm32)
    97 //   asmload(x << {0,1,2,3})
    98 //   asmload((x << {0,1,2,3}) + imm32)
    99 //   asmload((x << {0,1,2,3}) & mask)            (where mask is redundant with shift)
   100 //   asmload(((x << {0,1,2,3}) + imm32) & mask)  (where mask is redundant with shift + imm32)
   101 // into a single asmload instruction (and for asmstore too).
   102 //
   103 // Additionally, we should consider the general forms:
   104 //   truncate(x + y + imm32)
   105 //   truncate((y << {0,1,2,3}) + imm32)
   106 bool
   107 EffectiveAddressAnalysis::analyze()
   108 {
   109     for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
   110         for (MInstructionIterator i = block->begin(); i != block->end(); i++) {
   111             if (i->isLsh())
   112                 AnalyzeLsh(graph_.alloc(), i->toLsh());
   113         }
   114     }
   115     return true;
   116 }

mercurial