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.

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

mercurial