Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jit trampoline #27

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build_cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ add_library(CodeGen
../src/Jitter_CodeGen_Wasm.cpp
../src/Jitter_CodeGen.cpp
../src/Jitter_CodeGenFactory.cpp
../src/Jitter_Trampoline.cpp
../src/Jitter.cpp
../src/Jitter_Optimize.cpp
../src/Jitter_RegAlloc.cpp
Expand Down Expand Up @@ -93,6 +94,7 @@ add_library(CodeGen
../include/Jitter_Symbol.h
../include/Jitter_SymbolRef.h
../include/Jitter_SymbolTable.h
../include/Jitter_Trampoline.h
../include/Jitter.h
../include/Literal128.h
../include/LiteralPool.h
Expand Down
2 changes: 2 additions & 0 deletions include/Jitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ namespace Jitter
void Add();
void And();
void Break();

void CallRel64(size_t, unsigned int);
void Call(void*, unsigned int, bool);
void Call(void*, unsigned int, RETURN_VALUE_TYPE);
void Cmp(CONDITION);
Expand Down
2 changes: 2 additions & 0 deletions include/Jitter_CodeGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace Jitter
virtual bool CanHold128BitsReturnValueInRegisters() const = 0;
virtual void RegisterExternalSymbols(CObjectFile*) const = 0;
virtual uint32 GetPointerSize() const = 0;
void SetTrumpoline(bool);

protected:
enum MATCHTYPE
Expand Down Expand Up @@ -93,5 +94,6 @@ namespace Jitter

MatcherMapType m_matchers;
ExternalSymbolReferencedHandler m_externalSymbolReferencedHandler;
bool m_isTrampoline = false;
};
}
1 change: 1 addition & 0 deletions include/Jitter_CodeGen_x86_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ namespace Jitter
void Emit_ParamRet_Mem128(const STATEMENT&);

//CALL
void Emit_Call_Rel(const STATEMENT&);
void Emit_Call(const STATEMENT&);

//RETURNVALUE
Expand Down
1 change: 1 addition & 0 deletions include/Jitter_CodeGen_x86_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ namespace Jitter

//CALL
void Emit_Call(const STATEMENT&);
void Emit_Call_Rel64(const STATEMENT&);

//RETURNVALUE
void Emit_RetVal_Reg(const STATEMENT&);
Expand Down
26 changes: 26 additions & 0 deletions include/Jitter_Trampoline.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "Singleton.h"
#include "MemoryFunction.h"

namespace Jitter
{
class CJitter_Trampoline : public CSingleton<CJitter_Trampoline>
{
public:
CJitter_Trampoline();
~CJitter_Trampoline() = default;

void Trampoline(void*, void*);

private:
struct CONTEXT
{
void* context;
void* code;
};
void SetupTrumpoline();

CONTEXT m_context;
CMemoryFunction m_function;

};
};
2 changes: 1 addition & 1 deletion include/MemoryFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CMemoryFunction
CMemoryFunction& operator =(const CMemoryFunction&) = delete;

CMemoryFunction& operator =(CMemoryFunction&&);
void operator()(void*);
void operator()(void*, bool = false);

void* GetCode() const;
size_t GetSize() const;
Expand Down
17 changes: 17 additions & 0 deletions src/Jitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,23 @@ void CJitter::Break()
InsertStatement(statement);
}

void CJitter::CallRel64(size_t offset, unsigned int paramCount)
{
for(unsigned int i = 0; i < paramCount; i++)
{
STATEMENT paramStatement;
paramStatement.src1 = MakeSymbolRef(m_shadow.Pull());
paramStatement.op = OP_PARAM;
InsertStatement(paramStatement);
}

STATEMENT callStatement;
callStatement.src1 = MakeSymbolRef(MakeSymbol(SYM_RELATIVE64, static_cast<uint32>(offset)));
callStatement.src2 = MakeSymbolRef(MakeSymbol(SYM_CONSTANT, paramCount));
callStatement.op = OP_CALL;
InsertStatement(callStatement);
}

void CJitter::Call(void* func, unsigned int paramCount, bool keepRet)
{
Call(func, paramCount, keepRet ? RETURN_VALUE_32 : RETURN_VALUE_NONE);
Expand Down
5 changes: 5 additions & 0 deletions src/Jitter_CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,8 @@ uint32 CCodeGen::GetRegisterUsage(const StatementList& statements)
}
return registerUsage;
}

void CCodeGen::SetTrumpoline(bool isTrumpoline)
{
m_isTrampoline = isTrumpoline;
}
36 changes: 32 additions & 4 deletions src/Jitter_CodeGen_x86_32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ CCodeGen_x86_32::CONSTMATCHER CCodeGen_x86_32::g_constMatchers[] =

