js/src/jit/shared/Lowering-shared.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/shared/Lowering-shared-inl.h"
     9 #include "jit/LIR.h"
    10 #include "jit/MIR.h"
    12 using namespace js;
    13 using namespace jit;
    15 bool
    16 LIRGeneratorShared::visitConstant(MConstant *ins)
    17 {
    18     const Value &v = ins->value();
    19     switch (ins->type()) {
    20       case MIRType_Boolean:
    21         return define(new(alloc()) LInteger(v.toBoolean()), ins);
    22       case MIRType_Int32:
    23         return define(new(alloc()) LInteger(v.toInt32()), ins);
    24       case MIRType_String:
    25         return define(new(alloc()) LPointer(v.toString()), ins);
    26       case MIRType_Object:
    27         return define(new(alloc()) LPointer(&v.toObject()), ins);
    28       default:
    29         // Constants of special types (undefined, null) should never flow into
    30         // here directly. Operations blindly consuming them require a Box.
    31         JS_ASSERT(!"unexpected constant type");
    32         return false;
    33     }
    34 }
    36 bool
    37 LIRGeneratorShared::defineTypedPhi(MPhi *phi, size_t lirIndex)
    38 {
    39     LPhi *lir = current->getPhi(lirIndex);
    41     uint32_t vreg = getVirtualRegister();
    42     if (vreg >= MAX_VIRTUAL_REGISTERS)
    43         return false;
    45     phi->setVirtualRegister(vreg);
    46     lir->setDef(0, LDefinition(vreg, LDefinition::TypeFrom(phi->type())));
    47     annotate(lir);
    48     return true;
    49 }
    51 void
    52 LIRGeneratorShared::lowerTypedPhiInput(MPhi *phi, uint32_t inputPosition, LBlock *block, size_t lirIndex)
    53 {
    54     MDefinition *operand = phi->getOperand(inputPosition);
    55     LPhi *lir = block->getPhi(lirIndex);
    56     lir->setOperand(inputPosition, LUse(operand->virtualRegister(), LUse::ANY));
    57 }
    59 LRecoverInfo *
    60 LIRGeneratorShared::getRecoverInfo(MResumePoint *rp)
    61 {
    62     if (cachedRecoverInfo_ && cachedRecoverInfo_->mir() == rp)
    63         return cachedRecoverInfo_;
    65     LRecoverInfo *recoverInfo = LRecoverInfo::New(gen, rp);
    66     if (!recoverInfo)
    67         return nullptr;
    69     cachedRecoverInfo_ = recoverInfo;
    70     return recoverInfo;
    71 }
    73 #ifdef JS_NUNBOX32
    74 LSnapshot *
    75 LIRGeneratorShared::buildSnapshot(LInstruction *ins, MResumePoint *rp, BailoutKind kind)
    76 {
    77     LRecoverInfo *recover = getRecoverInfo(rp);
    78     if (!recover)
    79         return nullptr;
    81     LSnapshot *snapshot = LSnapshot::New(gen, recover, kind);
    82     if (!snapshot)
    83         return nullptr;
    85     size_t i = 0;
    86     for (MResumePoint **it = recover->begin(), **end = recover->end(); it != end; ++it) {
    87         MResumePoint *mir = *it;
    88         for (size_t j = 0, e = mir->numOperands(); j < e; ++i, ++j) {
    89             MDefinition *ins = mir->getOperand(j);
    91             LAllocation *type = snapshot->typeOfSlot(i);
    92             LAllocation *payload = snapshot->payloadOfSlot(i);
    94             if (ins->isBox())
    95                 ins = ins->toBox()->getOperand(0);
    97             // Guards should never be eliminated.
    98             JS_ASSERT_IF(ins->isUnused(), !ins->isGuard());
   100             // Snapshot operands other than constants should never be
   101             // emitted-at-uses. Try-catch support depends on there being no
   102             // code between an instruction and the LOsiPoint that follows it.
   103             JS_ASSERT_IF(!ins->isConstant(), !ins->isEmittedAtUses());
   105             // The register allocation will fill these fields in with actual
   106             // register/stack assignments. During code generation, we can restore
   107             // interpreter state with the given information. Note that for
   108             // constants, including known types, we record a dummy placeholder,
   109             // since we can recover the same information, much cleaner, from MIR.
   110             if (ins->isConstant() || ins->isUnused()) {
   111                 *type = LConstantIndex::Bogus();
   112                 *payload = LConstantIndex::Bogus();
   113             } else if (ins->type() != MIRType_Value) {
   114                 *type = LConstantIndex::Bogus();
   115                 *payload = use(ins, LUse::KEEPALIVE);
   116             } else {
   117                 *type = useType(ins, LUse::KEEPALIVE);
   118                 *payload = usePayload(ins, LUse::KEEPALIVE);
   119             }
   120         }
   121     }
   123     return snapshot;
   124 }
   126 #elif JS_PUNBOX64
   128 LSnapshot *
   129 LIRGeneratorShared::buildSnapshot(LInstruction *ins, MResumePoint *rp, BailoutKind kind)
   130 {
   131     LRecoverInfo *recover = getRecoverInfo(rp);
   132     if (!recover)
   133         return nullptr;
   135     LSnapshot *snapshot = LSnapshot::New(gen, recover, kind);
   136     if (!snapshot)
   137         return nullptr;
   139     size_t i = 0;
   140     for (MResumePoint **it = recover->begin(), **end = recover->end(); it != end; ++it) {
   141         MResumePoint *mir = *it;
   142         for (size_t j = 0, e = mir->numOperands(); j < e; ++i, ++j) {
   143             MDefinition *def = mir->getOperand(j);
   145             if (def->isBox())
   146                 def = def->toBox()->getOperand(0);
   148             // Guards should never be eliminated.
   149             JS_ASSERT_IF(def->isUnused(), !def->isGuard());
   151             // Snapshot operands other than constants should never be
   152             // emitted-at-uses. Try-catch support depends on there being no
   153             // code between an instruction and the LOsiPoint that follows it.
   154             JS_ASSERT_IF(!def->isConstant(), !def->isEmittedAtUses());
   156             LAllocation *a = snapshot->getEntry(i);
   158             if (def->isUnused()) {
   159                 *a = LConstantIndex::Bogus();
   160                 continue;
   161             }
   163             *a = useKeepaliveOrConstant(def);
   164         }
   165     }
   167     return snapshot;
   168 }
   169 #endif
   171 bool
   172 LIRGeneratorShared::assignSnapshot(LInstruction *ins, BailoutKind kind)
   173 {
   174     // assignSnapshot must be called before define/add, since
   175     // it may add new instructions for emitted-at-use operands.
   176     JS_ASSERT(ins->id() == 0);
   178     LSnapshot *snapshot = buildSnapshot(ins, lastResumePoint_, kind);
   179     if (!snapshot)
   180         return false;
   182     ins->assignSnapshot(snapshot);
   183     return true;
   184 }
   186 bool
   187 LIRGeneratorShared::assignSafepoint(LInstruction *ins, MInstruction *mir)
   188 {
   189     JS_ASSERT(!osiPoint_);
   190     JS_ASSERT(!ins->safepoint());
   192     ins->initSafepoint(alloc());
   194     MResumePoint *mrp = mir->resumePoint() ? mir->resumePoint() : lastResumePoint_;
   195     LSnapshot *postSnapshot = buildSnapshot(ins, mrp, Bailout_Normal);
   196     if (!postSnapshot)
   197         return false;
   199     osiPoint_ = new(alloc()) LOsiPoint(ins->safepoint(), postSnapshot);
   201     return lirGraph_.noteNeedsSafepoint(ins);
   202 }

mercurial