Removing SET_RETURN_ADDRESS - hopefully it'll never be needed again.

This commit is contained in:
Ben Vanik
2014-01-26 01:18:59 -08:00
parent 8789fd4134
commit ecf0988ddb
20 changed files with 81 additions and 83 deletions

View File

@@ -104,7 +104,7 @@ void IVMFunction::OnBreakpointHit(ThreadState* thread_state, IntCode* i) {
#undef TRACE_SOURCE_OFFSET
int IVMFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) {
int IVMFunction::CallImpl(ThreadState* thread_state) {
// Setup register file on stack.
auto stack = (IVMStack*)thread_state->backend_data();
auto register_file = (Register*)stack->Alloc(register_count_);
@@ -120,8 +120,6 @@ int IVMFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) {
ics.did_saturate = 0;
ics.access_callbacks = thread_state->runtime()->access_callbacks();
ics.thread_state = thread_state;
ics.return_address = return_address;
ics.call_return_address = 0;
volatile int* suspend_flag_address = thread_state->suspend_flag_address();

View File

@@ -31,8 +31,7 @@ public:
protected:
virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint);
virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint);
virtual int CallImpl(runtime::ThreadState* thread_state,
uint64_t return_address);
virtual int CallImpl(runtime::ThreadState* thread_state);
private:
IntCode* GetIntCodeAtSourceOffset(uint64_t offset);

View File

