Bug 1482932 - Baldr: replace unaligned access trap with out of bounds trap (r=lth)
authorLuke Wagner <luke@mozilla.com>
Mon, 20 Aug 2018 11:42:46 -0500
changeset 432428 6129cb421151f9a4f6032a3a2e48a71209850711
parent 432427 14ef4dec612654a0c3ba398bfcefd9436ea4abf6
child 432429 2e949e5a9a62d0db0d33833e1e875f12f2969ac4
push id106732
push userlwagner@mozilla.com
push dateMon, 20 Aug 2018 16:44:02 +0000
treeherdermozilla-inbound@6129cb421151 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslth
bugs1482932
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1482932 - Baldr: replace unaligned access trap with out of bounds trap (r=lth)
js/src/wasm/WasmBuiltins.cpp
js/src/wasm/WasmCode.cpp
js/src/wasm/WasmCode.h
js/src/wasm/WasmFrameIter.cpp
js/src/wasm/WasmGenerator.cpp
js/src/wasm/WasmModule.h
js/src/wasm/WasmSignalHandlers.cpp
js/src/wasm/WasmStubs.cpp
js/src/wasm/WasmTypes.cpp
js/src/wasm/WasmTypes.h
--- a/js/src/wasm/WasmBuiltins.cpp
+++ b/js/src/wasm/WasmBuiltins.cpp
@@ -284,23 +284,16 @@ WasmHandleTrap()
       case Trap::Limit:
         break;
     }
 
     MOZ_CRASH("unexpected trap");
 }
 
 static void
-WasmReportUnalignedAccess()
-{
-    JSContext* cx = TlsContext.get();
-    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_UNALIGNED_ACCESS);
-}
-
-static void
 WasmReportInt64JSCall()
 {
     JSContext* cx = TlsContext.get();
     JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_I64_TYPE);
 }
 
 static int32_t
 CoerceInPlace_ToInt32(Value* rawVal)
