Skip to content

Commit

Permalink
Implement fast array support for WebAssembly heap access
Browse files Browse the repository at this point in the history
Create WebAssemblyArrayBuffer that forces to use VirtualAlloc on x64 Windows
  • Loading branch information
Cellule committed Jan 27, 2017
1 parent 0dd9cd3 commit 6a7a303
Show file tree
Hide file tree
Showing 20 changed files with 379 additions and 214 deletions.
14 changes: 3 additions & 11 deletions lib/Backend/IR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3366,17 +3366,9 @@ bool Instr::HasAnyImplicitCalls() const

bool Instr::HasAnySideEffects() const
{
if (OpCodeAttr::HasSideEffects(this->m_opcode))
{
return true;
}

if (this->HasAnyImplicitCalls())
{
return true;
}

return false;
return (hasSideEffects ||
OpCodeAttr::HasSideEffects(this->m_opcode) ||
this->HasAnyImplicitCalls());
}

bool Instr::AreAllOpndInt64() const
Expand Down
4 changes: 3 additions & 1 deletion lib/Backend/IR.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ class Instr
extractedUpperBoundCheckWithoutHoisting(false),
ignoreOverflowBitCount(32),
isCtorCall(false),
isCallInstrProtectedByNoProfileBailout(false)
isCallInstrProtectedByNoProfileBailout(false),
hasSideEffects(false)
{
}
public:
Expand Down Expand Up @@ -484,6 +485,7 @@ class Instr
bool dstIsAlwaysConvertedToInt32 : 1;
bool dstIsAlwaysConvertedToNumber : 1;
bool isCallInstrProtectedByNoProfileBailout : 1;
bool hasSideEffects : 1; // The instruction cannot be dead stored
protected:
bool isCloned:1;
bool hasBailOutInfo:1;
Expand Down
7 changes: 1 addition & 6 deletions lib/Backend/IRBuilderAsmJs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1578,13 +1578,8 @@ IRBuilderAsmJs::BuildAsmTypedArr(Js::OpCodeAsmJs newOpcode, uint32 offset, uint3
instr = IR::Instr::New(op, indirOpnd, regOpnd, m_func);
}

#if _M_IX86 || !_WIN32
#if !_WIN64
instr->SetSrc2(BuildSrcOpnd(AsmJsRegSlots::LengthReg, TyUint32));
#else
if (this->m_func->GetJITFunctionBody()->IsWasmFunction())
{
instr->SetSrc2(BuildSrcOpnd(AsmJsRegSlots::LengthReg, TyUint32));
}
#endif
AddInstr(instr, offset);
}
Expand Down
11 changes: 9 additions & 2 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9181,17 +9181,24 @@ Lowerer::LowerLdArrViewElemWasm(IR::Instr * instr)
Assert(!dst->IsFloat64() || src1->IsFloat64());
done = m_lowererMD.LowerWasmMemOp(instr, src1);

IR::Instr* newMove = nullptr;
if (dst->IsInt64())
{
IR::Instr* movInt64 = IR::Instr::New(Js::OpCode::Ld_I4, dst, src1, m_func);
done->InsertBefore(movInt64);
m_lowererMD.LowerInt64Assign(movInt64);
newMove = m_lowererMD.LowerInt64Assign(movInt64);
}
else
{
InsertMove(dst, src1, done);
newMove = InsertMove(dst, src1, done);
}

#ifdef _WIN64
// We need to have an AV when accessing out of bounds memory even if the dst is not used
// Make sure LinearScan doesn't dead store this instruction
newMove->hasSideEffects = true;
#endif

instr->Remove();
return instrPrev;
#else
Expand Down
9 changes: 6 additions & 3 deletions lib/Backend/amd64/LowererMDArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1118,8 +1118,10 @@ LowererMDArch::LowerAsmJsCallI(IR::Instr * callInstr)
IR::Instr *
LowererMDArch::LowerWasmMemOp(IR::Instr * instr, IR::Opnd *addrOpnd)
{
#if _WIN64
return instr;
#else
Assert(instr->GetSrc2());

IR::LabelInstr * helperLabel = Lowerer::InsertLabel(true, instr);
IR::LabelInstr * loadLabel = Lowerer::InsertLabel(false, instr);
IR::LabelInstr * doneLabel = Lowerer::InsertLabel(false, instr);
Expand All @@ -1133,9 +1135,10 @@ LowererMDArch::LowerWasmMemOp(IR::Instr * instr, IR::Opnd *addrOpnd)
Lowerer::InsertAdd(true, cmpOpnd, indexOpnd, IR::IntConstOpnd::New(addrOpnd->GetSize(), TyUint64, m_func), helperLabel);
lowererMD->m_lowerer->InsertCompareBranch(cmpOpnd, arrayLenOpnd, Js::OpCode::BrGt_A, true, helperLabel, helperLabel);

lowererMD->m_lowerer->GenerateRuntimeError(loadLabel, WASMERR_ArrayIndexOutOfRange, IR::HelperOp_WebAssemblyRuntimeError);
lowererMD->m_lowerer->GenerateThrow(IR::IntConstOpnd::New(WASMERR_ArrayIndexOutOfRange, TyInt32, m_func), loadLabel);
Lowerer::InsertBranch(Js::OpCode::Br, loadLabel, helperLabel);
return doneLabel;
return done;
#endif
}

IR::Instr*
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/i386/LowererMDArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,7 @@ LowererMDArch::LowerWasmMemOp(IR::Instr * instr, IR::Opnd *addrOpnd)
lowererMD->m_lowerer->InsertCompareBranch(cmpOpnd, arrayLenOpnd, Js::OpCode::BrGe_A, true, helperLabel, helperLabel);
}

lowererMD->m_lowerer->GenerateRuntimeError(loadLabel, WASMERR_ArrayIndexOutOfRange, IR::HelperOp_WebAssemblyRuntimeError);
lowererMD->m_lowerer->GenerateThrow(IR::IntConstOpnd::New(WASMERR_ArrayIndexOutOfRange, TyInt32, m_func), loadLabel);
Lowerer::InsertBranch(Js::OpCode::Br, loadLabel, helperLabel);

Assert(indexPair.low->IsRegOpnd());
Expand Down
4 changes: 4 additions & 0 deletions lib/Common/CommonDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@
#ifdef _WIN32
#define ENABLE_OOP_NATIVE_CODEGEN 1 // Out of process JIT
#endif

#ifdef _WIN64
#define ENABLE_FAST_ARRAYBUFFER 1
#endif
#endif

// Other features
Expand Down
5 changes: 1 addition & 4 deletions lib/Runtime/Language/InterpreterStackFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2753,10 +2753,7 @@ namespace Js
}
localFunctionImports[import.location] = importFunc;
}
if (*arrayBufferPtr)
{
(*(ArrayBuffer**)arrayBufferPtr)->SetIsAsmJsBuffer();
}

threadContext->SetDisableImplicitFlags(prevDisableImplicitFlags);
threadContext->SetImplicitCallFlags(saveImplicitcallFlags);
// scope
Expand Down
Loading

0 comments on commit 6a7a303

Please sign in to comment.