branch patching cleanup

extensions
Steven Massey 3 years ago
parent e1441d53fd
commit 972e5cdcf1

@ -90,11 +90,6 @@ void ReleaseCompilationCodePage (IM3Compilation o)
ReleaseCodePage (o->runtime, o->page);
}
bool IsStackPolymorphic (IM3Compilation o)
{
return o->block.isPolymorphic;
}
bool IsRegisterSlotAlias (i16 i_slot) { return (i_slot >= d_m3Reg0SlotAlias); }
bool IsFpRegisterSlotAlias (i16 i_slot) { return (i_slot == d_m3Fp0SlotAlias); }
bool IsIntRegisterSlotAlias (i16 i_slot) { return (i_slot == d_m3Reg0SlotAlias); }
@ -109,11 +104,24 @@ u16 GetTypeNumSlots (u8 i_type)
# endif
}
bool IsStackPolymorphic (IM3Compilation o)
{
return o->block.isPolymorphic;
}
i16 GetStackTopIndex (IM3Compilation o)
{ d_m3Assert (o->stackIndex > 0 or IsStackPolymorphic (o));
return o->stackIndex - 1;
}
void SetStackPolymorphic (IM3Compilation o)
{
o->block.isPolymorphic = true;
// o->block.polymorphicIndex = GetStackTopIndex (o);
}
u8 GetStackTopTypeAtOffset (IM3Compilation o, u16 i_offset)
{
@ -671,59 +679,21 @@ M3Result AddTrapRecord (IM3Compilation o)
}
M3Result AcquirePatch (IM3Compilation o, IM3BranchPatch * o_patch)
{
M3Result result = m3Err_none;
IM3BranchPatch patch = o->releasedPatches;
if (patch)
{
o->releasedPatches = patch->next;
patch->next = NULL;
}
else {
patch = m3_AllocStruct(M3BranchPatch);
_throwifnull(patch);
}
* o_patch = patch;
_catch: return result;
}
bool PatchBranches (IM3Compilation o)
{
bool didPatch = false;
M3CompilationScope * block = & o->block;
pc_t pc = GetPC (o);
IM3BranchPatch patches = block->patches;
IM3BranchPatch endPatch = patches;
IM3BranchPatch patches = o->block.patches;
o->block.patches = NULL;
bool didPatch = patches;
while (patches)
{ m3log (compile, "patching location: %p to pc: %p", patches->location, pc);
if (not patches->location)
break;
* (patches->location) = pc;
endPatch = patches;
{ m3log (compile, "patching location: %p to pc: %p", patches, pc);
patches->location = pc;
patches = patches->next;
}
if (block->patches)
{ d_m3Assert (endPatch->next == NULL);
// return patches to pool
endPatch->next = o->releasedPatches;
o->releasedPatches = block->patches;
block->patches = NULL;
didPatch = true;
}
return didPatch;
}
@ -1089,15 +1059,15 @@ _ (EmitOp (o, op_Return));
_ (UnwindBlockStack (o));
// B: move register to return slot for branchehs
if (type)
{
if (PatchBranches (o))
{
_ (PushRegister (o, type));
ReturnStackTop (o);
_ (EmitOp (o, op_Return));
}
}
// if (type)
// {
// if (PatchBranches (o))
// {
//_ (PushRegister (o, type));
// ReturnStackTop (o);
//_ (EmitOp (o, op_Return));
// }
// }
}
_catch: return result;
@ -1219,6 +1189,23 @@ _ ((i_opcode == 0x23) ? Compile_GetGlobal (o, global) : Compile_SetGlo
}
M3Result EmitPatchingBranch (IM3Compilation o, IM3CompilationScope i_scope)
{
M3Result result;
_ (EmitOp (o, op_Branch));
// IM3BranchPatch is two word struct; reserve two words
IM3BranchPatch patch = (IM3BranchPatch) ReservePointer (o); m3log (compile, "branch patch required at: %p", patch);
ReservePointer (o);
patch->next = i_scope->patches;
i_scope->patches = patch;
_catch:
return result;
}
M3Result Compile_Branch (IM3Compilation o, m3opcode_t i_opcode)
{
M3Result result;
@ -1261,29 +1248,23 @@ _ (EmitOp (o, op));
IM3Operation op = conditionInRegister ? op_BranchIf_r : op_BranchIf_s;
_ (EmitOp (o, op));
EmitSlotNumOfStackTopAndPop (o);
EmitSlotNumOfStackTopAndPop (o); // condition
// this is continuation point, if the branch isn't taken
jumpTo = (pc_t *) ReservePointer (o);
}
if (not IsStackPolymorphic (o))
_ (ResolveBlockResults (o, scope, false));
_ (EmitOp (o, op_Branch));
IM3BranchPatch patch = NULL;
_ (AcquirePatch (o, & patch));
if (not IsStackPolymorphic (o))
_ (ResolveBlockResults (o, scope, false));
patch->location = (pc_t *) ReservePointer (o);
patch->next = scope->patches;
scope->patches = patch;
_ (EmitPatchingBranch (o, scope));
if (jumpTo)
{
* jumpTo = GetPC (o);
}
else o->block.isPolymorphic = true;
else SetStackPolymorphic (o);
// o->block.isPolymorphic = true;
}
_catch: return result;
@ -1341,14 +1322,7 @@ _ (EmitOp (o, op_ContinueLoop));
// TODO: this could be fused with equivalent targets
_ (ResolveBlockResults (o, scope, false));
_ (EmitOp (o, op_Branch));
IM3BranchPatch patch = NULL;
_ (AcquirePatch (o, & patch));
patch->location = (pc_t *) ReservePointer (o);
patch->next = scope->patches;
scope->patches = patch;
_ (EmitPatchingBranch (o, scope));
}
ReleaseCompilationCodePage (o); // FIX: continueOpPage can get lost if thrown
@ -1481,7 +1455,7 @@ _ (ReadLEB_u32 (& typeIndex, & o->wasm, o->wasmEnd));
i8 reserved;
_ (ReadLEB_i7 (& reserved, & o->wasm, o->wasmEnd));
_throwif ("function type index out of range", typeIndex >= o->module->numFuncTypes);
_throwif ("function call type index out of range", typeIndex >= o->module->numFuncTypes);
if (IsStackTopInRegister (o))
_ (PreserveRegisterIfOccupied (o, c_m3Type_i32));
@ -2395,9 +2369,7 @@ M3Result Compile_ReserveConstants (IM3Compilation o)
void SetupCompilation (IM3Compilation o)
{
IM3BranchPatch patches = o->releasedPatches;
memset (o, 0x0, sizeof (M3Compilation));
o->releasedPatches = patches;
}