@@ -505,19 +498,16 @@ AddressOf(SymbolicAddress imm, ABIFuncti
         *abiType = Args_General0;
         return FuncCast(WasmHandleDebugTrap, *abiType);
       case SymbolicAddress::HandleThrow:
         *abiType = Args_General0;
         return FuncCast(WasmHandleThrow, *abiType);
       case SymbolicAddress::HandleTrap:
         *abiType = Args_General0;
         return FuncCast(WasmHandleTrap, *abiType);
-      case SymbolicAddress::ReportUnalignedAccess:
-        *abiType = Args_General0;
-        return FuncCast(WasmReportUnalignedAccess, *abiType);
       case SymbolicAddress::ReportInt64JSCall:
         *abiType = Args_General0;
         return FuncCast(WasmReportInt64JSCall, *abiType);
       case SymbolicAddress::CallImport_Void:
         *abiType = Args_General4;
         return FuncCast(Instance::callImport_void, *abiType);
       case SymbolicAddress::CallImport_I32:
         *abiType = Args_General4;
@@ -685,17 +675,16 @@ bool
 wasm::NeedsBuiltinThunk(SymbolicAddress sym)
 {
     // Some functions don't want to a thunk, because they already have one or
     // they don't have frame info.
     switch (sym) {
       case SymbolicAddress::HandleDebugTrap:          // GenerateDebugTrapStub
       case SymbolicAddress::HandleThrow:              // GenerateThrowStub
       case SymbolicAddress::HandleTrap:               // GenerateTrapExit
-      case SymbolicAddress::ReportUnalignedAccess:    // GenerateUnalignedExit
       case SymbolicAddress::CallImport_Void:          // GenerateImportInterpExit
       case SymbolicAddress::CallImport_I32:
       case SymbolicAddress::CallImport_I64:
       case SymbolicAddress::CallImport_F64:
       case SymbolicAddress::CallImport_Ref:
       case SymbolicAddress::CoerceInPlace_ToInt32:    // GenerateImportJitExit
       case SymbolicAddress::CoerceInPlace_ToNumber:
 #if defined(JS_CODEGEN_MIPS32)
--- a/js/src/wasm/WasmCode.cpp
+++ b/js/src/wasm/WasmCode.cpp
@@ -273,17 +273,16 @@ SendCodeRangesToProfiler(const ModuleSeg
 }
 
 ModuleSegment::ModuleSegment(Tier tier,
                              UniqueCodeBytes codeBytes,
                              uint32_t codeLength,
                              const LinkDataTier& linkData)
   : CodeSegment(std::move(codeBytes), codeLength, CodeSegment::Kind::Module),
     tier_(tier),
-    unalignedAccessCode_(base() + linkData.unalignedAccessOffset),
     trapCode_(base() + linkData.trapOffset)
 {
 }
 
 /* static */ UniqueModuleSegment
 ModuleSegment::create(Tier tier, MacroAssembler& masm, const LinkDataTier& linkData)
 {
     uint32_t codeLength = masm.bytesNeeded();
--- a/js/src/wasm/WasmCode.h
+++ b/js/src/wasm/WasmCode.h
@@ -134,17 +134,16 @@ class CodeSegment
 
 // A wasm ModuleSegment owns the allocated executable code for a wasm module.
 
 typedef UniquePtr<ModuleSegment> UniqueModuleSegment;
 
 class ModuleSegment : public CodeSegment
 {
     const Tier      tier_;
-    uint8_t* const  unalignedAccessCode_;
     uint8_t* const  trapCode_;
 
   public:
     ModuleSegment(Tier tier,
                   UniqueCodeBytes codeBytes,
                   uint32_t codeLength,
                   const LinkDataTier& linkData);
 
@@ -160,17 +159,16 @@ class ModuleSegment : public CodeSegment
                     const LinkDataTier& linkData,
                     const Metadata& metadata,
                     const MetadataTier& metadataTier);
 
     Tier tier() const { return tier_; }
 
     // Pointers to stubs to which PC is redirected from the signal-handler.
 
-    uint8_t* unalignedAccessCode() const { return unalignedAccessCode_; }
     uint8_t* trapCode() const { return trapCode_; }
 
     // Structured clone support:
 
     size_t serializedSize() const;
     uint8_t* serialize(uint8_t* cursor, const LinkDataTier& linkData) const;
     static const uint8_t* deserialize(const uint8_t* cursor, const LinkDataTier& linkData,
                                       UniqueModuleSegment* segment);
--- a/js/src/wasm/WasmFrameIter.cpp
+++ b/js/src/wasm/WasmFrameIter.cpp
@@ -795,17 +795,16 @@ ProfilingFrameIterator::initFromExitFP(c
         callerFP_ = fp->callerFP;
         AssertMatchesCallSite(callerPC_, callerFP_);
         break;
       case CodeRange::ImportJitExit:
       case CodeRange::ImportInterpExit:
       case CodeRange::BuiltinThunk:
       case CodeRange::TrapExit:
       case CodeRange::DebugTrap:
-      case CodeRange::UnalignedExit:
       case CodeRange::Throw:
       case CodeRange::FarJumpIsland:
         MOZ_CRASH("Unexpected CodeRange kind");
     }
 
     MOZ_ASSERT(!done());
 }
 
@@ -983,17 +982,16 @@ js::wasm::StartUnwinding(const RegisterS
             fixedPC = pc;
             fixedFP = fp;
             *unwoundCaller = false;
             AssertMatchesCallSite(fp->returnAddress, fp->callerFP);
             break;
         }
         break;
       case CodeRange::TrapExit:
-      case CodeRange::UnalignedExit:
         // These code stubs execute after the prologue/epilogue have completed
         // so pc/fp contains the right values here.
         fixedPC = pc;
         fixedFP = fp;
         *unwoundCaller = false;
         AssertMatchesCallSite(fp->returnAddress, fp->callerFP);
         break;
       case CodeRange::InterpEntry:
@@ -1134,17 +1132,16 @@ ProfilingFrameIterator::operator++()
 
     switch (codeRange_->kind()) {
       case CodeRange::Function:
       case CodeRange::ImportJitExit:
       case CodeRange::ImportInterpExit:
       case CodeRange::BuiltinThunk:
       case CodeRange::TrapExit:
       case CodeRange::DebugTrap:
-      case CodeRange::UnalignedExit:
       case CodeRange::FarJumpIsland:
         stackAddress_ = callerFP_;
         callerPC_ = callerFP_->returnAddress;
         AssertMatchesCallSite(callerPC_, callerFP_->callerFP);
         callerFP_ = callerFP_->callerFP;
         break;
       case CodeRange::InterpEntry:
         MOZ_CRASH("should have had null caller fp");
@@ -1160,17 +1157,16 @@ ProfilingFrameIterator::operator++()
 static const char*
 ThunkedNativeToDescription(SymbolicAddress func)
 {
     MOZ_ASSERT(NeedsBuiltinThunk(func));
     switch (func) {
       case SymbolicAddress::HandleDebugTrap:
       case SymbolicAddress::HandleThrow:
       case SymbolicAddress::HandleTrap:
-      case SymbolicAddress::ReportUnalignedAccess:
       case SymbolicAddress::CallImport_Void:
       case SymbolicAddress::CallImport_I32:
       case SymbolicAddress::CallImport_I64:
       case SymbolicAddress::CallImport_F64:
       case SymbolicAddress::CallImport_Ref:
       case SymbolicAddress::CoerceInPlace_ToInt32:
       case SymbolicAddress::CoerceInPlace_ToNumber:
         MOZ_ASSERT(!NeedsBuiltinThunk(func), "not in sync with NeedsBuiltinThunk");
@@ -1315,17 +1311,16 @@ ProfilingFrameIterator::label() const
       case CodeRange::Function:          return code_->profilingLabel(codeRange_->funcIndex());
       case CodeRange::InterpEntry:       MOZ_CRASH("should be an ExitReason");
       case CodeRange::JitEntry:          return "fast entry trampoline (in wasm)";
       case CodeRange::ImportJitExit:     return importJitDescription;
       case CodeRange::BuiltinThunk:      return builtinNativeDescription;
       case CodeRange::ImportInterpExit:  return importInterpDescription;
       case CodeRange::TrapExit:          return trapDescription;
       case CodeRange::DebugTrap:         return debugTrapDescription;
-      case CodeRange::UnalignedExit:     return "unaligned trap stub (in wasm)";
       case CodeRange::FarJumpIsland:     return "interstitial (in wasm)";
       case CodeRange::Throw:             MOZ_CRASH("does not have a frame");
     }
 
     MOZ_CRASH("bad code range kind");
 }
 
 Instance*
--- a/js/src/wasm/WasmGenerator.cpp
+++ b/js/src/wasm/WasmGenerator.cpp
@@ -508,20 +508,16 @@ ModuleGenerator::noteCodeRange(uint32_t 
         break;
       case CodeRange::ImportInterpExit:
         metadataTier_->funcImports[codeRange.funcIndex()].initInterpExitOffset(codeRange.begin());
         break;
       case CodeRange::DebugTrap:
         MOZ_ASSERT(!debugTrapCodeOffset_);
         debugTrapCodeOffset_ = codeRange.begin();
         break;
-      case CodeRange::UnalignedExit:
-        MOZ_ASSERT(!linkDataTier_->unalignedAccessOffset);
-        linkDataTier_->unalignedAccessOffset = codeRange.begin();
-        break;
       case CodeRange::TrapExit:
         MOZ_ASSERT(!linkDataTier_->trapOffset);
         linkDataTier_->trapOffset = codeRange.begin();
         break;
       case CodeRange::Throw:
         // Jumped to by other stubs, so nothing to do.
         break;
       case CodeRange::FarJumpIsland:
--- a/js/src/wasm/WasmModule.h
+++ b/js/src/wasm/WasmModule.h
@@ -38,17 +38,16 @@ struct CompileArgs;
 //
 // LinkData is built incrementally by ModuleGenerator and then stored immutably
 // in Module. LinkData is distinct from Metadata in that LinkData is owned and
 // destroyed by the Module since it is not needed after instantiation; Metadata
 // is needed at runtime.
 
 struct LinkDataTierCacheablePod
 {
-    uint32_t unalignedAccessOffset = 0;
     uint32_t trapOffset = 0;
 
     LinkDataTierCacheablePod() = default;
 };
 
 struct LinkDataTier : LinkDataTierCacheablePod
 {
     const Tier tier;
--- a/js/src/wasm/WasmSignalHandlers.cpp
+++ b/js/src/wasm/WasmSignalHandlers.cpp
@@ -1310,28 +1310,16 @@ HandleFault(int signum, siginfo_t* info,
 #else
         return false;
 #endif
     } else {
         if (!IsHeapAccessAddress(*instance, faultingAddress))
             return false;
     }
 
-#ifdef JS_CODEGEN_ARM
-    if (signum == SIGBUS) {
-        // TODO: We may see a bus error for something that is an unaligned access that
-        // partly overlaps the end of the heap.  In this case, it is an out-of-bounds
-        // error and we should signal that properly, but to do so we must inspect
-        // the operand of the failed access.
-        activation->startWasmTrap(wasm::Trap::UnalignedAccess, 0, ToRegisterState(context));
-        *ppc = moduleSegment->unalignedAccessCode();
-        return true;
-    }
-#endif
-
     return HandleOutOfBounds(context, pc, faultingAddress, moduleSegment, *instance, activation, ppc);
 }
 
 static struct sigaction sPrevSEGVHandler;
 static struct sigaction sPrevSIGBUSHandler;
 static struct sigaction sPrevWasmTrapHandler;
 
 static void
--- a/js/src/wasm/WasmStubs.cpp
+++ b/js/src/wasm/WasmStubs.cpp
@@ -1593,52 +1593,16 @@ GenerateTrapExit(MacroAssembler& masm, L
     masm.abiret();
 #else
     masm.ret();
 #endif
 
     return FinishOffsets(masm, offsets);
 }
 
-// Generate a stub which is only used by the signal handlers to handle out of
-// bounds access by Atomics and unaligned accesses on ARM. This stub is
-// executed by direct PC transfer from the faulting memory access and thus the
-// stack depth is unknown. Since JitActivation::packedExitFP() is not set
-// before calling the error reporter, the current wasm activation will be lost.
-// This stub should be removed when Atomics are moved to wasm and given proper
-// traps and when we use a non-faulting strategy for unaligned ARM access.
-static bool
-GenerateGenericMemoryAccessTrap(MacroAssembler& masm, SymbolicAddress reporter, Label* throwLabel,
-                                Offsets* offsets)
-{
-    AssertExpectedSP(masm);
-    masm.haltingAlign(CodeAlignment);
-
-    offsets->begin = masm.currentOffset();
-
-    // 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)));
-    if (ShadowStackSpace)
-        masm.subFromStackPtr(Imm32(ShadowStackSpace));
-
-    masm.call(reporter);
-    masm.jump(throwLabel);
-
-    return FinishOffsets(masm, offsets);
-}
-
-static bool
-GenerateUnalignedExit(MacroAssembler& masm, Label* throwLabel, Offsets* offsets)
-{
-    return GenerateGenericMemoryAccessTrap(masm, SymbolicAddress::ReportUnalignedAccess, throwLabel,
-                                           offsets);
-}
-
 // Generate a stub that restores the stack pointer to what it was on entry to
 // the wasm activation, sets the return register to 'false' and then executes a
 // return which will return from this wasm activation to the caller. This stub
 // should only be called after the caller has reported an error.
 static bool
 GenerateThrowStub(MacroAssembler& masm, Label* throwLabel, Offsets* offsets)
 {
     AssertExpectedSP(masm);
@@ -1800,21 +1764,16 @@ wasm::GenerateStubs(const ModuleEnvironm
             return false;
         }
     }
 
     JitSpew(JitSpew_Codegen, "# Emitting wasm exit stubs");
 
     Offsets offsets;
 
-    if (!GenerateUnalignedExit(masm, &throwLabel, &offsets))
-        return false;
-    if (!code->codeRanges.emplaceBack(CodeRange::UnalignedExit, offsets))
-        return false;
-
     if (!GenerateTrapExit(masm, &throwLabel, &offsets))
         return false;
     if (!code->codeRanges.emplaceBack(CodeRange::TrapExit, offsets))
         return false;
 
     CallableOffsets callableOffsets;
     if (!GenerateDebugTrapStub(masm, &throwLabel, &callableOffsets))
         return false;
--- a/js/src/wasm/WasmTypes.cpp
+++ b/js/src/wasm/WasmTypes.cpp
@@ -859,17 +859,16 @@ CodeRange::CodeRange(Kind kind, Offsets 
     end_(offsets.end),
     kind_(kind)
 {
     MOZ_ASSERT(begin_ <= end_);
     PodZero(&u);
 #ifdef DEBUG
     switch (kind_) {
       case FarJumpIsland:
-      case UnalignedExit:
       case TrapExit:
       case Throw:
         break;
       default:
         MOZ_CRASH("should use more specific constructor");
     }
 #endif
 }
--- a/js/src/wasm/WasmTypes.h
+++ b/js/src/wasm/WasmTypes.h
@@ -1442,18 +1442,16 @@ class CodeRange
         InterpEntry,       // calls into wasm from C++
         JitEntry,          // calls into wasm from jit code
         ImportInterpExit,  // slow-path calling from wasm into C++ interp
         ImportJitExit,     // fast-path calling from wasm into jit code
         BuiltinThunk,      // fast-path calling from wasm into a C++ native
         TrapExit,          // calls C++ to report and jumps to throw stub
         DebugTrap,         // calls C++ to handle debug event
         FarJumpIsland,     // inserted to connect otherwise out-of-range insns
-        UnalignedExit,     // stub jumped to by wasm Atomics and non-standard
-                           // ARM unaligned trap
         Throw              // special stack-unwinding stub jumped to by other stubs
     };
 
   private:
     // All fields are treated as cacheable POD:
     uint32_t begin_;
     uint32_t ret_;
     uint32_t end_;
@@ -1756,17 +1754,16 @@ enum class SymbolicAddress
     NearbyIntF,
     ExpD,
     LogD,
     PowD,
     ATan2D,
     HandleDebugTrap,
     HandleThrow,
     HandleTrap,
-    ReportUnalignedAccess,
     ReportInt64JSCall,
     CallImport_Void,
     CallImport_I32,
     CallImport_I64,
     CallImport_F64,
     CallImport_Ref,
     CoerceInPlace_ToInt32,
     CoerceInPlace_ToNumber,