void LIRGeneratorARM::visitUnbox(MUnbox *unbox) { // An unbox on arm reads in a type tag (either in memory or a register) and // a payload. Unlike most instructions conusming a box, we ask for the type // second, so that the result can re-use the first input. MDefinition *inner = unbox->getOperand(0); MOZ_ASSERT(inner->type() == MIRType_Value); ensureDefined(inner); if (IsFloatingPointType(unbox->type())) { LUnboxFloatingPoint *lir = new(alloc()) LUnboxFloatingPoint(unbox->type()); if (unbox->fallible()) assignSnapshot(lir, unbox->bailoutKind()); useBox(lir, LUnboxFloatingPoint::Input, inner); define(lir, unbox); return; } // Swap the order we use the box pieces so we can re-use the payload register. LUnbox *lir = new(alloc()) LUnbox; lir->setOperand(0, usePayloadInRegisterAtStart(inner)); lir->setOperand(1, useType(inner, LUse::REGISTER)); if (unbox->fallible()) assignSnapshot(lir, unbox->bailoutKind()); // Types and payloads form two separate intervals. If the type becomes dead // before the payload, it could be used as a Value without the type being // recoverable. Unbox's purpose is to eagerly kill the definition of a type // tag, so keeping both alive (for the purpose of gcmaps) is unappealing. // Instead, we create a new virtual register. defineReuseInput(lir, unbox, 0); }
bool LIRGeneratorARM::visitUnbox(MUnbox *unbox) { // An unbox on arm reads in a type tag (either in memory or a register) and // a payload. Unlike most instructions conusming a box, we ask for the type // second, so that the result can re-use the first input. MDefinition *inner = unbox->getOperand(0); if (!ensureDefined(inner)) return false; if (unbox->type() == MIRType_Double) { LUnboxDouble *lir = new LUnboxDouble(); if (unbox->fallible() && !assignSnapshot(lir, unbox->bailoutKind())) return false; if (!useBox(lir, LUnboxDouble::Input, inner)) return false; return define(lir, unbox); } // Swap the order we use the box pieces so we can re-use the payload register. LUnbox *lir = new LUnbox; lir->setOperand(0, usePayloadInRegisterAtStart(inner)); lir->setOperand(1, useType(inner, LUse::REGISTER)); if (unbox->fallible() && !assignSnapshot(lir, unbox->bailoutKind())) return false; // Note that PASSTHROUGH here is illegal, since types and payloads form two // separate intervals. If the type becomes dead before the payload, it // could be used as a Value without the type being recoverable. Unbox's // purpose is to eagerly kill the definition of a type tag, so keeping both // alive (for the purpose of gcmaps) is unappealing. Instead, we create a // new virtual register. return defineReuseInput(lir, unbox, 0); }