Locking around some JIT stuff.

Excessive for now, but safer.
This commit is contained in:
Ben Vanik 2013-10-16 21:32:20 -07:00
parent 8e37fb8502
commit c53db98517
4 changed files with 18 additions and 1 deletions

View File

@ -50,6 +50,7 @@ Processor::Processor(xe_memory_ref memory, shared_ptr<Backend> backend) :
interrupt_thread_lock_(NULL), interrupt_thread_state_(NULL) { interrupt_thread_lock_(NULL), interrupt_thread_state_(NULL) {
memory_ = xe_memory_retain(memory); memory_ = xe_memory_retain(memory);
backend_ = backend; backend_ = backend;
sym_lock_ = xe_mutex_alloc(10000);
InitializeIfNeeded(); InitializeIfNeeded();
} }
@ -71,6 +72,7 @@ Processor::~Processor() {
delete jit_; delete jit_;
delete sym_table_; delete sym_table_;
xe_mutex_free(sym_lock_);
graphics_system_.reset(); graphics_system_.reset();
export_resolver_.reset(); export_resolver_.reset();
@ -158,7 +160,9 @@ int Processor::LoadRawBinary(const xechar_t* path, uint32_t start_address) {
// Initialize the module and prepare it for execution. // Initialize the module and prepare it for execution.
XEEXPECTZERO(jit_->InitModule(exec_module)); XEEXPECTZERO(jit_->InitModule(exec_module));
xe_mutex_lock(sym_lock_);
modules_.push_back(exec_module); modules_.push_back(exec_module);
xe_mutex_unlock(sym_lock_);
result_code = 0; result_code = 0;
XECLEANUP: XECLEANUP:
@ -183,7 +187,9 @@ int Processor::LoadXexModule(const char* name, const char* path,
// Initialize the module and prepare it for execution. // Initialize the module and prepare it for execution.
XEEXPECTZERO(jit_->InitModule(exec_module)); XEEXPECTZERO(jit_->InitModule(exec_module));
xe_mutex_lock(sym_lock_);
modules_.push_back(exec_module); modules_.push_back(exec_module);
xe_mutex_unlock(sym_lock_);
result_code = 0; result_code = 0;
XECLEANUP: XECLEANUP:
@ -264,6 +270,7 @@ uint64_t Processor::ExecuteInterrupt(uint32_t address,
FunctionSymbol* Processor::GetFunction(uint32_t address) { FunctionSymbol* Processor::GetFunction(uint32_t address) {
// Attempt to grab the function symbol from the global lookup table. // Attempt to grab the function symbol from the global lookup table.
// The symbol table takes a lock so it should be safe.
FunctionSymbol* fn_symbol = sym_table_->GetFunction(address); FunctionSymbol* fn_symbol = sym_table_->GetFunction(address);
if (fn_symbol) { if (fn_symbol) {
return fn_symbol; return fn_symbol;
@ -274,13 +281,16 @@ FunctionSymbol* Processor::GetFunction(uint32_t address) {
// symbol is not found (likely) it will do analysis on it. // symbol is not found (likely) it will do analysis on it.
// TODO(benvanik): make this more efficient. Could use a binary search or // TODO(benvanik): make this more efficient. Could use a binary search or
// something more clever. // something more clever.
xe_mutex_lock(sym_lock_);
for (std::vector<ExecModule*>::iterator it = modules_.begin(); for (std::vector<ExecModule*>::iterator it = modules_.begin();
it != modules_.end(); ++it) { it != modules_.end(); ++it) {
fn_symbol = (*it)->FindFunctionSymbol(address); fn_symbol = (*it)->FindFunctionSymbol(address);
if (fn_symbol) { if (fn_symbol) {
xe_mutex_unlock(sym_lock_);
return fn_symbol; return fn_symbol;
} }
} }
xe_mutex_unlock(sym_lock_);
// Not found at all? That seems wrong... // Not found at all? That seems wrong...
XEASSERTALWAYS(); XEASSERTALWAYS();

View File

@ -76,6 +76,7 @@ private:
sdb::SymbolTable* sym_table_; sdb::SymbolTable* sym_table_;
JIT* jit_; JIT* jit_;
std::vector<ExecModule*> modules_; std::vector<ExecModule*> modules_;
xe_mutex_t* sym_lock_;
xe_mutex_t* interrupt_thread_lock_; xe_mutex_t* interrupt_thread_lock_;
ThreadState* interrupt_thread_state_; ThreadState* interrupt_thread_state_;

View File

@ -27,10 +27,12 @@ using namespace AsmJit;
X64JIT::X64JIT(xe_memory_ref memory, SymbolTable* sym_table) : X64JIT::X64JIT(xe_memory_ref memory, SymbolTable* sym_table) :
JIT(memory, sym_table), JIT(memory, sym_table),
emitter_(NULL) { emitter_(NULL) {
jit_lock_ = xe_mutex_alloc(10000);
} }
X64JIT::~X64JIT() { X64JIT::~X64JIT() {
delete emitter_; delete emitter_;
xe_mutex_free(jit_lock_);
} }
int X64JIT::Setup() { int X64JIT::Setup() {
@ -160,17 +162,20 @@ int X64JIT::UninitModule(ExecModule* module) {
void* X64JIT::GetFunctionPointer(sdb::FunctionSymbol* fn_symbol) { void* X64JIT::GetFunctionPointer(sdb::FunctionSymbol* fn_symbol) {
// Check function. // Check function.
// TODO(benvanik): make this lock-free (or spin).
xe_mutex_lock(jit_lock_);
x64_function_t fn_ptr = (x64_function_t)fn_symbol->impl_value; x64_function_t fn_ptr = (x64_function_t)fn_symbol->impl_value;
if (!fn_ptr) { if (!fn_ptr) {
// Function hasn't been prepped yet - make it now inline. // Function hasn't been prepped yet - make it now inline.
// The emitter will lock and do other fancy things, if required. // The emitter will lock and do other fancy things, if required.
if (emitter_->PrepareFunction(fn_symbol)) { if (emitter_->PrepareFunction(fn_symbol)) {
xe_mutex_unlock(jit_lock_);
return NULL; return NULL;
} }
fn_ptr = (x64_function_t)fn_symbol->impl_value; fn_ptr = (x64_function_t)fn_symbol->impl_value;
XEASSERTNOTNULL(fn_ptr); XEASSERTNOTNULL(fn_ptr);
} }
xe_mutex_unlock(jit_lock_);
return fn_ptr; return fn_ptr;
} }

View File

@ -43,6 +43,7 @@ protected:
int CheckProcessor(); int CheckProcessor();
void DumpCPUInfo(); void DumpCPUInfo();
xe_mutex_t* jit_lock_;
X64Emitter* emitter_; X64Emitter* emitter_;
}; };