AsmJit update

This commit is contained in:
Petr Kobalicek 2019-08-19 20:54:47 +02:00 committed by Christoph Oelckers
commit 747b3dfcfe
165 changed files with 51918 additions and 45114 deletions

View file

@ -36,7 +36,7 @@ asmjit::CodeInfo GetHostCodeInfo()
if (firstCall)
{
asmjit::JitRuntime rt;
codeInfo = rt.getCodeInfo();
codeInfo = rt.codeInfo();
firstCall = false;
}
@ -56,13 +56,12 @@ static void *AllocJitMemory(size_t size)
}
else
{
const size_t bytesToAllocate = MAX(size_t(1024 * 1024), size);
size_t allocatedSize = 0;
void *p = OSUtils::allocVirtualMemory(bytesToAllocate, &allocatedSize, OSUtils::kVMWritable | OSUtils::kVMExecutable);
if (!p)
const size_t bytesToAllocate = asmjit::Support::alignUp(MAX(size_t(1024 * 1024), size), VirtMem::info().pageGranularity);
void *p;
if (VirtMem::alloc(&p, bytesToAllocate, VirtMem::kAccessReadWrite | VirtMem::kAccessExecute) != asmjit::kErrorOk)
return nullptr;
JitBlocks.Push((uint8_t*)p);
JitBlockSize = allocatedSize;
JitBlockSize = bytesToAllocate;
JitBlockPos = size;
return p;
}
@ -80,19 +79,15 @@ static void *AllocJitMemory(size_t size)
#define UWOP_SAVE_XMM128_FAR 9
#define UWOP_PUSH_MACHFRAME 10
static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::CCFunc *func)
static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::FuncNode *func)
{
using namespace asmjit;
FuncFrameLayout layout;
Error error = layout.init(func->getDetail(), func->getFrameInfo());
if (error != kErrorOk)
I_Error("FuncFrameLayout.init failed");
FuncFrame frame = func->frame();
// We need a dummy emitter for instruction size calculations
// We need a dummy assembler for instruction size calculations
CodeHolder code;
code.init(GetHostCodeInfo());
X86Assembler assembler(&code);
X86Emitter *emitter = assembler.asEmitter();
x86::Assembler assembler(&code);
// Build UNWIND_CODE codes:
@ -101,26 +96,26 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::CCFunc *func)
// Note: this must match exactly what X86Internal::emitProlog does
X86Gp zsp = emitter->zsp(); // ESP|RSP register.
X86Gp zbp = emitter->zsp(); // EBP|RBP register.
zbp.setId(X86Gp::kIdBp);
X86Gp gpReg = emitter->zsp(); // General purpose register (temporary).
X86Gp saReg = emitter->zsp(); // Stack-arguments base register.
uint32_t gpSaved = layout.getSavedRegs(X86Reg::kKindGp);
x86::Gp zsp = assembler.zsp(); // ESP|RSP register.
x86::Gp zbp = assembler.zsp(); // EBP|RBP register.
zbp.setId(x86::Gp::kIdBp);
x86::Gp gpReg = assembler.zsp(); // General purpose register (temporary).
x86::Gp saReg = assembler.zsp(); // Stack-arguments base register.
uint32_t gpSaved = frame.savedRegs(x86::Reg::kGroupGp);
if (layout.hasPreservedFP())
if (frame.hasPreservedFP())
{
// Emit: 'push zbp'
// 'mov zbp, zsp'.
gpSaved &= ~Utils::mask(X86Gp::kIdBp);
emitter->push(zbp);
gpSaved &= ~Support::bitMask(x86::Gp::kIdBp);
assembler.push(zbp);
opoffset = (uint32_t)assembler.getOffset();
opoffset = (uint32_t)assembler.offset();
opcode = UWOP_PUSH_NONVOL;
opinfo = X86Gp::kIdBp;
opinfo = x86::Gp::kIdBp;
codes.Push(opoffset | (opcode << 8) | (opinfo << 12));
emitter->mov(zbp, zsp);
assembler.mov(zbp, zsp);
}
if (gpSaved)
@ -130,48 +125,48 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::CCFunc *func)
if (!(i & 0x1)) continue;
// Emit: 'push gp' sequence.
gpReg.setId(regId);
emitter->push(gpReg);
assembler.push(gpReg);
opoffset = (uint32_t)assembler.getOffset();
opoffset = (uint32_t)assembler.offset();
opcode = UWOP_PUSH_NONVOL;
opinfo = regId;
codes.Push(opoffset | (opcode << 8) | (opinfo << 12));
}
}
uint32_t stackArgsRegId = layout.getStackArgsRegId();
if (stackArgsRegId != Globals::kInvalidRegId && stackArgsRegId != X86Gp::kIdSp)
uint32_t saRegId = frame.saRegId();
if (saRegId != BaseReg::kIdBad && saRegId != x86::Gp::kIdSp)
{
saReg.setId(stackArgsRegId);
if (!(layout.hasPreservedFP() && stackArgsRegId == X86Gp::kIdBp))
saReg.setId(saRegId);
if (!(frame.hasPreservedFP() && saRegId == x86::Gp::kIdBp))
{
// Emit: 'mov saReg, zsp'.
emitter->mov(saReg, zsp);
assembler.mov(saReg, zsp);
}
}
if (layout.hasDynamicAlignment())
if (frame.hasDynamicAlignment())
{
// Emit: 'and zsp, StackAlignment'.
emitter->and_(zsp, -static_cast<int32_t>(layout.getStackAlignment()));
assembler.and_(zsp, -static_cast<int32_t>(frame.finalStackAlignment()));
}
if (layout.hasStackAdjustment())
if (frame.hasStackAdjustment())
{
// Emit: 'sub zsp, StackAdjustment'.
emitter->sub(zsp, layout.getStackAdjustment());
assembler.sub(zsp, frame.stackAdjustment());
uint32_t stackadjust = layout.getStackAdjustment();
uint32_t stackadjust = frame.stackAdjustment();
if (stackadjust <= 128)
{
opoffset = (uint32_t)assembler.getOffset();
opoffset = (uint32_t)assembler.offset();
opcode = UWOP_ALLOC_SMALL;
opinfo = stackadjust / 8 - 1;
codes.Push(opoffset | (opcode << 8) | (opinfo << 12));
}
else if (stackadjust <= 512 * 1024 - 8)
{
opoffset = (uint32_t)assembler.getOffset();
opoffset = (uint32_t)assembler.offset();
opcode = UWOP_ALLOC_LARGE;
opinfo = 0;
codes.Push(stackadjust / 8);
@ -179,7 +174,7 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::CCFunc *func)
}
else
{
opoffset = (uint32_t)assembler.getOffset();
opoffset = (uint32_t)assembler.offset();
opcode = UWOP_ALLOC_LARGE;
opinfo = 1;
codes.Push((uint16_t)(stackadjust >> 16));
@ -188,21 +183,22 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::CCFunc *func)
}
}
if (layout.hasDynamicAlignment() && layout.hasDsaSlotUsed())
if (frame.hasDynamicAlignment() && frame.hasDAOffset())
{
// Emit: 'mov [zsp + dsaSlot], saReg'.
X86Mem saMem = x86::ptr(zsp, layout._dsaSlot);
emitter->mov(saMem, saReg);
x86::Mem saMem = x86::ptr(zsp, int32_t(frame.daOffset()));
assembler.mov(saMem, saReg);
}
uint32_t xmmSaved = layout.getSavedRegs(X86Reg::kKindVec);
uint32_t xmmSaved = frame.savedRegs(x86::Reg::kGroupVec);
if (xmmSaved)
{
X86Mem vecBase = x86::ptr(zsp, layout.getVecStackOffset());
X86Reg vecReg = x86::xmm(0);
bool avx = layout.isAvxEnabled();
bool aligned = layout.hasAlignedVecSR();
uint32_t vecInst = aligned ? (avx ? X86Inst::kIdVmovaps : X86Inst::kIdMovaps) : (avx ? X86Inst::kIdVmovups : X86Inst::kIdMovups);
int vecOffset = frame.nonGpSaveOffset();
x86::Mem vecBase = x86::ptr(zsp, vecOffset);
x86::Reg vecReg = x86::xmm(0);
bool avx = frame.isAvxEnabled();
bool aligned = frame.hasAlignedVecSR();
uint32_t vecInst = aligned ? (avx ? x86::Inst::kIdVmovaps : x86::Inst::kIdMovaps) : (avx ? x86::Inst::kIdVmovups : x86::Inst::kIdMovups);
uint32_t vecSize = 16;
for (uint32_t i = xmmSaved, regId = 0; i; i >>= 1, regId++)
{
@ -210,24 +206,24 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::CCFunc *func)
// Emit 'movaps|movups [zsp + X], xmm0..15'.
vecReg.setId(regId);
emitter->emit(vecInst, vecBase, vecReg);
assembler.emit(vecInst, vecBase, vecReg);
vecBase.addOffsetLo32(static_cast<int32_t>(vecSize));
if (vecBase.getOffsetLo32() / vecSize < (1 << 16))
if (vecBase.offsetLo32() / vecSize < (1 << 16))
{
opoffset = (uint32_t)assembler.getOffset();
opoffset = (uint32_t)assembler.offset();
opcode = UWOP_SAVE_XMM128;
opinfo = regId;
codes.Push(vecBase.getOffsetLo32() / vecSize);
codes.Push(vecBase.offsetLo32() / vecSize);
codes.Push(opoffset | (opcode << 8) | (opinfo << 12));
}
else
{
opoffset = (uint32_t)assembler.getOffset();
opoffset = (uint32_t)assembler.offset();
opcode = UWOP_SAVE_XMM128_FAR;
opinfo = regId;
codes.Push((uint16_t)(vecBase.getOffsetLo32() >> 16));
codes.Push((uint16_t)vecBase.getOffsetLo32());
codes.Push((uint16_t)(vecBase.offsetLo32() >> 16));
codes.Push((uint16_t)vecBase.offsetLo32());
codes.Push(opoffset | (opcode << 8) | (opinfo << 12));
}
}
@ -236,7 +232,7 @@ static TArray<uint16_t> CreateUnwindInfoWindows(asmjit::CCFunc *func)
// Build the UNWIND_INFO structure:
uint16_t version = 1, flags = 0, frameRegister = 0, frameOffset = 0;
uint16_t sizeOfProlog = (uint16_t)assembler.getOffset();
uint16_t sizeOfProlog = (uint16_t)assembler.offset();
uint16_t countOfCodes = (uint16_t)codes.Size();
TArray<uint16_t> info;
@ -256,10 +252,14 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
{
using namespace asmjit;
CCFunc *func = compiler->Codegen();
FuncNode *func = compiler->Codegen();
if (code->flatten() != kErrorOk)
return nullptr;
if (code->resolveUnresolvedLinks() != kErrorOk)
return nullptr;
size_t codeSize = code->getCodeSize();
if (codeSize == 0)
size_t estimatedCodeSize = Support::alignUp(code->codeSize(), 16);
if (estimatedCodeSize == 0)
return nullptr;
#ifdef _WIN64
@ -271,24 +271,24 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
size_t functionTableSize = 0;
#endif
codeSize = (codeSize + 15) / 16 * 16;
uint8_t *p = (uint8_t *)AllocJitMemory(codeSize + unwindInfoSize + functionTableSize);
uint8_t *p = (uint8_t *)AllocJitMemory(estimatedCodeSize + unwindInfoSize + functionTableSize);
if (!p)
return nullptr;
size_t relocSize = code->relocate(p);
if (relocSize == 0)
if (code->relocateToBase((uintptr_t)p) != kErrorOk)
return nullptr;
size_t unwindStart = relocSize;
unwindStart = (unwindStart + 15) / 16 * 16;
size_t codeSize = code->codeSize();
for (Section* section : code->sections())
memcpy(p + size_t(section->offset()), section->data(), size_t(section->bufferSize()));
size_t unwindStart = Support::alignUp(codeSize, 16);
JitBlockPos -= codeSize - unwindStart;
#ifdef _WIN64
uint8_t *baseaddr = JitBlocks.Last();
uint8_t *startaddr = p;
uint8_t *endaddr = p + relocSize;
uint8_t *endaddr = p + codeSize;
uint8_t *unwindptr = p + unwindStart;
memcpy(unwindptr, &unwindInfo[0], unwindInfoSize);
@ -403,7 +403,7 @@ static void WriteCIE(TArray<uint8_t> &stream, const TArray<uint8_t> &cieInstruct
unsigned int lengthPos = stream.Size();
WriteUInt32(stream, 0); // Length
WriteUInt32(stream, 0); // CIE ID
WriteUInt8(stream, 1); // CIE Version
WriteUInt8(stream, 'z');
WriteUInt8(stream, 'R'); // fde encoding
@ -428,7 +428,7 @@ static void WriteFDE(TArray<uint8_t> &stream, const TArray<uint8_t> &fdeInstruct
WriteUInt32(stream, 0); // Length
uint32_t offsetToCIE = stream.Size() - cieLocation;
WriteUInt32(stream, offsetToCIE);
functionStart = stream.Size();
WriteUInt64(stream, 0); // func start
WriteUInt64(stream, 0); // func size
@ -486,7 +486,7 @@ static void WriteRegisterStackLocation(TArray<uint8_t> &instructions, int dwarfR
WriteULEB128(instructions, stackLocation);
}
static TArray<uint8_t> CreateUnwindInfoUnix(asmjit::CCFunc *func, unsigned int &functionStart)
static TArray<uint8_t> CreateUnwindInfoUnix(asmjit::FuncNode *func, unsigned int &functionStart)
{
using namespace asmjit;
@ -499,71 +499,67 @@ static TArray<uint8_t> CreateUnwindInfoUnix(asmjit::CCFunc *func, unsigned int &
//
// The CFI_Parser<A>::decodeFDE parser on the other side..
// https://github.com/llvm-mirror/libunwind/blob/master/src/DwarfParser.hpp
// Asmjit -> DWARF register id
int dwarfRegId[16];
dwarfRegId[X86Gp::kIdAx] = 0;
dwarfRegId[X86Gp::kIdDx] = 1;
dwarfRegId[X86Gp::kIdCx] = 2;
dwarfRegId[X86Gp::kIdBx] = 3;
dwarfRegId[X86Gp::kIdSi] = 4;
dwarfRegId[X86Gp::kIdDi] = 5;
dwarfRegId[X86Gp::kIdBp] = 6;
dwarfRegId[X86Gp::kIdSp] = 7;
dwarfRegId[X86Gp::kIdR8] = 8;
dwarfRegId[X86Gp::kIdR9] = 9;
dwarfRegId[X86Gp::kIdR10] = 10;
dwarfRegId[X86Gp::kIdR11] = 11;
dwarfRegId[X86Gp::kIdR12] = 12;
dwarfRegId[X86Gp::kIdR13] = 13;
dwarfRegId[X86Gp::kIdR14] = 14;
dwarfRegId[X86Gp::kIdR15] = 15;
dwarfRegId[x86::Gp::kIdAx] = 0;
dwarfRegId[x86::Gp::kIdDx] = 1;
dwarfRegId[x86::Gp::kIdCx] = 2;
dwarfRegId[x86::Gp::kIdBx] = 3;
dwarfRegId[x86::Gp::kIdSi] = 4;
dwarfRegId[x86::Gp::kIdDi] = 5;
dwarfRegId[x86::Gp::kIdBp] = 6;
dwarfRegId[x86::Gp::kIdSp] = 7;
dwarfRegId[x86::Gp::kIdR8] = 8;
dwarfRegId[x86::Gp::kIdR9] = 9;
dwarfRegId[x86::Gp::kIdR10] = 10;
dwarfRegId[x86::Gp::kIdR11] = 11;
dwarfRegId[x86::Gp::kIdR12] = 12;
dwarfRegId[x86::Gp::kIdR13] = 13;
dwarfRegId[x86::Gp::kIdR14] = 14;
dwarfRegId[x86::Gp::kIdR15] = 15;
int dwarfRegRAId = 16;
int dwarfRegXmmId = 17;
TArray<uint8_t> cieInstructions;
TArray<uint8_t> fdeInstructions;
uint8_t returnAddressReg = dwarfRegRAId;
int stackOffset = 8; // Offset from RSP to the Canonical Frame Address (CFA) - stack position where the CALL return address is stored
WriteDefineCFA(cieInstructions, dwarfRegId[X86Gp::kIdSp], stackOffset);
WriteDefineCFA(cieInstructions, dwarfRegId[x86::Gp::kIdSp], stackOffset);
WriteRegisterStackLocation(cieInstructions, returnAddressReg, stackOffset);
FuncFrameLayout layout;
Error error = layout.init(func->getDetail(), func->getFrameInfo());
if (error != kErrorOk)
I_Error("FuncFrameLayout.init failed");
// We need a dummy emitter for instruction size calculations
FuncFrame frame = func->frame();
// We need a dummy assembler for instruction size calculations
CodeHolder code;
code.init(GetHostCodeInfo());
X86Assembler assembler(&code);
X86Emitter *emitter = assembler.asEmitter();
x86::Assembler assembler(&code);
uint64_t lastOffset = 0;
// Note: the following code must match exactly what X86Internal::emitProlog does
X86Gp zsp = emitter->zsp(); // ESP|RSP register.
X86Gp zbp = emitter->zsp(); // EBP|RBP register.
zbp.setId(X86Gp::kIdBp);
X86Gp gpReg = emitter->zsp(); // General purpose register (temporary).
X86Gp saReg = emitter->zsp(); // Stack-arguments base register.
uint32_t gpSaved = layout.getSavedRegs(X86Reg::kKindGp);
x86::Gp zsp = assembler.zsp(); // ESP|RSP register.
x86::Gp zbp = assembler.zsp(); // EBP|RBP register.
zbp.setId(x86::Gp::kIdBp);
x86::Gp gpReg = assembler.zsp(); // General purpose register (temporary).
x86::Gp saReg = assembler.zsp(); // Stack-arguments base register.
uint32_t gpSaved = frame.savedRegs(x86::Reg::kGroupGp);
if (layout.hasPreservedFP())
if (frame.hasPreservedFP())
{
// Emit: 'push zbp'
// 'mov zbp, zsp'.
gpSaved &= ~Utils::mask(X86Gp::kIdBp);
emitter->push(zbp);
gpSaved &= ~Support::bitMask(x86::Gp::kIdBp);
assembler.push(zbp);
stackOffset += 8;
WriteAdvanceLoc(fdeInstructions, assembler.getOffset(), lastOffset);
WriteAdvanceLoc(fdeInstructions, assembler.offset(), lastOffset);
WriteDefineStackOffset(fdeInstructions, stackOffset);
WriteRegisterStackLocation(fdeInstructions, dwarfRegId[X86Gp::kIdBp], stackOffset);
WriteRegisterStackLocation(fdeInstructions, dwarfRegId[x86::Gp::kIdBp], stackOffset);
emitter->mov(zbp, zsp);
assembler.mov(zbp, zsp);
}
if (gpSaved)
@ -573,58 +569,60 @@ static TArray<uint8_t> CreateUnwindInfoUnix(asmjit::CCFunc *func, unsigned int &
if (!(i & 0x1)) continue;
// Emit: 'push gp' sequence.
gpReg.setId(regId);
emitter->push(gpReg);
assembler.push(gpReg);
stackOffset += 8;
WriteAdvanceLoc(fdeInstructions, assembler.getOffset(), lastOffset);
WriteAdvanceLoc(fdeInstructions, assembler.offset(), lastOffset);
WriteDefineStackOffset(fdeInstructions, stackOffset);
WriteRegisterStackLocation(fdeInstructions, dwarfRegId[regId], stackOffset);
}
}
uint32_t stackArgsRegId = layout.getStackArgsRegId();
if (stackArgsRegId != Globals::kInvalidRegId && stackArgsRegId != X86Gp::kIdSp)
uint32_t saRegId = frame.saRegId();
if (saRegId != BaseReg::kIdBad && saRegId != x86::Gp::kIdSp)
{
saReg.setId(stackArgsRegId);
if (!(layout.hasPreservedFP() && stackArgsRegId == X86Gp::kIdBp))
{
// Emit: 'mov saReg, zsp'.
emitter->mov(saReg, zsp);
saReg.setId(saRegId);
if (frame.hasPreservedFP()) {
if (saRegId != x86::Gp::kIdBp)
assembler.mov(saReg, zbp);
}
else {
assembler.mov(saReg, zsp);
}
}
if (layout.hasDynamicAlignment())
if (frame.hasDynamicAlignment())
{
// Emit: 'and zsp, StackAlignment'.
emitter->and_(zsp, -static_cast<int32_t>(layout.getStackAlignment()));
assembler.and_(zsp, -static_cast<int32_t>(frame.finalStackAlignment()));
}
if (layout.hasStackAdjustment())
if (frame.hasStackAdjustment())
{
// Emit: 'sub zsp, StackAdjustment'.
emitter->sub(zsp, layout.getStackAdjustment());
assembler.sub(zsp, frame.stackAdjustment());
stackOffset += layout.getStackAdjustment();
WriteAdvanceLoc(fdeInstructions, assembler.getOffset(), lastOffset);
stackOffset += frame.stackAdjustment();
WriteAdvanceLoc(fdeInstructions, assembler.offset(), lastOffset);
WriteDefineStackOffset(fdeInstructions, stackOffset);
}
if (layout.hasDynamicAlignment() && layout.hasDsaSlotUsed())
if (frame.hasDynamicAlignment() && frame.hasDAOffset())
{
// Emit: 'mov [zsp + dsaSlot], saReg'.
X86Mem saMem = x86::ptr(zsp, layout._dsaSlot);
emitter->mov(saMem, saReg);
x86::Mem saMem = x86::ptr(zsp, int32_t(frame.daOffset()));
assembler.mov(saMem, saReg);
}
uint32_t xmmSaved = layout.getSavedRegs(X86Reg::kKindVec);
uint32_t xmmSaved = frame.savedRegs(x86::Reg::kGroupVec);
if (xmmSaved)
{
int vecOffset = layout.getVecStackOffset();
X86Mem vecBase = x86::ptr(zsp, layout.getVecStackOffset());
X86Reg vecReg = x86::xmm(0);
bool avx = layout.isAvxEnabled();
bool aligned = layout.hasAlignedVecSR();
uint32_t vecInst = aligned ? (avx ? X86Inst::kIdVmovaps : X86Inst::kIdMovaps) : (avx ? X86Inst::kIdVmovups : X86Inst::kIdMovups);
int vecOffset = frame.nonGpSaveOffset();
x86::Mem vecBase = x86::ptr(zsp, vecOffset);
x86::Reg vecReg = x86::xmm(0);
bool avx = frame.isAvxEnabled();
bool aligned = frame.hasAlignedVecSR();
uint32_t vecInst = aligned ? (avx ? x86::Inst::kIdVmovaps : x86::Inst::kIdMovaps) : (avx ? x86::Inst::kIdVmovups : x86::Inst::kIdMovups);
uint32_t vecSize = 16;
for (uint32_t i = xmmSaved, regId = 0; i; i >>= 1, regId++)
{
@ -632,10 +630,10 @@ static TArray<uint8_t> CreateUnwindInfoUnix(asmjit::CCFunc *func, unsigned int &
// Emit 'movaps|movups [zsp + X], xmm0..15'.
vecReg.setId(regId);
emitter->emit(vecInst, vecBase, vecReg);
assembler.emit(vecInst, vecBase, vecReg);
vecBase.addOffsetLo32(static_cast<int32_t>(vecSize));
WriteAdvanceLoc(fdeInstructions, assembler.getOffset(), lastOffset);
WriteAdvanceLoc(fdeInstructions, assembler.offset(), lastOffset);
WriteRegisterStackLocation(fdeInstructions, dwarfRegXmmId + regId, stackOffset - vecOffset);
vecOffset += static_cast<int32_t>(vecSize);
}
@ -652,33 +650,37 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
{
using namespace asmjit;
CCFunc *func = compiler->Codegen();
FuncNode *func = compiler->Codegen();
if (code->flatten() != kErrorOk)
return nullptr;
if (code->resolveUnresolvedLinks() != kErrorOk)
return nullptr;
size_t codeSize = code->getCodeSize();
if (codeSize == 0)
size_t estimatedCodeSize = Support::alignUp(code->codeSize(), 16);
if (estimatedCodeSize == 0)
return nullptr;
unsigned int fdeFunctionStart = 0;
TArray<uint8_t> unwindInfo = CreateUnwindInfoUnix(func, fdeFunctionStart);
size_t unwindInfoSize = unwindInfo.Size();
codeSize = (codeSize + 15) / 16 * 16;
uint8_t *p = (uint8_t *)AllocJitMemory(codeSize + unwindInfoSize);
uint8_t *p = (uint8_t *)AllocJitMemory(estimatedCodeSize + unwindInfoSize);
if (!p)
return nullptr;
size_t relocSize = code->relocate(p);
if (relocSize == 0)
if (code->relocateToBase((uintptr_t)p) != kErrorOk)
return nullptr;
size_t unwindStart = relocSize;
unwindStart = (unwindStart + 15) / 16 * 16;
size_t codeSize = code->codeSize();
for (Section* section : code->sections())
memcpy(p + size_t(section->offset()), section->data(), size_t(section->bufferSize()));
size_t unwindStart = Support::alignUp(codeSize, 16);
JitBlockPos -= codeSize - unwindStart;
uint8_t *baseaddr = JitBlocks.Last();
uint8_t *startaddr = p;
uint8_t *endaddr = p + relocSize;
uint8_t *endaddr = p + codeSize;
uint8_t *unwindptr = p + unwindStart;
memcpy(unwindptr, &unwindInfo[0], unwindInfoSize);
@ -702,7 +704,7 @@ void *AddJitFunction(asmjit::CodeHolder* code, JitCompiler *compiler)
uint64_t length64 = *((uint64_t *)(entry + 4));
if (length64 == 0)
break;
uint64_t offset = *((uint64_t *)(entry + 12));
if (offset != 0)
{
@ -750,7 +752,7 @@ void JitRelease()
#endif
for (auto p : JitBlocks)
{
asmjit::OSUtils::releaseVirtualMemory(p, 1024 * 1024);
asmjit::VirtMem::release(p, 1024 * 1024);
}
JitDebugInfo.Clear();
JitFrames.Clear();