зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset a95360977f76 (bug 1428453) for arm build bustage
This commit is contained in:
Родитель
c921526073
Коммит
c241a94698
|
@ -3292,8 +3292,20 @@ MacroAssembler::wasmEmitOldTrapOutOfLineCode()
|
|||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(site.trap != wasm::Trap::IndirectCallBadSig);
|
||||
|
||||
if (site.trap == wasm::Trap::IndirectCallBadSig) {
|
||||
// The indirect call bad-signature trap is a special case for two
|
||||
// reasons:
|
||||
// - the check happens in the very first instructions of the
|
||||
// prologue, before the stack frame has been set up which messes
|
||||
// up everything (stack depth computations, unwinding)
|
||||
// - the check happens in the callee while the trap should be
|
||||
// reported at the caller's call_indirect
|
||||
// To solve both problems at once, the out-of-line path (far) jumps
|
||||
// directly to the trap exit stub. This takes advantage of the fact
|
||||
// that there is already a CallSite for call_indirect and the
|
||||
// current pre-prologue stack/register state.
|
||||
append(wasm::OldTrapFarJump(site.trap, farJumpWithPatch()));
|
||||
} else {
|
||||
// Inherit the frame depth of the trap site. This value is captured
|
||||
// by the wasm::CallSite to allow unwinding this frame.
|
||||
setFramePushed(site.framePushed);
|
||||
|
@ -3320,6 +3332,7 @@ MacroAssembler::wasmEmitOldTrapOutOfLineCode()
|
|||
// the trapping instruction.
|
||||
wasm::CallSiteDesc desc(site.offset, wasm::CallSiteDesc::OldTrapExit);
|
||||
call(desc, site.trap);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Traps do not return, so no need to freeStack().
|
||||
|
|
|
@ -1646,12 +1646,7 @@ Simulator::handleWasmSegFault(int32_t addr, unsigned numBytes)
|
|||
const wasm::ModuleSegment* moduleSegment = segment->asModule();
|
||||
|
||||
wasm::Instance* instance = wasm::LookupFaultingInstance(*moduleSegment, pc, fp);
|
||||
if (!instance)
|
||||
return false;
|
||||
|
||||
MOZ_RELEASE_ASSERT(&instance->code() == &codeSegment.code());
|
||||
|
||||
if (!instance->memoryAccessInGuardRegion((uint8_t*)addr, numBytes))
|
||||
if (!instance || !instance->memoryAccessInGuardRegion((uint8_t*)addr, numBytes))
|
||||
return false;
|
||||
|
||||
const wasm::MemoryAccess* memoryAccess = instance->code().lookupMemoryAccess(pc);
|
||||
|
|
|
@ -1823,27 +1823,13 @@ jit::JitActivation::wasmInterruptResumePC() const
|
|||
}
|
||||
|
||||
void
|
||||
jit::JitActivation::startWasmTrap(wasm::Trap trap, uint32_t bytecodeOffset,
|
||||
const wasm::RegisterState& state)
|
||||
jit::JitActivation::startWasmTrap(wasm::Trap trap, uint32_t bytecodeOffset, void* pc, void* fp)
|
||||
{
|
||||
bool unwound;
|
||||
wasm::UnwindState unwindState;
|
||||
MOZ_ALWAYS_TRUE(wasm::StartUnwinding(state, &unwindState, &unwound));
|
||||
MOZ_ASSERT(unwound == (trap == wasm::Trap::IndirectCallBadSig));
|
||||
|
||||
void* pc = unwindState.pc;
|
||||
wasm::Frame* fp = unwindState.fp;
|
||||
|
||||
const wasm::Code& code = fp->tls->instance->code();
|
||||
MOZ_RELEASE_ASSERT(&code == wasm::LookupCode(pc));
|
||||
|
||||
// If the frame was unwound, the bytecodeOffset must be recovered from the
|
||||
// callsite so that it is accurate.
|
||||
if (unwound)
|
||||
bytecodeOffset = code.lookupCallSite(pc)->lineOrBytecode();
|
||||
MOZ_ASSERT(pc);
|
||||
MOZ_ASSERT(fp);
|
||||
|
||||
cx_->runtime()->wasmUnwindData.ref().construct<wasm::TrapData>(pc, trap, bytecodeOffset);
|
||||
setWasmExitFP(fp);
|
||||
setWasmExitFP((wasm::Frame*)fp);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1667,13 +1667,13 @@ class JitActivation : public Activation
|
|||
// when the interrupt is handled.
|
||||
|
||||
// Returns true iff we've entered interrupted state.
|
||||
bool startWasmInterrupt(const wasm::RegisterState& state);
|
||||
bool startWasmInterrupt(const JS::ProfilingFrameIterator::RegisterState& state);
|
||||
void finishWasmInterrupt();
|
||||
bool isWasmInterrupted() const;
|
||||
void* wasmInterruptUnwindPC() const;
|
||||
void* wasmInterruptResumePC() const;
|
||||
|
||||
void startWasmTrap(wasm::Trap trap, uint32_t bytecodeOffset, const wasm::RegisterState& state);
|
||||
void startWasmTrap(wasm::Trap trap, uint32_t bytecodeOffset, void* pc, void* fp);
|
||||
void finishWasmTrap();
|
||||
bool isWasmTrapping() const;
|
||||
void* wasmTrapPC() const;
|
||||
|
|
|
@ -459,26 +459,18 @@ wasm::GenerateFunctionPrologue(MacroAssembler& masm, uint32_t framePushed, IsLea
|
|||
masm.flushBuffer();
|
||||
masm.haltingAlign(CodeAlignment);
|
||||
|
||||
// The table entry falls through into the normal entry after it has checked
|
||||
// the signature.
|
||||
Label normalEntry;
|
||||
|
||||
// Generate table entry. The BytecodeOffset of the trap is fixed up to be
|
||||
// the bytecode offset of the callsite by JitActivation::startWasmTrap.
|
||||
// Generate table entry:
|
||||
offsets->begin = masm.currentOffset();
|
||||
OldTrapDesc trap(trapOffset, Trap::IndirectCallBadSig, 0);
|
||||
switch (sigId.kind()) {
|
||||
case SigIdDesc::Kind::Global: {
|
||||
Register scratch = WasmTableCallScratchReg;
|
||||
masm.loadWasmGlobalPtr(sigId.globalDataOffset(), scratch);
|
||||
masm.branchPtr(Assembler::Condition::Equal, WasmTableCallSigReg, scratch,
|
||||
&normalEntry);
|
||||
masm.wasmTrap(Trap::IndirectCallBadSig, BytecodeOffset(0));
|
||||
masm.branchPtr(Assembler::Condition::NotEqual, WasmTableCallSigReg, scratch, trap);
|
||||
break;
|
||||
}
|
||||
case SigIdDesc::Kind::Immediate: {
|
||||
masm.branch32(Assembler::Condition::Equal, WasmTableCallSigReg, Imm32(sigId.immediate()),
|
||||
&normalEntry);
|
||||
masm.wasmTrap(Trap::IndirectCallBadSig, BytecodeOffset(0));
|
||||
masm.branch32(Assembler::Condition::NotEqual, WasmTableCallSigReg, Imm32(sigId.immediate()), trap);
|
||||
break;
|
||||
}
|
||||
case SigIdDesc::Kind::None:
|
||||
|
@ -491,7 +483,6 @@ wasm::GenerateFunctionPrologue(MacroAssembler& masm, uint32_t framePushed, IsLea
|
|||
|
||||
// Generate normal entry:
|
||||
masm.nopAlign(CodeAlignment);
|
||||
masm.bind(&normalEntry);
|
||||
GenerateCallablePrologue(masm, &offsets->normalEntry);
|
||||
|
||||
// Tiering works as follows. The Code owns a jumpTable, which has one
|
||||
|
@ -1281,21 +1272,20 @@ wasm::LookupFaultingInstance(const ModuleSegment& codeSegment, void* pc, void* f
|
|||
return nullptr;
|
||||
|
||||
size_t offsetInModule = ((uint8_t*)pc) - codeSegment.base();
|
||||
if ((offsetInModule >= codeRange->funcNormalEntry() &&
|
||||
offsetInModule < codeRange->funcNormalEntry() + SetFP) ||
|
||||
(offsetInModule >= codeRange->ret() - PoppedFP &&
|
||||
offsetInModule <= codeRange->ret()))
|
||||
{
|
||||
if (offsetInModule < codeRange->funcNormalEntry() + SetFP)
|
||||
return nullptr;
|
||||
if (offsetInModule >= codeRange->ret() - PoppedFP && offsetInModule <= codeRange->ret())
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Instance* instance = reinterpret_cast<Frame*>(fp)->tls->instance;
|
||||
|
||||
// TODO: In the special case of a cross-instance indirect call bad-signature
|
||||
// fault, fp can point to the caller frame which is in a different
|
||||
// instance/module than pc. This special case should go away when old-style
|
||||
// traps go away and signal handling is reworked.
|
||||
// TODO: when Trap::IndirectCallBadSig is converted away from being an
|
||||
// OldTrap, this could become a release assert again. The reason for the
|
||||
// check is the out-of-line trap stub for the table entry's signature check,
|
||||
// which executes before fp has been updated.
|
||||
//MOZ_RELEASE_ASSERT(&instance->code() == &codeSegment.code());
|
||||
if (&instance->code() != &codeSegment.code())
|
||||
return nullptr;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
|
|
@ -1039,13 +1039,11 @@ HandleFault(PEXCEPTION_POINTERS exception)
|
|||
if (!moduleSegment->code().lookupTrap(pc, &trap, &bytecode))
|
||||
return false;
|
||||
|
||||
activation->startWasmTrap(trap, bytecode.offset, ToRegisterState(context));
|
||||
activation->startWasmTrap(trap, bytecode.offset, pc, ContextToFP(context));
|
||||
*ppc = moduleSegment->trapCode();
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(&instance->code() == &moduleSegment->code());
|
||||
|
||||
if (record->NumberParameters < 2)
|
||||
return false;
|
||||
|
||||
|
@ -1172,11 +1170,9 @@ HandleMachException(JSContext* cx, const ExceptionRequest& request)
|
|||
if (!moduleSegment->code().lookupTrap(pc, &trap, &bytecode))
|
||||
return false;
|
||||
|
||||
activation->startWasmTrap(trap, bytecode.offset, ToRegisterState(&context));
|
||||
activation->startWasmTrap(trap, bytecode.offset, pc, ContextToFP(&context));
|
||||
*ppc = moduleSegment->trapCode();
|
||||
} else {
|
||||
MOZ_RELEASE_ASSERT(&instance->code() == &moduleSegment->code());
|
||||
|
||||
MOZ_ASSERT(request.body.exception == EXC_BAD_ACCESS);
|
||||
if (request.body.codeCnt != 2)
|
||||
return false;
|
||||
|
@ -1398,13 +1394,11 @@ HandleFault(int signum, siginfo_t* info, void* ctx)
|
|||
if (!moduleSegment->code().lookupTrap(pc, &trap, &bytecode))
|
||||
return false;
|
||||
|
||||
activation->startWasmTrap(trap, bytecode.offset, ToRegisterState(context));
|
||||
activation->startWasmTrap(trap, bytecode.offset, pc, ContextToFP(context));
|
||||
*ppc = moduleSegment->trapCode();
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(&instance->code() == &moduleSegment->code());
|
||||
|
||||
uint8_t* faultingAddress = reinterpret_cast<uint8_t*>(info->si_addr);
|
||||
|
||||
// Although it's not strictly necessary, to make sure we're not covering up
|
||||
|
|
|
@ -1730,14 +1730,14 @@ wasm::GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& import
|
|||
case Trap::InvalidConversionToInteger:
|
||||
case Trap::IntegerDivideByZero:
|
||||
case Trap::IndirectCallToNull:
|
||||
case Trap::IndirectCallBadSig:
|
||||
case Trap::ImpreciseSimdConversion:
|
||||
case Trap::StackOverflow:
|
||||
case Trap::ThrowReported:
|
||||
break;
|
||||
// The TODO list of "old" traps to convert to new traps:
|
||||
case Trap::OutOfBounds:
|
||||
case Trap::UnalignedAccess: {
|
||||
case Trap::UnalignedAccess:
|
||||
case Trap::IndirectCallBadSig: {
|
||||
CallableOffsets offsets;
|
||||
if (!GenerateOldTrapExit(masm, trap, &throwLabel, &offsets))
|
||||
return false;
|
||||
|
|
Загрузка…
Ссылка в новой задаче