Bug 1268024: Add an unaligned access trap; r=luke

MozReview-Commit-ID: HvAF3lvlfw3

--HG--
extra : rebase_source : 4c326dd9af59cc0df9e1351786c3d3739fa27e0f
extra : histedit_source : 2e530129632340c6c1f1f465668aecc12c559abf
This commit is contained in:
Benjamin Bouvier 2016-06-30 14:42:09 +02:00
Родитель 25b54cb93b
Коммит b1470f9537
19 изменённых файлов: 43 добавлений и 5 удалений

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

@ -213,6 +213,7 @@ CodeSegment::create(JSContext* cx,
cs->globalDataLength_ = linkData.globalDataLength;
cs->interruptCode_ = cs->code() + linkData.interruptOffset;
cs->outOfBoundsCode_ = cs->code() + linkData.outOfBoundsOffset;
cs->unalignedAccessCode_ = cs->code() + linkData.unalignedAccessOffset;
{
JitContext jcx(CompileRuntime::get(cx->compartment()->runtimeFromAnyThread()));

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

@ -47,10 +47,11 @@ class CodeSegment
uint32_t codeLength_;
uint32_t globalDataLength_;
// These are pointers into code for two stubs used for asynchronous
// These are pointers into code for stubs used for asynchronous
// signal-handler control-flow transfer.
uint8_t* interruptCode_;
uint8_t* outOfBoundsCode_;
uint8_t* unalignedAccessCode_;
// The profiling mode may be changed dynamically.
bool profilingEnabled_;
@ -80,6 +81,7 @@ class CodeSegment
uint8_t* interruptCode() const { return interruptCode_; }
uint8_t* outOfBoundsCode() const { return outOfBoundsCode_; }
uint8_t* unalignedAccessCode() const { return unalignedAccessCode_; }
// The range [0, functionBytes) is a subrange of [0, codeBytes) that
// contains only function body code, not the stub code. This distinction is

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

@ -419,6 +419,7 @@ ModuleGenerator::finishCodegen()
// Fill in LinkData with the offsets of these stubs.
linkData_.outOfBoundsOffset = jumpTargets[JumpTarget::OutOfBounds].begin;
linkData_.unalignedAccessOffset = jumpTargets[JumpTarget::UnalignedAccess].begin;
linkData_.interruptOffset = interruptExit.begin;
// Only call convertOutOfRangeBranchesToThunks after all other codegen that may

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

@ -35,6 +35,9 @@ wasm::HasCompilerSupport(ExclusiveContext* cx)
if (!cx->jitSupportsFloatingPoint())
return false;
if (!cx->jitSupportsUnalignedAccesses())
return false;
#if defined(JS_CODEGEN_NONE) || defined(JS_CODEGEN_ARM64)
return false;
#else

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

@ -41,6 +41,7 @@ struct LinkDataCacheablePod
uint32_t globalDataLength;
uint32_t interruptOffset;
uint32_t outOfBoundsOffset;
uint32_t unalignedAccessOffset;
LinkDataCacheablePod() { mozilla::PodZero(this); }
};

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

@ -934,6 +934,7 @@ wasm::GenerateJumpTarget(MacroAssembler& masm, JumpTarget target)
return GenerateThrow(masm);
case JumpTarget::BadIndirectCall:
case JumpTarget::OutOfBounds:
case JumpTarget::UnalignedAccess:
case JumpTarget::Unreachable:
case JumpTarget::IntegerOverflow:
case JumpTarget::InvalidConversionToInteger:

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

@ -124,6 +124,9 @@ HandleTrap(int32_t trapIndex)
case Trap::OutOfBounds:
errorNumber = JSMSG_BAD_INDEX;
break;
case Trap::UnalignedAccess:
errorNumber = JSMSG_WASM_UNALIGNED_ACCESS;
break;
default:
MOZ_CRASH("unexpected trap");
}

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

@ -732,6 +732,8 @@ enum class Trap
IntegerDivideByZero,
// Out of bounds on wasm memory accesses and asm.js SIMD/atomic accesses.
OutOfBounds,
// Unaligned memory access.
UnalignedAccess,
// Bad signature for an indirect call.
BadIndirectCall,
@ -755,6 +757,7 @@ enum class JumpTarget
InvalidConversionToInteger = unsigned(Trap::InvalidConversionToInteger),
IntegerDivideByZero = unsigned(Trap::IntegerDivideByZero),
OutOfBounds = unsigned(Trap::OutOfBounds),
UnalignedAccess = unsigned(Trap::UnalignedAccess),
BadIndirectCall = unsigned(Trap::BadIndirectCall),
ImpreciseSimdConversion = unsigned(Trap::ImpreciseSimdConversion),
// Non-traps

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