{ OP_PARAM_RET, MATCH_NIL, MATCH_MEMORY128, MATCH_NIL, &CCodeGen_x86_32::Emit_ParamRet_Mem128 },

{ OP_CALL, MATCH_NIL, MATCH_RELATIVE, MATCH_CONSTANT, &CCodeGen_x86_32::Emit_Call_Rel },
{ OP_CALL, MATCH_NIL, MATCH_CONSTANTPTR, MATCH_CONSTANT, &CCodeGen_x86_32::Emit_Call },

{ OP_RETVAL, MATCH_TEMPORARY, MATCH_NIL, MATCH_NIL, &CCodeGen_x86_32::Emit_RetVal_Tmp },
Expand Down Expand Up @@ -194,9 +195,9 @@ void CCodeGen_x86_32::Emit_Prolog(const StatementList& statements, unsigned int
m_assembler.MovEd(CX86Assembler::rBP, CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rSP, 8));

//Save registers
for(unsigned int i = 0; i < MAX_REGISTERS; i++)
if(m_isTrampoline)
{
if(m_registerUsage & (1 << i))
for(unsigned int i = 0; i < MAX_REGISTERS; i++)
{
m_assembler.Push(m_registers[i]);
}
Expand Down Expand Up @@ -260,9 +261,9 @@ void CCodeGen_x86_32::Emit_Epilog()

m_assembler.Pop(CX86Assembler::rSP);

for(int i = MAX_REGISTERS - 1; i >= 0; i--)
if(m_isTrampoline)
{
if(m_registerUsage & (1 << i))
for(int i = MAX_REGISTERS - 1; i >= 0; i--)
{
m_assembler.Pop(m_registers[i]);
}
Expand Down Expand Up @@ -415,6 +416,33 @@ void CCodeGen_x86_32::Emit_ParamRet_Mem128(const STATEMENT& statement)
m_hasImplicitRetValueParam = true;
}

void CCodeGen_x86_32::Emit_Call_Rel(const STATEMENT& statement)
{
auto src1 = statement.src1->GetSymbol().get();
auto src2 = statement.src2->GetSymbol().get();

uint32 paramCount = src2->m_valueLow;
CALL_STATE callState;
for(unsigned int i = 0; i < paramCount; i++)
{
auto emitter(m_params.back());
m_params.pop_back();
emitter(callState);
}

m_assembler.MovEd(CX86Assembler::rAX, MakeRelativeSymbolAddress(src1));
m_assembler.CallEd(CX86Assembler::MakeRegisterAddress(CX86Assembler::rAX));

if(m_hasImplicitRetValueParam && m_implicitRetValueParamFixUpRequired)
{
//Allocated stack space for the extra parameter is cleaned up by the callee.
//So adjust the amount of stack space we free up after the call
m_assembler.SubId(CX86Assembler::MakeRegisterAddress(CX86Assembler::rSP), 4);
}

m_hasImplicitRetValueParam = false;
}

void CCodeGen_x86_32::Emit_Call(const STATEMENT& statement)
{
auto src1 = statement.src1->GetSymbol().get();
Expand Down
31 changes: 25 additions & 6 deletions src/Jitter_CodeGen_x86_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ CCodeGen_x86_64::CONSTMATCHER CCodeGen_x86_64::g_constMatchers[] =
{ OP_PARAM_RET, MATCH_NIL, MATCH_MEMORY128, MATCH_NIL, MATCH_NIL, &CCodeGen_x86_64::Emit_Param_Mem128 },

{ OP_CALL, MATCH_NIL, MATCH_CONSTANTPTR, MATCH_CONSTANT, MATCH_NIL, &CCodeGen_x86_64::Emit_Call },
{ OP_CALL, MATCH_NIL, MATCH_RELATIVE64, MATCH_CONSTANT, MATCH_NIL, &CCodeGen_x86_64::Emit_Call_Rel64 },

{ OP_RETVAL, MATCH_REGISTER, MATCH_NIL, MATCH_NIL, MATCH_NIL, &CCodeGen_x86_64::Emit_RetVal_Reg },
{ OP_RETVAL, MATCH_MEMORY, MATCH_NIL, MATCH_NIL, MATCH_NIL, &CCodeGen_x86_64::Emit_RetVal_Mem },
Expand Down Expand Up @@ -325,7 +326,6 @@ uint32 CCodeGen_x86_64::GetPointerSize() const
void CCodeGen_x86_64::Emit_Prolog(const StatementList& statements, unsigned int stackSize)
{
m_params.clear();

//Compute the size needed to store all function call parameters
uint32 maxParamSpillSize = 0;
{
Expand Down Expand Up @@ -363,14 +363,14 @@ void CCodeGen_x86_64::Emit_Prolog(const StatementList& statements, unsigned int
m_assembler.MovEq(CX86Assembler::rBP, CX86Assembler::MakeRegisterAddress(m_paramRegs[0]));

uint32 savedSize = 0;
for(unsigned int i = 0; i < m_maxRegisters; i++)
if(m_isTrampoline)
{
if(m_registerUsage & (1 << i))
for(unsigned int i = 0; i < m_maxRegisters; i++)
{
m_assembler.Push(m_registers[i]);
savedSize += 8;
}
}
}

uint32 savedRegAlignAdjust = (savedSize != 0) ? (0x10 - (savedSize & 0xF)) : 0;

Expand Down Expand Up @@ -402,9 +402,9 @@ void CCodeGen_x86_64::Emit_Epilog()
{
m_assembler.AddIq(CX86Assembler::MakeRegisterAddress(CX86Assembler::rSP), m_totalStackAlloc);

for(int i = m_maxRegisters - 1; i >= 0; i--)
if(m_isTrampoline)
{
if(m_registerUsage & (1 << i))
for(int i = m_maxRegisters - 1; i >= 0; i--)
{
m_assembler.Pop(m_registers[i]);
}
Expand Down Expand Up @@ -539,6 +539,25 @@ void CCodeGen_x86_64::Emit_Param_Mem128(const STATEMENT& statement)
);
}

void CCodeGen_x86_64::Emit_Call_Rel64(const STATEMENT& statement)
{
const auto& src1 = statement.src1->GetSymbol().get();
const auto& src2 = statement.src2->GetSymbol().get();

unsigned int paramCount = src2->m_valueLow;
uint32 paramSpillOffset = 0;

for(unsigned int i = 0; i < paramCount; i++)
{
auto emitter(m_params.back());
m_params.pop_back();
paramSpillOffset += emitter(m_paramRegs[i], paramSpillOffset);
}

m_assembler.MovEq(CX86Assembler::rAX, MakeMemory64SymbolAddress(src1));
m_assembler.CallEd(CX86Assembler::MakeRegisterAddress(CX86Assembler::rAX));
}

void CCodeGen_x86_64::Emit_Call(const STATEMENT& statement)
{
const auto& src1 = statement.src1->GetSymbol().get();
Expand Down
37 changes: 37 additions & 0 deletions src/Jitter_Trampoline.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "Jitter_Trampoline.h"
#include "Jitter.h"
#include "Jitter_CodeGenFactory.h"

#include "MemStream.h"

Jitter::CJitter_Trampoline::CJitter_Trampoline()
{
SetupTrumpoline();
}

void Jitter::CJitter_Trampoline::SetupTrumpoline()
{
Jitter::CCodeGen* codeGen = Jitter::CreateCodeGen();
codeGen->SetTrumpoline(true);
Jitter::CJitter jitter(codeGen);

Framework::CMemStream codeStream;
jitter.SetStream(&codeStream);

jitter.Begin();
{
jitter.PushRel64(offsetof(CONTEXT, context));
jitter.CallRel64(offsetof(CONTEXT, code), 1);
}
jitter.End();
codeGen->SetTrumpoline(false);

m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize());
}

void Jitter::CJitter_Trampoline::Trampoline(void* context, void* code)
{
m_context.context = context;
m_context.code = code;
m_function(&m_context, true);
}
16 changes: 12 additions & 4 deletions src/MemoryFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <cstdint>
#include "AlignedAlloc.h"
#include "MemoryFunction.h"
#include "Jitter_Trampoline.h"

#define BLOCK_ALIGN 0x10

Expand Down Expand Up @@ -177,11 +178,18 @@ CMemoryFunction& CMemoryFunction::operator =(CMemoryFunction&& rhs)
return (*this);
}

void CMemoryFunction::operator()(void* context)
void CMemoryFunction::operator()(void* context, bool isTrampoline)
{
typedef void (*FctType)(void*);
auto fct = reinterpret_cast<FctType>(m_code);
fct(context);
if(isTrampoline)
{
typedef void (*FctType)(void*);
auto fct = reinterpret_cast<FctType>(m_code);
fct(context);
}
else
{
Jitter::CJitter_Trampoline::GetInstance().Trampoline(context, m_code);
}
}

void* CMemoryFunction::GetCode() const
Expand Down