Skip to content

Commit

Permalink
cleaned up some management interface stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewfl committed Jul 29, 2016
1 parent c0341d8 commit 5fbfcb5
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 71 deletions.
6 changes: 2 additions & 4 deletions src/asm_interface.S
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ red_asm_restart_trace:
// might end up returning to a another trace block
.global red_asm_end_trace
red_asm_end_trace:
pushq %rdi
call red_end_trace@plt
popq %rsi
jmp *%rax


Expand All @@ -95,10 +97,6 @@ red_asm_start_nested_trace:
jmp *%rax


testing:
jmp 0x123fa(,%r12,8)
mov 0xfafafa(,%r12,8), %rax


// we don't need executable stack
.section .note.GNU-stack,"",%progbits
2 changes: 1 addition & 1 deletion src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@


// using 10 will cause ipython to crash, TODO: find the bug...
#define CONF_NUMBER_OF_JUMPS_BEFORE_TRACE 100
#define CONF_NUMBER_OF_JUMPS_BEFORE_TRACE 10


//#define CONF_VERBOSE
Expand Down
6 changes: 3 additions & 3 deletions src/jit_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ namespace redmagic {

void ensure_not_traced();

void *temp_disable(void *resume_pc);
void *temp_enable(void *resume_pc);
void *temp_disable(void *ret_addr);
void *temp_enable(void *ret_addr);

void *begin_merge_block();
void *end_merge_block();
Expand Down Expand Up @@ -121,7 +121,7 @@ namespace redmagic {
bool is_temp_disabled = false;
bool is_traced = false;
bool is_compiled = false;
bool did_abort = false;
//bool did_abort = false;
};

//extern thread_local std::vector<tracer_stack_state> trace_return_addr;
Expand Down
2 changes: 1 addition & 1 deletion src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ int main(int argc, char* argv[]) {

int program[] = {
PRINT_NUM, 0,
COND_SET, 100,
COND_SET, 400,
PRINT_NUM, 1,
COND_ADD, -1,
MERGE_TEST, 0,
Expand Down
188 changes: 178 additions & 10 deletions src/manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ extern "C" void* red_user_fellthrough_branch(void *id, void *ret_addr) {
extern "C" void* red_user_ensure_not_traced(void *_, void *ret_addr) {
// TODO:
auto head = manager->get_tracer_head();
assert(!head->is_traced || head->did_abort); // TODO: better manage abort
assert(!head->is_traced);
return NULL;
}

Expand Down Expand Up @@ -224,6 +224,8 @@ uint32_t Manager::get_thread_id() {
}

void* Manager::begin_trace(void *id, void *ret_addr) {
assert(0); // TODO: rewrite this method

branch_info *info = &branches[id];
if(info->disabled)
return NULL; // do not trace this loop
Expand Down Expand Up @@ -279,11 +281,13 @@ void* Manager::begin_trace(void *id, void *ret_addr) {
extern "C" void* red_end_trace(mem_loc_t);

void* Manager::end_trace(void *id, void *ret_addr) {
assert(0); // TODO: rewrite this method

void *ret;
Tracer *l;
auto head = get_tracer_head();
branch_info *info = &branches[id];
if(!head->tracer || head->did_abort) {
if(!head->tracer /*|| head->did_abort*/) {
// then we weren't actually running on the tracer
return red_end_trace((mem_loc_t)ret_addr);
}
Expand Down Expand Up @@ -321,6 +325,112 @@ void* Manager::backwards_branch(void *id, void *ret_addr) {
if(id == nullptr)
return NULL;

tracer_stack_state* head = get_tracer_head();
tracer_stack_state* new_head = nullptr;
Tracer *l;
void* start_addr = ret_addr;
auto info = &branches[id];
if(head->trace_id == id) {
if(head->is_traced) {
#ifdef CONF_GLOBAL_ABORT
//assert(!head->did_abort);
#endif
assert(!head->is_compiled);
assert(info->tracer == head->tracer);
assert(!info->disabled);
void *ret = head->tracer->EndTraceLoop();
head->is_compiled = true;
l = head->tracer;
head->tracer = info->tracer = nullptr;

Tracer *expected = nullptr;
if(!free_tracer_list.compare_exchange_strong(expected, l)) {
// failled to save the tracer to the free list head
delete l;
}

return ret;
} else {
new_head = head;
if(info->starting_point && (!info->tracer || info->tracer->did_abort)) {
// then we must have performed the abort
//assert(info->tracer->did_abort);
head->is_traced = true;
head->is_compiled = true;
//head->tracer = info->tracer;
return info->starting_point;
}
goto check_new_trace;
}
} else {
// if there is no tracer set then that means that this was either call directly from normal code
// and the ret_addr is a valid starting point, or this is call from branch_to_sub_trace which
// will pass in a valid address to the ret_addr
if(head->tracer) {
//assert(head->tracer);
start_addr = (void*)head->tracer->get_pc();
head->tracer->JumpToNestedLoop(id);
}
new_head = push_tracer_stack();
head = &threadl_tracer_stack[threadl_tracer_stack.size() - 2];
new_head->trace_id = id;
if(info->starting_point) {
assert(!info->tracer || info->tracer->did_abort);
new_head->is_compiled = true;
new_head->is_traced = true;
#ifdef CONF_VERBOSE
red_printf("entering trace %x\n", id);
#endif
return info->starting_point;
}
goto check_new_trace;
// int cnt = info->count++;
// if(cnt > CONF_NUMBER_OF_JUMPS_BEFORE_TRACE) {
// goto start_new_trace;
// //return begin_trace(id, ret_addr);
// }
// return NULL;
}

check_new_trace:
int cnt = info->count++;
if(info->tracer) {
// then it aborted or is currently performing this trace
if(info->tracer->did_abort) {
new_head->is_compiled = true;
new_head->is_traced = true;
#ifdef CONF_VERBOSE
red_printf("entering aborted trace %x\n", id);
#endif
return info->starting_point;
}
return start_addr;
}
if(cnt > CONF_NUMBER_OF_JUMPS_BEFORE_TRACE && !info->disabled) {
goto start_new_trace;
}

return start_addr; // do nothing, force it to jump back to "normal" address even if coming from a tracer

start_new_trace:
assert(!info->disabled);
assert(!info->tracer);
assert(new_head != nullptr);
assert(info->trace_loop_counter == nullptr);
auto buff = CodeBuffer::CreateBuffer(1024 * 1024);
info->tracer = new_head->tracer = l = new Tracer(buff);
l->tracing_from = (mem_loc_t)start_addr;
l->owning_thread = get_thread_id();
void *ret = l->Start(start_addr);
new_head->is_traced = true;
info->starting_point = l->get_start_location();
info->trace_loop_counter = l->get_loop_counter();

return ret;



/*
//return NULL;
auto head = get_tracer_head();
if(head->is_traced) {
Expand Down Expand Up @@ -424,14 +534,67 @@ void* Manager::backwards_branch(void *id, void *ret_addr) {
}
}
return NULL;
*/
}

void* Manager::fellthrough_branch(void *id, void *ret_addr) {
// ignore
if(id == nullptr)
return NULL;

Tracer *l;
void *ret = NULL;
auto head = get_tracer_head();
if(head->trace_id == id) {
auto info = &branches[id];
if(head->is_traced) {
assert(!head->is_compiled);
assert(!info->disabled);
assert(head->tracer && head->tracer == info->tracer);
l = head->tracer;
// this will pop the head of the stack internally
ret = l->EndTraceFallthrough();
info->tracer = head->tracer = nullptr;

Tracer *expected = nullptr;
if(!free_tracer_list.compare_exchange_strong(expected, l)) {
// failled to save the tracer to the free list head
delete l;
}

return ret;
} else {
assert(!head->is_compiled);
assert(head->resume_addr == nullptr);
assert(head->is_temp_disabled == false);
// we have to pop this frame since we weren't being traced and there is nothing that will do it for us
pop_tracer_stack();
auto new_head = get_tracer_head();
if(new_head->resume_addr) {
if(new_head->tracer) {
// ret_addr will not be a traced address but a real normal address
// so we set that as the possible resume address if there is a tracer that we are going to be resuming
new_head->tracer->JumpFromNestedLoop(ret_addr);
}
ret = new_head->resume_addr;
new_head->resume_addr = nullptr;
return ret;
}
return NULL;
}
}

if(head->is_traced) {
// there is a fallthrough without a backwards branch which means that we never
// got to the backwards branch portion of this loop
assert(!head->is_compiled);
assert(head->tracer);
return head->tracer->DeleteLastCall();
}

return NULL;

/*
if(head->trace_id == id && head->is_traced) {
return end_trace(id, ret_addr);
// branch_info *info = &branches[id];
Expand All @@ -449,34 +612,35 @@ void* Manager::fellthrough_branch(void *id, void *ret_addr) {
// //l->tracing_from.store(0);
// return ret;
}
return NULL;
*/
}

void* Manager::temp_disable(void *resume_pc) {
temp_disable_last_addr = resume_pc;
void* Manager::temp_disable(void *ret_addr) {
temp_disable_last_addr = ret_addr;
auto head = get_tracer_head();
assert(!head->is_temp_disabled);
head->is_temp_disabled = true;
void *ret = NULL;
assert(!head->is_traced || head->tracer || head->did_abort);
assert(!head->is_traced || head->tracer);
if(head->tracer && !head->tracer->did_abort) {
// this will push the stack
ret = head->tracer->TempDisableTrace();
} else {
assert(!head->resume_addr);
push_tracer_stack();
}
return ret;
}

void* Manager::temp_enable(void *resume_pc) {
void* Manager::temp_enable(void *ret_addr) {
auto old_head = pop_tracer_stack();
assert(!old_head.is_temp_disabled);
auto head = get_tracer_head();
assert(head->is_temp_disabled);
head->is_temp_disabled = false;
void *ret = NULL;
if(head->tracer && !head->tracer->did_abort) {
head->tracer->TempEnableTrace(resume_pc);
head->tracer->TempEnableTrace(ret_addr);
}
if(head->resume_addr != nullptr) {
ret = head->resume_addr;
Expand Down Expand Up @@ -532,7 +696,8 @@ void* Manager::is_traced_call() {
void Manager::disable_branch(void *id) {
branches[id].disabled = true;
for(int i = 0; i < threadl_tracer_stack.size(); i++) {
assert(threadl_tracer_stack[i].trace_id != id);
auto b = &threadl_tracer_stack[i];
assert(b->trace_id != id || !b->is_traced);
}
}

Expand Down Expand Up @@ -575,8 +740,11 @@ namespace {
}
}
~_noname() {
if(manager)
if(manager) {
// this is at the end of the program so don't print this jumk
threadl_tracer_stack.clear();
manager->print_info();
}
}
} _noinst;
}
Expand Down
3 changes: 2 additions & 1 deletion src/simple_compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ uint64_t* SimpleCompiler::MakeCounter() {
//auto op = x86::ptr_abs((Ptr)cptr);
auto op = x86::ptr(label);
op.setSize(8);
add(op, 1);
inc(op); // use inc instead of add since this won't change the eflags
//add(op, 1);
//assert(0);

return cptr;
Expand Down
Loading

0 comments on commit 5fbfcb5

Please sign in to comment.