@ -46,10 +46,11 @@ enum
// since the end location of a block is unknown when a branch is compiled, writing
// the actual address must deferred. A linked-list of patch locations is kept in
// M3CompilationScope. When the block compilation exits, it patches these addresses.
// this data structure is embedded into the code pages themselves
typedef struct M3BranchPatch
{
struct M3BranchPatch * next;
pc_t * location;
pc_t location;
struct M3BranchPatch * next;
}
M3BranchPatch;
@ -65,6 +66,7 @@ typedef struct M3CompilationScope
i32 depth;
i16 initStackIndex;
u16 topSlot;
u16 polymorphicIndex;
IM3FuncType type;
m3opcode_t opcode;
bool isPolymorphic;
@ -88,8 +90,6 @@ typedef struct
IM3CodePage page;
IM3BranchPatch releasedPatches;
#ifdef DEBUG
u32 numEmits;
u32 numOpcodes;

@ -221,20 +221,6 @@ void * _FreeModule (IM3Module i_module, void * i_info)
}
void FreeCompilationPatches (IM3Compilation o)
{
IM3BranchPatch patches = o->releasedPatches;
while (patches)
{
IM3BranchPatch next = patches->next;
m3_Free (patches);
patches = next;
}
}
void Runtime_Release (IM3Runtime i_runtime)
{
ForEachModule (i_runtime, _FreeModule, NULL); d_m3Assert (i_runtime->numActiveCodePages == 0);
@ -242,8 +228,6 @@ void Runtime_Release (IM3Runtime i_runtime)
Environment_ReleaseCodePages (i_runtime->environment, i_runtime->pagesOpen);
Environment_ReleaseCodePages (i_runtime->environment, i_runtime->pagesFull);
FreeCompilationPatches (& i_runtime->compilation);
m3_Free (i_runtime->stack);
m3_Free (i_runtime->memory.mallocated);
}

Loading…
Cancel
Save