Backed out changeset a95360977f76 (bug 1428453) for arm build bustage

This commit is contained in:
Dorel Luca 2018-02-19 23:18:06 +02:00
Родитель c921526073
Коммит c241a94698
7 изменённых файлов: 63 добавлений и 85 удалений

Просмотреть файл

@ -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 // Inherit the frame depth of the trap site. This value is captured
// by the wasm::CallSite to allow unwinding this frame. // by the wasm::CallSite to allow unwinding this frame.
setFramePushed(site.framePushed); setFramePushed(site.framePushed);
@ -3320,6 +3332,7 @@ MacroAssembler::wasmEmitOldTrapOutOfLineCode()
// the trapping instruction. // the trapping instruction.
wasm::CallSiteDesc desc(site.offset, wasm::CallSiteDesc::OldTrapExit); wasm::CallSiteDesc desc(site.offset, wasm::CallSiteDesc::OldTrapExit);
call(desc, site.trap); call(desc, site.trap);
}
#ifdef DEBUG #ifdef DEBUG
// Traps do not return, so no need to freeStack(). // 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(); const wasm::ModuleSegment* moduleSegment = segment->asModule();
wasm::Instance* instance = wasm::LookupFaultingInstance(*moduleSegment, pc, fp); wasm::Instance* instance = wasm::LookupFaultingInstance(*moduleSegment, pc, fp);
if (!instance) if (!instance || !instance->memoryAccessInGuardRegion((uint8_t*)addr, numBytes))
return false;
MOZ_RELEASE_ASSERT(&instance->code() == &codeSegment.code());
if (!instance->memoryAccessInGuardRegion((uint8_t*)addr, numBytes))
return false; return false;
const wasm::MemoryAccess* memoryAccess = instance->code().lookupMemoryAccess(pc); const wasm::MemoryAccess* memoryAccess = instance->code().lookupMemoryAccess(pc);

Просмотреть файл

@ -1823,27 +1823,13 @@ jit::JitActivation::wasmInterruptResumePC() const
} }
void void
jit::JitActivation::startWasmTrap(wasm::Trap trap, uint32_t bytecodeOffset, jit::JitActivation::startWasmTrap(wasm::Trap trap, uint32_t bytecodeOffset, void* pc, void* fp)
const wasm::RegisterState& state)
{ {
bool unwound; MOZ_ASSERT(pc);
wasm::UnwindState unwindState; MOZ_ASSERT(fp);
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();
cx_->runtime()->wasmUnwindData.ref().construct<wasm::TrapData>(pc, trap, bytecodeOffset); cx_->runtime()->wasmUnwindData.ref().construct<wasm::TrapData>(pc, trap, bytecodeOffset);
setWasmExitFP(fp); setWasmExitFP((wasm::Frame*)fp);
} }
void void

Просмотреть файл

@ -1667,13 +1667,13 @@ class JitActivation : public Activation
// when the interrupt is handled. // when the interrupt is handled.
// Returns true iff we've entered interrupted state. // Returns true iff we've entered interrupted state.
bool startWasmInterrupt(const wasm::RegisterState& state); bool startWasmInterrupt(const JS::ProfilingFrameIterator::RegisterState& state);
void finishWasmInterrupt(); void finishWasmInterrupt();
bool isWasmInterrupted() const; bool isWasmInterrupted() const;
void* wasmInterruptUnwindPC() const; void* wasmInterruptUnwindPC() const;
void* wasmInterruptResumePC() 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(); void finishWasmTrap();
bool isWasmTrapping() const; bool isWasmTrapping() const;
void* wasmTrapPC() const; void* wasmTrapPC() const;

Просмотреть файл