@ -3477,6 +3477,12 @@ jit::JitSupportsFloatingPoint()
return js::jit::MacroAssembler::SupportsFloatingPoint();
}
bool
jit::JitSupportsUnalignedAccesses()
{
return js::jit::MacroAssembler::SupportsUnalignedAccesses();
}
bool
jit::JitSupportsSimd()
{

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

@ -203,6 +203,7 @@ void DestroyJitScripts(FreeOp* fop, JSScript* script);
void TraceJitScripts(JSTracer* trc, JSScript* script);
bool JitSupportsFloatingPoint();
bool JitSupportsUnalignedAccesses();
bool JitSupportsSimd();
bool JitSupportsAtomics();

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

@ -6,7 +6,7 @@
#include "jit/arm/Architecture-arm.h"
#if !defined(JS_ARM_SIMULATOR) && !defined(__APPLE__)
#if !defined(JS_SIMULATOR_ARM) && !defined(__APPLE__)
#include <elf.h>
#endif
@ -41,7 +41,6 @@
namespace js {
namespace jit {
// Parse the Linux kernel cpuinfo features. This is also used to parse the
// override features which has some extensions: 'armv7', 'align' and 'hardfp'.
static uint32_t
@ -269,6 +268,12 @@ GetARMFlags()
return armHwCapFlags;
}
bool HasARMv7()
{
MOZ_ASSERT(armHwCapFlags != HWCAP_UNINITIALIZED);
return armHwCapFlags & HWCAP_ARMv7;
}
bool HasMOVWT()
{
MOZ_ASSERT(armHwCapFlags != HWCAP_UNINITIALIZED);

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

@ -576,6 +576,7 @@ class VFPRegister
typedef VFPRegister FloatRegister;
uint32_t GetARMFlags();
bool HasARMv7();
bool HasMOVWT();
bool HasLDSTREXBHD(); // {LD,ST}REX{B,H,D}
bool HasDMBDSBISB(); // DMB, DSB, and ISB

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

@ -1752,6 +1752,9 @@ class Assembler : public AssemblerShared
static bool SupportsFloatingPoint() {
return HasVFP();
}
static bool SupportsUnalignedAccesses() {
return HasARMv7();
}
static bool SupportsSimd() {
return js::jit::SupportsSimd;
}

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

@ -287,6 +287,7 @@ class Assembler : public vixl::Assembler
}
static bool SupportsFloatingPoint() { return true; }
static bool SupportsUnalignedAccesses() { return true; }
static bool SupportsSimd() { return js::jit::SupportsSimd; }
// Tracks a jump that is patchable after finalization.

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

@ -1101,6 +1101,7 @@ class AssemblerX86Shared : public AssemblerShared
static bool HasSSE41() { return CPUInfo::IsSSE41Present(); }
static bool HasPOPCNT() { return CPUInfo::IsPOPCNTPresent(); }
static bool SupportsFloatingPoint() { return CPUInfo::IsSSE2Present(); }
static bool SupportsUnalignedAccesses() { return true; }
static bool SupportsSimd() { return CPUInfo::IsSSE2Present(); }
static bool HasAVX() { return CPUInfo::IsAVXPresent(); }

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

@ -352,6 +352,7 @@ MSG_DEF(JSMSG_WASM_UNREACHABLE, 0, JSEXN_ERR, "unreachable execut
MSG_DEF(JSMSG_WASM_INTEGER_OVERFLOW, 0, JSEXN_ERR, "integer overflow")
MSG_DEF(JSMSG_WASM_INVALID_CONVERSION, 0, JSEXN_ERR, "invalid conversion to integer")
MSG_DEF(JSMSG_WASM_INT_DIVIDE_BY_ZERO, 0, JSEXN_ERR, "integer divide by zero")
MSG_DEF(JSMSG_WASM_UNALIGNED_ACCESS, 0, JSEXN_ERR, "unaligned memory access")
MSG_DEF(JSMSG_WASM_OVERRECURSED, 0, JSEXN_INTERNALERR, "call stack exhausted")
// Proxy

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

@ -210,6 +210,7 @@ class ExclusiveContext : public ContextFriendFields,
size_t gcSystemPageSize() { return gc::SystemPageSize(); }
bool canUseSignalHandlers() const { return runtime_->canUseSignalHandlers(); }
bool jitSupportsFloatingPoint() const { return runtime_->jitSupportsFloatingPoint; }
bool jitSupportsUnalignedAccesses() const { return runtime_->jitSupportsUnalignedAccesses; }
bool jitSupportsSimd() const { return runtime_->jitSupportsSimd; }
bool lcovEnabled() const { return runtime_->lcovOutput.isEnabled(); }

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

@ -238,6 +238,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
wrapObjectCallbacks(&DefaultWrapObjectCallbacks),
preserveWrapperCallback(nullptr),
jitSupportsFloatingPoint(false),
jitSupportsUnalignedAccesses(false),
jitSupportsSimd(false),
ionPcScriptCache(nullptr),
scriptEnvironmentPreparer(nullptr),
@ -350,6 +351,7 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
#endif
jitSupportsFloatingPoint = js::jit::JitSupportsFloatingPoint();
jitSupportsUnalignedAccesses = js::jit::JitSupportsUnalignedAccesses();
jitSupportsSimd = js::jit::JitSupportsSimd();
signalHandlersInstalled_ = wasm::EnsureSignalHandlersInstalled(this);

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

@ -1186,8 +1186,9 @@ struct JSRuntime : public JS::shadow::Runtime,
return scriptDataTable_;
}
bool jitSupportsFloatingPoint;
bool jitSupportsSimd;
bool jitSupportsFloatingPoint;
bool jitSupportsUnalignedAccesses;
bool jitSupportsSimd;
// Cache for jit::GetPcScript().
js::jit::PcScriptCache* ionPcScriptCache;