bool
GreedyAllocator::informSafepoint(LSafepoint *safepoint)
{
    for (InlineListIterator<VirtualRegister> iter = liveSlots_.begin();
         iter != liveSlots_.end();
         iter++)
    {
        VirtualRegister *vr = *iter;
        if (vr->type() == LDefinition::OBJECT || vr->type() == LDefinition::BOX) {
            if (!safepoint->addGcSlot(vr->stackSlot()))
                return false;
            continue;
        }

#ifdef JS_NUNBOX32
        if (!IsNunbox(vr->type()))
            continue;

        VirtualRegister *other = otherHalfOfNunbox(vr);

        // Only bother if both halves are spilled.
        if (vr->hasStackSlot() && other->hasStackSlot()) {
            uint32 slot = BaseOfNunboxSlot(vr->type(), vr->stackSlot());
            if (!safepoint->addValueSlot(slot))
                return false;
        }
#endif
    }
    return true;
}
void
GreedyAllocator::allocateStack(VirtualRegister *vr)
{
    if (vr->hasBackingStack())
        return;

    uint32 index;
#ifdef JS_NUNBOX32
    if (IsNunbox(vr->type())) {
        VirtualRegister *other = otherHalfOfNunbox(vr);
        unsigned stackSlot;
        if (!other->hasStackSlot())
            stackSlot = allocateSlotFor(vr);
        else
            stackSlot = BaseOfNunboxSlot(other->type(), other->stackSlot());
        index = stackSlot - OffsetOfNunboxSlot(vr->type());
    } else
#endif
    {
        index = allocateSlotFor(vr);
    }

    IonSpew(IonSpew_RegAlloc, "    assign vr%d := stack%d", vr->def->virtualRegister(), index);

    vr->setStackSlot(index);
}
bool
GreedyAllocator::spillDefinition(LDefinition *def)
{
    if (def->policy() == LDefinition::PASSTHROUGH)
        return true;

    VirtualRegister *vr = getVirtualRegister(def);
    const LAllocation *output = def->output();

    if (output->isRegister()) {
        if (vr->hasRegister()) {
            // If the returned register is different from the output
            // register, a move is required.
            AnyRegister out = GetAllocatedRegister(output);
            if (out != vr->reg()) {
                if (!spill(*output, vr->reg()))
                    return false;
            }
        }

        // Spill to the stack if needed.
        if (vr->hasStackSlot() && vr->backingStackUsed()) {
            if (!spill(*output, vr->backingStack()))
                return false;
        }
    } else if (vr->hasRegister()) {
        // This definition has a canonical spill location, so make sure to
        // load it to the resulting register, if any.
        JS_ASSERT(!vr->hasStackSlot());
        JS_ASSERT(vr->hasBackingStack());
        if (!spill(*output, vr->reg()))
            return false;
    }

    return true;
}