@@ -580,9 +580,7 @@ uint32_t IntCode_CALL_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) {
ics.thread_state->runtime()->ResolveFunction(symbol_info->address(), &fn);
XEASSERTNOTNULL(fn);
// TODO(benvanik): proper tail call support, somehow.
uint64_t return_address =
(i->flags & CALL_TAIL) ? ics.return_address : ics.call_return_address;
fn->Call(ics.thread_state, return_address);
fn->Call(ics.thread_state);
if (i->flags & CALL_TAIL) {
return IA_RETURN;
}
@@ -647,19 +645,12 @@ int Translate_CALL_TRUE(TranslationContext& ctx, Instr* i) {
uint32_t IntCode_CALL_INDIRECT_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) {
uint64_t target = ics.rf[reg].u32;
// Check if return address - if so, return.
if (target == ics.return_address) {
return IA_RETURN;
}
// Real call.
Function* fn = NULL;
ics.thread_state->runtime()->ResolveFunction(target, &fn);
XEASSERTNOTNULL(fn);
// TODO(benvanik): proper tail call support, somehow.
uint64_t return_address =
(i->flags & CALL_TAIL) ? ics.return_address : ics.call_return_address;
fn->Call(ics.thread_state, return_address);
fn->Call(ics.thread_state);
if (i->flags & CALL_TAIL) {
return IA_RETURN;
}
@@ -777,14 +768,6 @@ int Translate_RETURN_TRUE(TranslationContext& ctx, Instr* i) {
return DispatchToC(ctx, i, fns[i->src1.value->type]);
}
uint32_t IntCode_SET_RETURN_ADDRESS(IntCodeState& ics, const IntCode* i) {
ics.call_return_address = ics.rf[i->src1_reg].u32;
return IA_NEXT;
}
int Translate_SET_RETURN_ADDRESS(TranslationContext& ctx, Instr* i) {
return DispatchToC(ctx, i, IntCode_SET_RETURN_ADDRESS);
}
uint32_t IntCode_BRANCH_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) {
return ics.rf[reg].u32;
}
@@ -4028,7 +4011,6 @@ static const TranslateFn dispatch_table[] = {
Translate_CALL_INDIRECT_TRUE,
Translate_RETURN,
Translate_RETURN_TRUE,
Translate_SET_RETURN_ADDRESS,
Translate_BRANCH,
Translate_BRANCH_TRUE,

View File

@@ -48,8 +48,6 @@ typedef struct {
int8_t did_saturate;
runtime::RegisterAccessCallbacks* access_callbacks;
runtime::ThreadState* thread_state;
uint64_t return_address;
uint64_t call_return_address;
} IntCodeState;

View File

@@ -11,11 +11,15 @@
#include <alloy/backend/x64/x64_emitter.h>
#include <alloy/backend/x64/lowering/lowering_table.h>
#include <alloy/runtime/symbol_info.h>
#include <alloy/runtime/runtime.h>
#include <alloy/runtime/thread_state.h>
using namespace alloy;
using namespace alloy::backend::x64;
using namespace alloy::backend::x64::lowering;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace Xbyak;
@@ -31,6 +35,49 @@ void Dummy() {
//
}
// TODO(benvanik): fancy stuff.
void CallThunk(void* raw_context, uint8_t* membase,
FunctionInfo* symbol_info) {
// TODO(benvanik): generate this thunk at runtime? or a shim?
auto thread_state = *((ThreadState**)raw_context);
Function* fn = NULL;
thread_state->runtime()->ResolveFunction(symbol_info->address(), &fn);
XEASSERTNOTNULL(fn);
fn->Call(thread_state);
}
void IssueCall(X64Emitter& e, FunctionInfo* symbol_info, uint32_t flags) {
e.mov(e.r8, (uint64_t)symbol_info);
e.mov(e.rax, (uint64_t)CallThunk);
if (flags & CALL_TAIL) {
e.jmp(e.rax);
} else {
e.call(e.rax);
}
}
void IndirectCallThunk(void* raw_context, uint8_t* membase,
uint64_t target_address) {
// TODO(benvanik): generate this thunk at runtime? or a shim?
auto thread_state = *((ThreadState**)raw_context);
}
void IssueCallIndirect(X64Emitter& e, Value* target, uint32_t flags) {
Reg64 r;
e.BeginOp(target, r, 0);
if (r != e.r8) {
e.mov(e.r8, r);
}
e.EndOp(r);
e.mov(e.rax, (uint64_t)IndirectCallThunk);
if (flags & CALL_TAIL) {
e.jmp(e.rax);
} else {
e.sub(e.rsp, 0x20);
e.call(e.rax);
e.add(e.rsp, 0x20);
}
}
// Sets EFLAGs with zf for the given value.
void CheckBoolean(X64Emitter& e, Value* v) {
if (v->IsConstant()) {
@@ -259,9 +306,7 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
// --------------------------------------------------------------------------
table->AddSequence(OPCODE_CALL, [](X64Emitter& e, Instr*& i) {
e.mov(e.rax, (uint64_t)Dummy);
e.call(e.rax);
UNIMPLEMENTED_SEQ();
IssueCall(e, i->src1.symbol_info, i->flags);
i = e.Advance(i);
return true;
});
@@ -270,10 +315,7 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
e.inLocalLabel();
CheckBoolean(e, i->src1.value);
e.jne(".x", e.T_SHORT);
// TODO(benvanik): call
e.mov(e.rax, (uint64_t)Dummy);
e.call(e.rax);
UNIMPLEMENTED_SEQ();
IssueCall(e, i->src2.symbol_info, i->flags);
e.L(".x");
e.outLocalLabel();
i = e.Advance(i);
@@ -281,9 +323,7 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
});
table->AddSequence(OPCODE_CALL_INDIRECT, [](X64Emitter& e, Instr*& i) {
e.mov(e.rax, (uint64_t)Dummy);
e.call(e.rax);
UNIMPLEMENTED_SEQ();
IssueCallIndirect(e, i->src1.value, i->flags);
i = e.Advance(i);
return true;
});
@@ -292,10 +332,7 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
e.inLocalLabel();
CheckBoolean(e, i->src1.value);
e.jne(".x", e.T_SHORT);
// TODO(benvanik): call
e.mov(e.rax, (uint64_t)Dummy);
e.call(e.rax);
UNIMPLEMENTED_SEQ();
IssueCallIndirect(e, i->src2.value, i->flags);
e.L(".x");
e.outLocalLabel();
i = e.Advance(i);
@@ -319,12 +356,6 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
return true;
});
table->AddSequence(OPCODE_SET_RETURN_ADDRESS, [](X64Emitter& e, Instr*& i) {
//UNIMPLEMENTED_SEQ();
i = e.Advance(i);
return true;
});
// --------------------------------------------------------------------------
// Branches
// --------------------------------------------------------------------------

View File

@@ -41,10 +41,8 @@ int X64Function::RemoveBreakpointImpl(Breakpoint* breakpoint) {
return 0;
}
int X64Function::CallImpl(ThreadState* thread_state, uint64_t return_address) {
//typedef void(*call_t)(ThreadState* thread_state, uint64_t return_address);
//((call_t)machine_code_)(thread_state, return_address);
typedef void(*call_t)(ThreadState* thread_state, uint8_t* membase);
((call_t)machine_code_)(thread_state, thread_state->memory()->membase());
int X64Function::CallImpl(ThreadState* thread_state) {
typedef void(*call_t)(void* raw_context, uint8_t* membase);
((call_t)machine_code_)(thread_state->raw_context(), thread_state->memory()->membase());
return 0;
}

View File

@@ -30,8 +30,7 @@ public:
protected:
virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint);
virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint);
virtual int CallImpl(runtime::ThreadState* thread_state,
uint64_t return_address);
virtual int CallImpl(runtime::ThreadState* thread_state);
private:
void* machine_code_;