IonBailoutIterator::IonBailoutIterator(const JitActivationIterator &activations, BailoutStack *bailout) : IonFrameIterator(activations), machine_(bailout->machine()) { uint8_t *sp = bailout->parentStackPointer(); uint8_t *fp = sp + bailout->frameSize(); current_ = fp; type_ = IonFrame_OptimizedJS; topFrameSize_ = current_ - sp; topIonScript_ = script()->ionScript(); if (bailout->frameClass() == FrameSizeClass::None()) { snapshotOffset_ = bailout->snapshotOffset(); return; } // Compute the snapshot offset from the bailout ID. JitActivation *activation = activations.activation()->asJit(); JSRuntime *rt = activation->compartment()->runtimeFromMainThread(); IonCode *code = rt->ionRuntime()->getBailoutTable(bailout->frameClass()); uintptr_t tableOffset = bailout->tableOffset(); uintptr_t tableStart = reinterpret_cast<uintptr_t>(code->raw()); JS_ASSERT(tableOffset >= tableStart && tableOffset < tableStart + code->instructionsSize()); JS_ASSERT((tableOffset - tableStart) % BAILOUT_TABLE_ENTRY_SIZE == 0); uint32_t bailoutId = ((tableOffset - tableStart) / BAILOUT_TABLE_ENTRY_SIZE) - 1; JS_ASSERT(bailoutId < BAILOUT_TABLE_SIZE); snapshotOffset_ = topIonScript_->bailoutToSnapshot(bailoutId); }
BailoutEnvironment::BailoutEnvironment(IonCompartment *ion, void **sp) : sp_(sp) { bailout_ = reinterpret_cast<ExtendedBailoutStack *>(sp); if (bailout_->frameClass() != FrameSizeClass::None()) { frameSize_ = bailout_->frameSize(); frame_ = &sp_[sizeof(BailoutStack) / STACK_SLOT_SIZE]; // Compute the bailout ID. IonCode *code = ion->getBailoutTable(bailout_->frameClass()); uintptr_t tableOffset = bailout_->tableOffset(); uintptr_t tableStart = reinterpret_cast<uintptr_t>(code->raw()); JS_ASSERT(tableOffset >= tableStart && tableOffset < tableStart + code->instructionsSize()); JS_ASSERT((tableOffset - tableStart) % BAILOUT_TABLE_ENTRY_SIZE == 0); bailoutId_ = ((tableOffset - tableStart) / BAILOUT_TABLE_ENTRY_SIZE) - 1; JS_ASSERT(bailoutId_ < BAILOUT_TABLE_SIZE); } else { frameSize_ = bailout_->frameSize(); frame_ = &sp_[sizeof(ExtendedBailoutStack) / STACK_SLOT_SIZE]; } }
ParallelIonInvoke(JSContext *cx, HandleFunction callee, uint32_t argc) : argc_(argc), args(argv_ + 2) { JS_ASSERT(argc <= maxArgc + 2); // Set 'callee' and 'this'. argv_[0] = ObjectValue(*callee); argv_[1] = UndefinedValue(); // Find JIT code pointer. IonScript *ion = callee->nonLazyScript()->parallelIonScript(); IonCode *code = ion->method(); jitcode_ = code->raw(); enter_ = cx->compartment->ionCompartment()->enterJIT(); calleeToken_ = CalleeToParallelToken(callee); }
bool CodeGeneratorX86Shared::generateOutOfLineCode() { if (!CodeGeneratorShared::generateOutOfLineCode()) return false; if (deoptLabel_.used()) { // All non-table-based bailouts will go here. masm.bind(&deoptLabel_); // Push the frame size, so the handler can recover the IonScript. masm.push(Imm32(frameSize())); IonCode *handler = gen->ionRuntime()->getGenericBailoutHandler(); masm.jmp(ImmPtr(handler->raw()), Relocation::IONCODE); } return true; }