@ -459,26 +459,18 @@ wasm::GenerateFunctionPrologue(MacroAssembler& masm, uint32_t framePushed, IsLea
masm.flushBuffer(); masm.flushBuffer();
masm.haltingAlign(CodeAlignment); masm.haltingAlign(CodeAlignment);
// The table entry falls through into the normal entry after it has checked // Generate table entry:
// 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.
offsets->begin = masm.currentOffset(); offsets->begin = masm.currentOffset();
OldTrapDesc trap(trapOffset, Trap::IndirectCallBadSig, 0);
switch (sigId.kind()) { switch (sigId.kind()) {
case SigIdDesc::Kind::Global: { case SigIdDesc::Kind::Global: {
Register scratch = WasmTableCallScratchReg; Register scratch = WasmTableCallScratchReg;
masm.loadWasmGlobalPtr(sigId.globalDataOffset(), scratch); masm.loadWasmGlobalPtr(sigId.globalDataOffset(), scratch);
masm.branchPtr(Assembler::Condition::Equal, WasmTableCallSigReg, scratch, masm.branchPtr(Assembler::Condition::NotEqual, WasmTableCallSigReg, scratch, trap);
&normalEntry);
masm.wasmTrap(Trap::IndirectCallBadSig, BytecodeOffset(0));
break; break;
} }
case SigIdDesc::Kind::Immediate: { case SigIdDesc::Kind::Immediate: {
masm.branch32(Assembler::Condition::Equal, WasmTableCallSigReg, Imm32(sigId.immediate()), masm.branch32(Assembler::Condition::NotEqual, WasmTableCallSigReg, Imm32(sigId.immediate()), trap);
&normalEntry);
masm.wasmTrap(Trap::IndirectCallBadSig, BytecodeOffset(0));
break; break;
} }
case SigIdDesc::Kind::None: case SigIdDesc::Kind::None:
@ -491,7 +483,6 @@ wasm::GenerateFunctionPrologue(MacroAssembler& masm, uint32_t framePushed, IsLea
// Generate normal entry: // Generate normal entry:
masm.nopAlign(CodeAlignment); masm.nopAlign(CodeAlignment);
masm.bind(&normalEntry);
GenerateCallablePrologue(masm, &offsets->normalEntry); GenerateCallablePrologue(masm, &offsets->normalEntry);
// Tiering works as follows. The Code owns a jumpTable, which has one // 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; return nullptr;
size_t offsetInModule = ((uint8_t*)pc) - codeSegment.base(); size_t offsetInModule = ((uint8_t*)pc) - codeSegment.base();
if ((offsetInModule >= codeRange->funcNormalEntry() && if (offsetInModule < codeRange->funcNormalEntry() + SetFP)
offsetInModule < codeRange->funcNormalEntry() + SetFP) || return nullptr;
(offsetInModule >= codeRange->ret() - PoppedFP && if (offsetInModule >= codeRange->ret() - PoppedFP && offsetInModule <= codeRange->ret())
offsetInModule <= codeRange->ret()))
{
return nullptr; return nullptr;
}
Instance* instance = reinterpret_cast<Frame*>(fp)->tls->instance; Instance* instance = reinterpret_cast<Frame*>(fp)->tls->instance;
// TODO: In the special case of a cross-instance indirect call bad-signature // TODO: when Trap::IndirectCallBadSig is converted away from being an
// fault, fp can point to the caller frame which is in a different // OldTrap, this could become a release assert again. The reason for the
// instance/module than pc. This special case should go away when old-style // check is the out-of-line trap stub for the table entry's signature check,
// traps go away and signal handling is reworked. // which executes before fp has been updated.
//MOZ_RELEASE_ASSERT(&instance->code() == &codeSegment.code()); //MOZ_RELEASE_ASSERT(&instance->code() == &codeSegment.code());
if (&instance->code() != &codeSegment.code())
return nullptr;
return instance; return instance;
} }

Просмотреть файл

@ -1039,13 +1039,11 @@ HandleFault(PEXCEPTION_POINTERS exception)
if (!moduleSegment->code().lookupTrap(pc, &trap, &bytecode)) if (!moduleSegment->code().lookupTrap(pc, &trap, &bytecode))
return false; return false;
activation->startWasmTrap(trap, bytecode.offset, ToRegisterState(context)); activation->startWasmTrap(trap, bytecode.offset, pc, ContextToFP(context));
*ppc = moduleSegment->trapCode(); *ppc = moduleSegment->trapCode();
return true; return true;
} }
MOZ_RELEASE_ASSERT(&instance->code() == &moduleSegment->code());
if (record->NumberParameters < 2) if (record->NumberParameters < 2)
return false; return false;
@ -1172,11 +1170,9 @@ HandleMachException(JSContext* cx, const ExceptionRequest& request)
if (!moduleSegment->code().lookupTrap(pc, &trap, &bytecode)) if (!moduleSegment->code().lookupTrap(pc, &trap, &bytecode))
return false; return false;
activation->startWasmTrap(trap, bytecode.offset, ToRegisterState(&context)); activation->startWasmTrap(trap, bytecode.offset, pc, ContextToFP(&context));
*ppc = moduleSegment->trapCode(); *ppc = moduleSegment->trapCode();
} else { } else {
MOZ_RELEASE_ASSERT(&instance->code() == &moduleSegment->code());
MOZ_ASSERT(request.body.exception == EXC_BAD_ACCESS); MOZ_ASSERT(request.body.exception == EXC_BAD_ACCESS);
if (request.body.codeCnt != 2) if (request.body.codeCnt != 2)
return false; return false;
@ -1398,13 +1394,11 @@ HandleFault(int signum, siginfo_t* info, void* ctx)
if (!moduleSegment->code().lookupTrap(pc, &trap, &bytecode)) if (!moduleSegment->code().lookupTrap(pc, &trap, &bytecode))
return false; return false;
activation->startWasmTrap(trap, bytecode.offset, ToRegisterState(context)); activation->startWasmTrap(trap, bytecode.offset, pc, ContextToFP(context));
*ppc = moduleSegment->trapCode(); *ppc = moduleSegment->trapCode();
return true; return true;
} }
MOZ_RELEASE_ASSERT(&instance->code() == &moduleSegment->code());
uint8_t* faultingAddress = reinterpret_cast<uint8_t*>(info->si_addr); uint8_t* faultingAddress = reinterpret_cast<uint8_t*>(info->si_addr);
// Although it's not strictly necessary, to make sure we're not covering up // 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::InvalidConversionToInteger:
case Trap::IntegerDivideByZero: case Trap::IntegerDivideByZero:
case Trap::IndirectCallToNull: case Trap::IndirectCallToNull:
case Trap::IndirectCallBadSig:
case Trap::ImpreciseSimdConversion: case Trap::ImpreciseSimdConversion:
case Trap::StackOverflow: case Trap::StackOverflow:
case Trap::ThrowReported: case Trap::ThrowReported:
break; break;
// The TODO list of "old" traps to convert to new traps: // The TODO list of "old" traps to convert to new traps:
case Trap::OutOfBounds: case Trap::OutOfBounds:
case Trap::UnalignedAccess: { case Trap::UnalignedAccess:
case Trap::IndirectCallBadSig: {
CallableOffsets offsets; CallableOffsets offsets;
if (!GenerateOldTrapExit(masm, trap, &throwLabel, &offsets)) if (!GenerateOldTrapExit(masm, trap, &throwLabel, &offsets))
return false; return false;