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; }