Closed Bug 1268910 Opened 9 years ago Closed 8 years ago

Baldr: trap on edge cases for arithmetic operations

Categories

(Core :: JavaScript Engine: JIT, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: bbouvier, Assigned: bbouvier)

References

Details

Attachments

(5 files, 3 obsolete files)

e.g. I32Div should trap when we try to divide by zero. We should also find a way to generalize traps, so we don't have to create a stub for each of them, and just generate a reason that we pass to the trap handler.
Blocks: wasm
Status: NEW → ASSIGNED
Attached patch traps wip (obsolete) — Splinter Review
Just asking feedback at the moment, to validate the approach. I don't think it's fine to generate an error stub inline, so instead we could have a JumpTarget::Trap, and we'd push the reason onto the stack first in MacroAssembler::wasmTrap; and would read it from the error stub (that is, the target of JumpTarget::Trap) later. How does that sound?
Attachment #8747110 - Flags: feedback?(luke)
Comment on attachment 8747110 [details] [diff] [review] traps wip Review of attachment 8747110 [details] [diff] [review]: ----------------------------------------------------------------- Yes, this definitely looks good! IIUC, you're saying the patch would *not* use callWithABI which I think is good b/c I think it doesn't work for wasm (in particular, wrt profiling).
Attachment #8747110 - Flags: feedback?(luke) → feedback+
Attached patch traps.patch (obsolete) — Splinter Review
Attachment #8747110 - Attachment is obsolete: true
Attachment #8747768 - Flags: review?(luke)
Attached patch wip-div.patch (obsolete) — Splinter Review
And this is what it looks like to add a new trap thereafter.
Comment on attachment 8747768 [details] [diff] [review] traps.patch Review of attachment 8747768 [details] [diff] [review]: ----------------------------------------------------------------- ::: js/src/asmjs/WasmStubs.cpp @@ +869,5 @@ > + > + // sp can be anything at this point, so ensure it is aligned when calling > + // into C++. We unconditionally jump to throw so don't worry about > + // restoring sp. > + masm.andToStackPtr(Imm32(~(ABIStackAlignment - 1))); Pre-existing from GenerateErrorStub (which I'm hoping we can wholly replace by this function), but I think, after masking the stack pointer, you need to further subtract ShadowStackSpace (which is bytes above the stack pointer that may be clobbered by the callee). (See GenerateInterruptStub.) @@ +879,5 @@ > + if (i->kind() == ABIArg::GPR) { > + if (WasmTrapStubArgReg != i->gpr()) > + masm.move32(WasmTrapStubArgReg, i->gpr()); > + } else { > + masm.storePtr(WasmTrapStubArgReg, I think this should be store32. @@ +937,5 @@ > return GenerateErrorStub(masm, SymbolicAddress::OnOutOfBounds); > case JumpTarget::BadIndirectCall: > return GenerateErrorStub(masm, SymbolicAddress::BadIndirectCall); > + case JumpTarget::Trap: > + return GenerateTrapStub(masm); Can you use GenerateTrapStub for the other two as well, removing GenerateErrorStub? ::: js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp @@ +2577,5 @@ > > + Label done; > + if (gen->compilingAsmJS()) { > + masm.j(Assembler::Equal, &done); > + masm.wasmTrap(wasm::Trap::ImpreciseSimdConversion); Can you give wasmTrap a condition? Otherwise, this change deoptimizes the common case where there is no trap.
Attachment #8747768 - Flags: review?(luke) → review+
Thank you for the review! (In reply to Luke Wagner [:luke] from comment #5) > Comment on attachment 8747768 [details] [diff] [review] > traps.patch > > Review of attachment 8747768 [details] [diff] [review]: > ----------------------------------------------------------------- > > ::: js/src/asmjs/WasmStubs.cpp > @@ +869,5 @@ > > + > > + // sp can be anything at this point, so ensure it is aligned when calling > > + // into C++. We unconditionally jump to throw so don't worry about > > + // restoring sp. > > + masm.andToStackPtr(Imm32(~(ABIStackAlignment - 1))); > > Pre-existing from GenerateErrorStub (which I'm hoping we can wholly replace > by this function), but I think, after masking the stack pointer, you need to > further subtract ShadowStackSpace (which is bytes above the stack pointer > that may be clobbered by the callee). (See GenerateInterruptStub.) Ha! Could it be somehow related to bug 1267441, which happens only on win x64, which iirc is the only platform that has shadow stack space? The out of memory stub uses the GenerateErrorStub, so maybe the stack gets corrupted after the call and we don't jump to the throw handler, or go there with a stack that sometimes is wrong? > @@ +937,5 @@ > > return GenerateErrorStub(masm, SymbolicAddress::OnOutOfBounds); > > case JumpTarget::BadIndirectCall: > > return GenerateErrorStub(masm, SymbolicAddress::BadIndirectCall); > > + case JumpTarget::Trap: > > + return GenerateTrapStub(masm); > > Can you use GenerateTrapStub for the other two as well, removing > GenerateErrorStub? I've tried this first, but the stubs entries are directly referenced from inline code (e.g. the out of bounds stubs is the one we redirect to from the OOB signal handler, for OOB SIMD accesses), and it makes things more complicated. I can look into it in another patch, though. > > ::: js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp > @@ +2577,5 @@ > > > > + Label done; > > + if (gen->compilingAsmJS()) { > > + masm.j(Assembler::Equal, &done); > > + masm.wasmTrap(wasm::Trap::ImpreciseSimdConversion); > > Can you give wasmTrap a condition? Otherwise, this change deoptimizes the > common case where there is no trap. I've done that: although there is no Assembler::Condition::Always on x86 and x64, so I made two variants (one with Assembler::Condition, one without it).
Actually, now that I think about it, wasmTrap() would be more flexible if, in addition taking a Condition, it was a single conditional-branch instruction. Otherwise you can't use the branch to either jump-to-trap or fallthrough-to-valid since the move is executed either way. Rather, I think there should be 1 jump target per trap and each jump target stores the Trap code and calls a single C++ function.
Attached patch traps.patchSplinter Review
Agreed on irc that the required changes are bigger than expected so another look would be good.
Attachment #8747768 - Attachment is obsolete: true
Attachment #8748253 - Flags: review?(luke)
This implements the traps on integer (signed or unsigned) div/mod: - div/mod by zero - div INTMIN by -1 As far as I can tell from the tests, there are no other traps for any arithmetic operations, be it on integers or non-integer operations: is that correct? With this patch, the spec test i32.wast passes in our implementation.
Attachment #8747769 - Attachment is obsolete: true
Attachment #8748258 - Flags: review?(sunfish)
Comment on attachment 8748258 [details] [diff] [review] trap-div-mod.patch Review of attachment 8748258 [details] [diff] [review]: ----------------------------------------------------------------- Looks good!
Attachment #8748258 - Flags: review?(sunfish) → review+
Comment on attachment 8748253 [details] [diff] [review] traps.patch Review of attachment 8748253 [details] [diff] [review]: ----------------------------------------------------------------- Great, thanks! ::: js/src/asmjs/WasmStubs.cpp @@ +869,5 @@ > + // into C++. We unconditionally jump to throw so don't worry about > + // restoring sp. > + masm.andToStackPtr(Imm32(~(ABIStackAlignment - 1))); > + if (ShadowStackSpace) > + masm.subFromStackPtr(Imm32(ShadowStackSpace)); Could you fix up GenerateErrorStub as well?
Attachment #8748253 - Flags: review?(luke) → review+
Attached patch oobstub.patchSplinter Review
Actually the OOB stub is trivial to remove.
Attachment #8748574 - Flags: review?(luke)
Comment on attachment 8748574 [details] [diff] [review] oobstub.patch Review of attachment 8748574 [details] [diff] [review]: ----------------------------------------------------------------- Great! ::: js/src/asmjs/WasmStubs.cpp @@ +935,2 @@ > case JumpTarget::BadIndirectCall: > return GenerateErrorStub(masm, SymbolicAddress::BadIndirectCall); Ah, and this straggler will probably get removed or rejiggered with the heterogeneous table work. ::: js/src/asmjs/WasmTypes.h @@ +643,5 @@ > // Integer division by zero. > IntegerDivideByZero, > > + // (asm.js only) out of bounds on SIMD and atomic memory accesses. > + OutOfBounds, This will be exercised by wasm load/store oob too, so I'd tweak the comment and put it up with the others.
Attachment #8748574 - Flags: review?(luke) → review+
As said on IRC, I'm worried about one thing: if we call from an inline stub we can jump to, will profiling work? Testing suggests it does, but this might be our tests don't cover this.
Attachment #8748654 - Flags: review?(luke)
Comment on attachment 8748654 [details] [diff] [review] badindirectcall.patch Review of attachment 8748654 [details] [diff] [review]: ----------------------------------------------------------------- Even better! Good observation. ::: js/src/asmjs/WasmTypes.h @@ +648,2 @@ > // (asm.js only) out of bounds on SIMD and atomic memory accesses. > OutOfBounds, In my previous comment, I didn't mean that the whole error would go away, just how we exercise it. I think the target impl scheme will be to check the signature in the callee which will jump to this same stub. So I don't think it's (temporary) and I'd give it a proper comment and move it up with the others.
Attachment #8748654 - Flags: review?(luke) → review+
Attached patch addendum.patchSplinter Review
And an addendum, so that unsigned div/mod by zero don't get constant folded into the wrong thing. This also adds tests so that i32 edge cases are handled for the constant value cases; in particular, this ensures that div_s/mod_s are not getting DCE'd.
Attachment #8750297 - Flags: review?(sunfish)
Comment on attachment 8750297 [details] [diff] [review] addendum.patch Review of attachment 8750297 [details] [diff] [review]: ----------------------------------------------------------------- Looks good.
Attachment #8750297 - Flags: review?(sunfish) → review+
Forgot to remove leave-open after the last push.
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
Keywords: leave-open
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: