bool AllocationIntegrityState::checkSafepointAllocation(LInstruction* ins, uint32_t vreg, LAllocation alloc, bool populateSafepoints) { LSafepoint* safepoint = ins->safepoint(); MOZ_ASSERT(safepoint); if (ins->isCall() && alloc.isRegister()) return true; if (alloc.isRegister()) { AnyRegister reg = alloc.toRegister(); if (populateSafepoints) safepoint->addLiveRegister(reg); MOZ_ASSERT(safepoint->liveRegs().has(reg)); } // The |this| argument slot is implicitly included in all safepoints. if (alloc.isArgument() && alloc.toArgument()->index() < THIS_FRAME_ARGSLOT + sizeof(Value)) return true; LDefinition::Type type = virtualRegisters[vreg] ? virtualRegisters[vreg]->type() : LDefinition::GENERAL; switch (type) { case LDefinition::OBJECT: if (populateSafepoints) { JitSpew(JitSpew_RegAlloc, "Safepoint object v%u i%u %s", vreg, ins->id(), alloc.toString()); if (!safepoint->addGcPointer(alloc)) return false; } MOZ_ASSERT(safepoint->hasGcPointer(alloc)); break; case LDefinition::SLOTS: if (populateSafepoints) { JitSpew(JitSpew_RegAlloc, "Safepoint slots v%u i%u %s", vreg, ins->id(), alloc.toString()); if (!safepoint->addSlotsOrElementsPointer(alloc)) return false; } MOZ_ASSERT(safepoint->hasSlotsOrElementsPointer(alloc)); break; #ifdef JS_NUNBOX32 // Do not assert that safepoint information for nunbox types is complete, // as if a vreg for a value's components are copied in multiple places // then the safepoint information may not reflect all copies. All copies // of payloads must be reflected, however, for generational GC. case LDefinition::TYPE: if (populateSafepoints) { JitSpew(JitSpew_RegAlloc, "Safepoint type v%u i%u %s", vreg, ins->id(), alloc.toString()); if (!safepoint->addNunboxType(vreg, alloc)) return false; } break; case LDefinition::PAYLOAD: if (populateSafepoints) { JitSpew(JitSpew_RegAlloc, "Safepoint payload v%u i%u %s", vreg, ins->id(), alloc.toString()); if (!safepoint->addNunboxPayload(vreg, alloc)) return false; } MOZ_ASSERT(safepoint->hasNunboxPayload(alloc)); break; #else case LDefinition::BOX: if (populateSafepoints) { JitSpew(JitSpew_RegAlloc, "Safepoint boxed value v%u i%u %s", vreg, ins->id(), alloc.toString()); if (!safepoint->addBoxedValue(alloc)) return false; } MOZ_ASSERT(safepoint->hasBoxedValue(alloc)); break; #endif default: break; } return true; }
bool AllocationIntegrityState::checkSafepointAllocation(LInstruction *ins, uint32_t vreg, LAllocation alloc, bool populateSafepoints) { LSafepoint *safepoint = ins->safepoint(); JS_ASSERT(safepoint); if (ins->isCall() && alloc.isRegister()) return true; if (alloc.isRegister()) { AnyRegister reg = alloc.toRegister(); if (populateSafepoints) safepoint->addLiveRegister(reg); JS_ASSERT(safepoint->liveRegs().has(reg)); } LDefinition::Type type = virtualRegisters[vreg] ? virtualRegisters[vreg]->type() : LDefinition::GENERAL; switch (type) { case LDefinition::OBJECT: if (populateSafepoints) { IonSpew(IonSpew_RegAlloc, "Safepoint object v%u i%u %s", vreg, ins->id(), alloc.toString()); if (!safepoint->addGcPointer(alloc)) return false; } JS_ASSERT(safepoint->hasGcPointer(alloc)); break; #ifdef JS_NUNBOX32 // Do not assert that safepoint information for nunboxes is complete, // as if a vreg for a value's components are copied in multiple places // then the safepoint information may not reflect all copies. // See SafepointWriter::writeNunboxParts. case LDefinition::TYPE: if (populateSafepoints) { IonSpew(IonSpew_RegAlloc, "Safepoint type v%u i%u %s", vreg, ins->id(), alloc.toString()); if (!safepoint->addNunboxType(vreg, alloc)) return false; } break; case LDefinition::PAYLOAD: if (populateSafepoints) { IonSpew(IonSpew_RegAlloc, "Safepoint payload v%u i%u %s", vreg, ins->id(), alloc.toString()); if (!safepoint->addNunboxPayload(vreg, alloc)) return false; } break; #else case LDefinition::BOX: if (populateSafepoints) { IonSpew(IonSpew_RegAlloc, "Safepoint boxed value v%u i%u %s", vreg, ins->id(), alloc.toString()); if (!safepoint->addBoxedValue(alloc)) return false; } JS_ASSERT(safepoint->hasBoxedValue(alloc)); break; #endif default: break; } return true; }