Initial Alloy implementation.
This is a regression in functionality and performance, but a much better foundation for the future of the project (I think). It can run basic apps under an SSA interpreter but doesn't support some of the features required to do real 360 apps yet.
This commit is contained in:
74
src/alloy/runtime/entry_table.cc
Normal file
74
src/alloy/runtime/entry_table.cc
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <alloy/runtime/entry_table.h>
|
||||
|
||||
using namespace alloy;
|
||||
using namespace alloy::runtime;
|
||||
|
||||
|
||||
EntryTable::EntryTable() {
|
||||
lock_ = AllocMutex(10000);
|
||||
}
|
||||
|
||||
EntryTable::~EntryTable() {
|
||||
LockMutex(lock_);
|
||||
EntryMap::iterator it = map_.begin();
|
||||
for (; it != map_.end(); ++it) {
|
||||
Entry* entry = it->second;
|
||||
delete entry;
|
||||
}
|
||||
UnlockMutex(lock_);
|
||||
FreeMutex(lock_);
|
||||
}
|
||||
|
||||
Entry* EntryTable::Get(uint64_t address) {
|
||||
LockMutex(lock_);
|
||||
EntryMap::const_iterator it = map_.find(address);
|
||||
Entry* entry = it != map_.end() ? it->second : NULL;
|
||||
if (entry) {
|
||||
// TODO(benvanik): wait if needed?
|
||||
if (entry->status != Entry::STATUS_READY) {
|
||||
entry = NULL;
|
||||
}
|
||||
}
|
||||
UnlockMutex(lock_);
|
||||
return entry;
|
||||
}
|
||||
|
||||
Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) {
|
||||
LockMutex(lock_);
|
||||
EntryMap::const_iterator it = map_.find(address);
|
||||
Entry* entry = it != map_.end() ? it->second : NULL;
|
||||
Entry::Status status;
|
||||
if (entry) {
|
||||
// If we aren't ready yet spin and wait.
|
||||
if (entry->status == Entry::STATUS_COMPILING) {
|
||||
// Still compiling, so spin.
|
||||
do {
|
||||
UnlockMutex(lock_);
|
||||
// TODO(benvanik): sleep for less time?
|
||||
Sleep(0);
|
||||
LockMutex(lock_);
|
||||
} while (entry->status == Entry::STATUS_COMPILING);
|
||||
}
|
||||
status = entry->status;
|
||||
} else {
|
||||
// Create and return for initialization.
|
||||
entry = new Entry();
|
||||
entry->address = address;
|
||||
entry->status = Entry::STATUS_COMPILING;
|
||||
entry->function = 0;
|
||||
map_[address] = entry;
|
||||
status = Entry::STATUS_NEW;
|
||||
}
|
||||
UnlockMutex(lock_);
|
||||
*out_entry = entry;
|
||||
return status;
|
||||
}
|
||||
56
src/alloy/runtime/entry_table.h
Normal file
56
src/alloy/runtime/entry_table.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ALLOY_RUNTIME_ENTRY_TABLE_H_
|
||||
#define ALLOY_RUNTIME_ENTRY_TABLE_H_
|
||||
|
||||
#include <alloy/core.h>
|
||||
|
||||
|
||||
namespace alloy {
|
||||
namespace runtime {
|
||||
|
||||
class Function;
|
||||
|
||||
|
||||
typedef struct Entry_t {
|
||||
typedef enum {
|
||||
STATUS_NEW = 0,
|
||||
STATUS_COMPILING,
|
||||
STATUS_READY,
|
||||
STATUS_FAILED,
|
||||
} Status;
|
||||
|
||||
uint64_t address;
|
||||
Status status;
|
||||
Function* function;
|
||||
} Entry;
|
||||
|
||||
|
||||
class EntryTable {
|
||||
public:
|
||||
EntryTable();
|
||||
~EntryTable();
|
||||
|
||||
Entry* Get(uint64_t address);
|
||||
Entry::Status GetOrCreate(uint64_t address, Entry** out_entry);
|
||||
|
||||
private:
|
||||
// TODO(benvanik): replace with a better data structure.
|
||||
Mutex* lock_;
|
||||
typedef std::tr1::unordered_map<uint64_t, Entry*> EntryMap;
|
||||
EntryMap map_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace runtime
|
||||
} // namespace alloy
|
||||
|
||||
|
||||
#endif // ALLOY_RUNTIME_ENTRY_TABLE_H_
|
||||
62
src/alloy/runtime/function.cc
Normal file
62
src/alloy/runtime/function.cc
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <alloy/runtime/function.h>
|
||||
|
||||
#include <alloy/runtime/symbol_info.h>
|
||||
#include <alloy/runtime/thread_state.h>
|
||||
|
||||
using namespace alloy;
|
||||
using namespace alloy::runtime;
|
||||
|
||||
|
||||
Function::Function(Type type, uint64_t address) :
|
||||
type_(type), address_(address) {
|
||||
}
|
||||
|
||||
Function::~Function() {
|
||||
}
|
||||
|
||||
int Function::Call(ThreadState* thread_state) {
|
||||
ThreadState* original_thread_state = ThreadState::Get();
|
||||
if (original_thread_state != thread_state) {
|
||||
ThreadState::Bind(thread_state);
|
||||
}
|
||||
int result = CallImpl(thread_state);
|
||||
if (original_thread_state != thread_state) {
|
||||
ThreadState::Bind(original_thread_state);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ExternFunction::ExternFunction(
|
||||
uint64_t address, Handler handler, void* arg0, void* arg1) :
|
||||
handler_(handler), arg0_(arg0), arg1_(arg1),
|
||||
Function(Function::EXTERN_FUNCTION, address) {
|
||||
}
|
||||
|
||||
ExternFunction::~ExternFunction() {
|
||||
}
|
||||
|
||||
int ExternFunction::CallImpl(ThreadState* thread_state) {
|
||||
if (!handler_) {
|
||||
XELOGW("undefined extern call to %.8X", address());
|
||||
return 0;
|
||||
}
|
||||
handler_(thread_state->raw_context(), arg0_, arg1_);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GuestFunction::GuestFunction(FunctionInfo* symbol_info) :
|
||||
symbol_info_(symbol_info),
|
||||
Function(Function::USER_FUNCTION, symbol_info->address()) {
|
||||
}
|
||||
|
||||
GuestFunction::~GuestFunction() {
|
||||
}
|
||||
85
src/alloy/runtime/function.h
Normal file
85
src/alloy/runtime/function.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ALLOY_RUNTIME_FUNCTION_H_
|
||||
#define ALLOY_RUNTIME_FUNCTION_H_
|
||||
|
||||
#include <alloy/core.h>
|
||||
|
||||
|
||||
namespace alloy {
|
||||
namespace runtime {
|
||||
|
||||
class FunctionInfo;
|
||||
class ThreadState;
|
||||
|
||||
|
||||
class Function {
|
||||
public:
|
||||
enum Type {
|
||||
UNKNOWN_FUNCTION = 0,
|
||||
EXTERN_FUNCTION,
|
||||
USER_FUNCTION,
|
||||
};
|
||||
public:
|
||||
Function(Type type, uint64_t address);
|
||||
virtual ~Function();
|
||||
|
||||
Type type() const { return type_; }
|
||||
uint64_t address() const { return address_; }
|
||||
|
||||
int Call(ThreadState* thread_state);
|
||||
|
||||
protected:
|
||||
virtual int CallImpl(ThreadState* thread_state) = 0;
|
||||
|
||||
protected:
|
||||
Type type_;
|
||||
uint64_t address_;
|
||||
};
|
||||
|
||||
|
||||
class ExternFunction : public Function {
|
||||
public:
|
||||
typedef void(*Handler)(void* context, void* arg0, void* arg1);
|
||||
public:
|
||||
ExternFunction(uint64_t address, Handler handler, void* arg0, void* arg1);
|
||||
virtual ~ExternFunction();
|
||||
|
||||
Handler handler() const { return handler_; }
|
||||
void* arg0() const { return arg0_; }
|
||||
void* arg1() const { return arg1_; }
|
||||
|
||||
protected:
|
||||
virtual int CallImpl(ThreadState* thread_state);
|
||||
|
||||
protected:
|
||||
Handler handler_;
|
||||
void* arg0_;
|
||||
void* arg1_;
|
||||
};
|
||||
|
||||
|
||||
class GuestFunction : public Function {
|
||||
public:
|
||||
GuestFunction(FunctionInfo* symbol_info);
|
||||
virtual ~GuestFunction();
|
||||
|
||||
FunctionInfo* symbol_info() const { return symbol_info_; }
|
||||
|
||||
protected:
|
||||
FunctionInfo* symbol_info_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace runtime
|
||||
} // namespace alloy
|
||||
|
||||
|
||||
#endif // ALLOY_RUNTIME_FUNCTION_H_
|
||||
154
src/alloy/runtime/module.cc
Normal file
154
src/alloy/runtime/module.cc
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <alloy/runtime/module.h>
|
||||
|
||||
using namespace alloy;
|
||||
using namespace alloy::runtime;
|
||||
|
||||
|
||||
Module::Module(Memory* memory) :
|
||||
memory_(memory) {
|
||||
lock_ = AllocMutex(10000);
|
||||
}
|
||||
|
||||
Module::~Module() {
|
||||
LockMutex(lock_);
|
||||
SymbolMap::iterator it = map_.begin();
|
||||
for (; it != map_.end(); ++it) {
|
||||
SymbolInfo* symbol_info = it->second;
|
||||
delete symbol_info;
|
||||
}
|
||||
UnlockMutex(lock_);
|
||||
FreeMutex(lock_);
|
||||
}
|
||||
|
||||
bool Module::ContainsAddress(uint64_t address) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) {
|
||||
LockMutex(lock_);
|
||||
SymbolMap::const_iterator it = map_.find(address);
|
||||
SymbolInfo* symbol_info = it != map_.end() ? it->second : NULL;
|
||||
if (symbol_info) {
|
||||
if (symbol_info->status() == SymbolInfo::STATUS_DECLARING) {
|
||||
// Some other thread is declaring the symbol - wait.
|
||||
if (wait) {
|
||||
do {
|
||||
UnlockMutex(lock_);
|
||||
// TODO(benvanik): sleep for less time?
|
||||
Sleep(0);
|
||||
LockMutex(lock_);
|
||||
} while (symbol_info->status() == SymbolInfo::STATUS_DECLARING);
|
||||
} else {
|
||||
// Immediate request, just return.
|
||||
symbol_info = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
UnlockMutex(lock_);
|
||||
return symbol_info;
|
||||
}
|
||||
|
||||
SymbolInfo::Status Module::DeclareSymbol(
|
||||
SymbolInfo::Type type, uint64_t address, SymbolInfo** out_symbol_info) {
|
||||
*out_symbol_info = NULL;
|
||||
LockMutex(lock_);
|
||||
SymbolMap::const_iterator it = map_.find(address);
|
||||
SymbolInfo* symbol_info = it != map_.end() ? it->second : NULL;
|
||||
SymbolInfo::Status status;
|
||||
if (symbol_info) {
|
||||
// If we exist but are the wrong type, die.
|
||||
if (symbol_info->type() != type) {
|
||||
UnlockMutex(lock_);
|
||||
return SymbolInfo::STATUS_FAILED;
|
||||
}
|
||||
// If we aren't ready yet spin and wait.
|
||||
if (symbol_info->status() == SymbolInfo::STATUS_DECLARING) {
|
||||
// Still declaring, so spin.
|
||||
do {
|
||||
UnlockMutex(lock_);
|
||||
// TODO(benvanik): sleep for less time?
|
||||
Sleep(0);
|
||||
LockMutex(lock_);
|
||||
} while (symbol_info->status() == SymbolInfo::STATUS_DECLARING);
|
||||
}
|
||||
status = symbol_info->status();
|
||||
} else {
|
||||
// Create and return for initialization.
|
||||
switch (type) {
|
||||
case SymbolInfo::TYPE_FUNCTION:
|
||||
symbol_info = new FunctionInfo(this, address);
|
||||
break;
|
||||
case SymbolInfo::TYPE_VARIABLE:
|
||||
symbol_info = new VariableInfo(this, address);
|
||||
break;
|
||||
}
|
||||
map_[address] = symbol_info;
|
||||
status = SymbolInfo::STATUS_NEW;
|
||||
}
|
||||
UnlockMutex(lock_);
|
||||
*out_symbol_info = symbol_info;
|
||||
|
||||
// Get debug info from providers, if this is new.
|
||||
if (status == SymbolInfo::STATUS_NEW) {
|
||||
// TODO(benvanik): lookup in map data/dwarf/etc?
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SymbolInfo::Status Module::DeclareFunction(
|
||||
uint64_t address, FunctionInfo** out_symbol_info) {
|
||||
SymbolInfo* symbol_info;
|
||||
SymbolInfo::Status status = DeclareSymbol(
|
||||
SymbolInfo::TYPE_FUNCTION, address, &symbol_info);
|
||||
*out_symbol_info = (FunctionInfo*)symbol_info;
|
||||
return status;
|
||||
}
|
||||
|
||||
SymbolInfo::Status Module::DeclareVariable(
|
||||
uint64_t address, VariableInfo** out_symbol_info) {
|
||||
SymbolInfo* symbol_info;
|
||||
SymbolInfo::Status status = DeclareSymbol(
|
||||
SymbolInfo::TYPE_VARIABLE, address, &symbol_info);
|
||||
*out_symbol_info = (VariableInfo*)symbol_info;
|
||||
return status;
|
||||
}
|
||||
|
||||
SymbolInfo::Status Module::DefineSymbol(SymbolInfo* symbol_info) {
|
||||
LockMutex(lock_);
|
||||
SymbolInfo::Status status;
|
||||
if (symbol_info->status() == SymbolInfo::STATUS_DECLARED) {
|
||||
// Declared but undefined, so request caller define it.
|
||||
symbol_info->set_status(SymbolInfo::STATUS_DEFINING);
|
||||
status = SymbolInfo::STATUS_NEW;
|
||||
} else if (symbol_info->status() == SymbolInfo::STATUS_DEFINING) {
|
||||
// Still defining, so spin.
|
||||
do {
|
||||
UnlockMutex(lock_);
|
||||
// TODO(benvanik): sleep for less time?
|
||||
Sleep(0);
|
||||
LockMutex(lock_);
|
||||
} while (symbol_info->status() == SymbolInfo::STATUS_DEFINING);
|
||||
} else {
|
||||
status = symbol_info->status();
|
||||
}
|
||||
UnlockMutex(lock_);
|
||||
return status;
|
||||
}
|
||||
|
||||
SymbolInfo::Status Module::DefineFunction(FunctionInfo* symbol_info) {
|
||||
return DefineSymbol((SymbolInfo*)symbol_info);
|
||||
}
|
||||
|
||||
SymbolInfo::Status Module::DefineVariable(VariableInfo* symbol_info) {
|
||||
return DefineSymbol((SymbolInfo*)symbol_info);
|
||||
}
|
||||
64
src/alloy/runtime/module.h
Normal file
64
src/alloy/runtime/module.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ALLOY_RUNTIME_MODULE_H_
|
||||
#define ALLOY_RUNTIME_MODULE_H_
|
||||
|
||||
#include <alloy/core.h>
|
||||
#include <alloy/memory.h>
|
||||
#include <alloy/runtime/symbol_info.h>
|
||||
|
||||
|
||||
namespace alloy {
|
||||
namespace runtime {
|
||||
|
||||
class Function;
|
||||
|
||||
|
||||
class Module {
|
||||
public:
|
||||
Module(Memory* memory);
|
||||
virtual ~Module();
|
||||
|
||||
Memory* memory() const { return memory_; }
|
||||
|
||||
virtual const char* name() const = 0;
|
||||
|
||||
virtual bool ContainsAddress(uint64_t address);
|
||||
|
||||
SymbolInfo* LookupSymbol(uint64_t address, bool wait = true);
|
||||
SymbolInfo::Status DeclareFunction(
|
||||
uint64_t address, FunctionInfo** out_symbol_info);
|
||||
SymbolInfo::Status DeclareVariable(
|
||||
uint64_t address, VariableInfo** out_symbol_info);
|
||||
|
||||
SymbolInfo::Status DefineFunction(FunctionInfo* symbol_info);
|
||||
SymbolInfo::Status DefineVariable(VariableInfo* symbol_info);
|
||||
|
||||
private:
|
||||
SymbolInfo::Status DeclareSymbol(
|
||||
SymbolInfo::Type type, uint64_t address, SymbolInfo** out_symbol_info);
|
||||
SymbolInfo::Status DefineSymbol(SymbolInfo* symbol_info);
|
||||
|
||||
protected:
|
||||
Memory* memory_;
|
||||
|
||||
private:
|
||||
// TODO(benvanik): replace with a better data structure.
|
||||
Mutex* lock_;
|
||||
typedef std::tr1::unordered_map<uint64_t, SymbolInfo*> SymbolMap;
|
||||
SymbolMap map_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace runtime
|
||||
} // namespace alloy
|
||||
|
||||
|
||||
#endif // ALLOY_RUNTIME_MODULE_H_
|
||||
61
src/alloy/runtime/raw_module.cc
Normal file
61
src/alloy/runtime/raw_module.cc
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <alloy/runtime/raw_module.h>
|
||||
|
||||
using namespace alloy;
|
||||
using namespace alloy::runtime;
|
||||
|
||||
|
||||
RawModule::RawModule(Memory* memory) :
|
||||
name_(0),
|
||||
base_address_(0), low_address_(0), high_address_(0),
|
||||
Module(memory) {
|
||||
}
|
||||
|
||||
RawModule::~RawModule() {
|
||||
if (base_address_) {
|
||||
memory_->HeapFree(base_address_, high_address_ - low_address_);
|
||||
}
|
||||
xe_free(name_);
|
||||
}
|
||||
|
||||
int RawModule::LoadFile(uint64_t base_address, const char* path) {
|
||||
FILE* file = fopen(path, "rb");
|
||||
fseek(file, 0, SEEK_END);
|
||||
size_t file_length = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
// Allocate memory.
|
||||
base_address_ = memory_->HeapAlloc(
|
||||
base_address, file_length, MEMORY_FLAG_ZERO);
|
||||
if (!base_address_) {
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read into memory.
|
||||
uint8_t* p = memory_->Translate(base_address_);
|
||||
fread(p, file_length, 1, file);
|
||||
|
||||
fclose(file);
|
||||
|
||||
// Setup debug info.
|
||||
const char* name = xestrrchra(path, XE_PATH_SEPARATOR) + 1;
|
||||
name_ = xestrdupa(name);
|
||||
// TODO(benvanik): debug info
|
||||
|
||||
low_address_ = base_address;
|
||||
high_address_ = base_address + file_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool RawModule::ContainsAddress(uint64_t address) {
|
||||
return address >= low_address_ && address < high_address_;
|
||||
}
|
||||
43
src/alloy/runtime/raw_module.h
Normal file
43
src/alloy/runtime/raw_module.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ALLOY_RUNTIME_RAW_MODULE_H_
|
||||
#define ALLOY_RUNTIME_RAW_MODULE_H_
|
||||
|
||||
#include <alloy/runtime/module.h>
|
||||
|
||||
|
||||
namespace alloy {
|
||||
namespace runtime {
|
||||
|
||||
|
||||
class RawModule : public Module {
|
||||
public:
|
||||
RawModule(Memory* memory);
|
||||
virtual ~RawModule();
|
||||
|
||||
int LoadFile(uint64_t base_address, const char* path);
|
||||
|
||||
virtual const char* name() const { return name_; }
|
||||
|
||||
virtual bool ContainsAddress(uint64_t address);
|
||||
|
||||
private:
|
||||
char* name_;
|
||||
uint64_t base_address_;
|
||||
uint64_t low_address_;
|
||||
uint64_t high_address_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace runtime
|
||||
} // namespace alloy
|
||||
|
||||
|
||||
#endif // ALLOY_RUNTIME_RAW_MODULE_H_
|
||||
36
src/alloy/runtime/register_access.h
Normal file
36
src/alloy/runtime/register_access.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ALLOY_RUNTIME_REGISTER_ACCESS_H_
|
||||
#define ALLOY_RUNTIME_REGISTER_ACCESS_H_
|
||||
|
||||
#include <alloy/core.h>
|
||||
|
||||
|
||||
namespace alloy {
|
||||
namespace runtime {
|
||||
|
||||
typedef bool (*RegisterHandlesCallback)(void* context, uint64_t addr);
|
||||
typedef uint64_t (*RegisterReadCallback)(void* context, uint64_t addr);
|
||||
typedef void (*RegisterWriteCallback)(void* context, uint64_t addr,
|
||||
uint64_t value);
|
||||
|
||||
typedef struct {
|
||||
void* context;
|
||||
RegisterHandlesCallback handles;
|
||||
RegisterReadCallback read;
|
||||
RegisterWriteCallback write;
|
||||
} RegisterAccessCallbacks;
|
||||
|
||||
|
||||
} // namespace runtime
|
||||
} // namespace alloy
|
||||
|
||||
|
||||
#endif // ALLOY_RUNTIME_REGISTER_ACCESS_H_
|
||||
218
src/alloy/runtime/runtime.cc
Normal file
218
src/alloy/runtime/runtime.cc
Normal file
@@ -0,0 +1,218 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <alloy/runtime/runtime.h>
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
#include <alloy/runtime/module.h>
|
||||
#include <alloy/runtime/tracing.h>
|
||||
|
||||
using namespace alloy;
|
||||
using namespace alloy::backend;
|
||||
using namespace alloy::frontend;
|
||||
using namespace alloy::runtime;
|
||||
|
||||
|
||||
DEFINE_string(runtime_backend, "any",
|
||||
"Runtime backend [any, ivm, x64].");
|
||||
|
||||
|
||||
Runtime::Runtime(Memory* memory) :
|
||||
memory_(memory), backend_(0), frontend_(0) {
|
||||
tracing::Initialize();
|
||||
modules_lock_ = AllocMutex(10000);
|
||||
}
|
||||
|
||||
Runtime::~Runtime() {
|
||||
LockMutex(modules_lock_);
|
||||
for (ModuleList::iterator it = modules_.begin();
|
||||
it != modules_.end(); ++it) {
|
||||
Module* module = *it;
|
||||
delete module;
|
||||
}
|
||||
UnlockMutex(modules_lock_);
|
||||
FreeMutex(modules_lock_);
|
||||
|
||||
delete frontend_;
|
||||
delete backend_;
|
||||
|
||||
tracing::Flush();
|
||||
}
|
||||
|
||||
// TODO(benvanik): based on compiler support
|
||||
#include <alloy/backend/ivm/ivm_backend.h>
|
||||
|
||||
int Runtime::Initialize(Frontend* frontend, Backend* backend) {
|
||||
// Must be initialized by subclass before calling into this.
|
||||
XEASSERTNOTNULL(memory_);
|
||||
|
||||
int result = memory_->Initialize();
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (frontend_ || backend_) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!backend) {
|
||||
#if defined(ALLOY_HAS_IVM_BACKEND) && ALLOY_HAS_IVM_BACKEND
|
||||
if (FLAGS_runtime_backend == "ivm") {
|
||||
backend = new alloy::backend::ivm::IVMBackend(
|
||||
this);
|
||||
}
|
||||
#endif
|
||||
// x64/etc
|
||||
if (FLAGS_runtime_backend == "any") {
|
||||
// x64/etc
|
||||
#if defined(ALLOY_HAS_IVM_BACKEND) && ALLOY_HAS_IVM_BACKEND
|
||||
if (!backend) {
|
||||
backend = new alloy::backend::ivm::IVMBackend(
|
||||
this);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!backend) {
|
||||
return 1;
|
||||
}
|
||||
backend_ = backend;
|
||||
frontend_ = frontend;
|
||||
|
||||
result = backend_->Initialize();
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = frontend_->Initialize();
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Runtime::AddModule(Module* module) {
|
||||
LockMutex(modules_lock_);
|
||||
modules_.push_back(module);
|
||||
UnlockMutex(modules_lock_);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Runtime::ResolveFunction(uint64_t address, Function** out_function) {
|
||||
*out_function = NULL;
|
||||
Entry* entry;
|
||||
Entry::Status status = entry_table_.GetOrCreate(address, &entry);
|
||||
if (status == Entry::STATUS_NEW) {
|
||||
// Needs to be generated. We have the 'lock' on it and must do so now.
|
||||
|
||||
// Grab symbol declaration.
|
||||
FunctionInfo* symbol_info;
|
||||
int result = LookupFunctionInfo(address, &symbol_info);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = DemandFunction(symbol_info, &entry->function);
|
||||
if (result) {
|
||||
entry->status = Entry::STATUS_FAILED;
|
||||
return result;
|
||||
}
|
||||
status = entry->status = Entry::STATUS_READY;
|
||||
}
|
||||
if (status == Entry::STATUS_READY) {
|
||||
// Ready to use.
|
||||
*out_function = entry->function;
|
||||
return 0;
|
||||
} else {
|
||||
// Failed or bad state.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int Runtime::LookupFunctionInfo(
|
||||
uint64_t address, FunctionInfo** out_symbol_info) {
|
||||
*out_symbol_info = NULL;
|
||||
|
||||
// TODO(benvanik): fast reject invalid addresses/log errors.
|
||||
|
||||
// Find the module that contains the address.
|
||||
Module* code_module = NULL;
|
||||
LockMutex(modules_lock_);
|
||||
// TODO(benvanik): sort by code address (if contiguous) so can bsearch.
|
||||
// TODO(benvanik): cache last module low/high, as likely to be in there.
|
||||
for (ModuleList::const_iterator it = modules_.begin();
|
||||
it != modules_.end(); ++it) {
|
||||
Module* module = *it;
|
||||
if (module->ContainsAddress(address)) {
|
||||
code_module = module;
|
||||
break;
|
||||
}
|
||||
}
|
||||
UnlockMutex(modules_lock_);
|
||||
if (!code_module) {
|
||||
// No module found that could contain the address.
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Atomic create/lookup symbol in module.
|
||||
// If we get back the NEW flag we must declare it now.
|
||||
FunctionInfo* symbol_info = NULL;
|
||||
SymbolInfo::Status symbol_status =
|
||||
code_module->DeclareFunction(address, &symbol_info);
|
||||
if (symbol_status == SymbolInfo::STATUS_NEW) {
|
||||
// Symbol is undeclared, so declare now.
|
||||
int result = frontend_->DeclareFunction(symbol_info);
|
||||
if (result) {
|
||||
symbol_info->set_status(SymbolInfo::STATUS_FAILED);
|
||||
return 1;
|
||||
}
|
||||
symbol_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||
}
|
||||
|
||||
*out_symbol_info = symbol_info;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Runtime::DemandFunction(
|
||||
FunctionInfo* symbol_info, Function** out_function) {
|
||||
*out_function = NULL;
|
||||
|
||||
// Lock function for generation. If it's already being generated
|
||||
// by another thread this will block and return DECLARED.
|
||||
Module* module = symbol_info->module();
|
||||
SymbolInfo::Status symbol_status = module->DefineFunction(symbol_info);
|
||||
if (symbol_status == SymbolInfo::STATUS_NEW) {
|
||||
// Symbol is undefined, so define now.
|
||||
Function* function = NULL;
|
||||
int result = frontend_->DefineFunction(symbol_info, &function);
|
||||
if (result) {
|
||||
symbol_info->set_status(SymbolInfo::STATUS_FAILED);
|
||||
return result;
|
||||
}
|
||||
symbol_info->set_function(function);
|
||||
symbol_info->set_status(SymbolInfo::STATUS_DEFINED);
|
||||
symbol_status = symbol_info->status();
|
||||
}
|
||||
|
||||
if (symbol_status == SymbolInfo::STATUS_FAILED) {
|
||||
// Symbol likely failed.
|
||||
return 1;
|
||||
}
|
||||
|
||||
*out_function = symbol_info->function();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Runtime::AddRegisterAccessCallbacks(RegisterAccessCallbacks callbacks) {
|
||||
//
|
||||
}
|
||||
68
src/alloy/runtime/runtime.h
Normal file
68
src/alloy/runtime/runtime.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ALLOY_RUNTIME_RUNTIME_H_
|
||||
#define ALLOY_RUNTIME_RUNTIME_H_
|
||||
|
||||
#include <alloy/core.h>
|
||||
#include <alloy/memory.h>
|
||||
#include <alloy/backend/backend.h>
|
||||
#include <alloy/frontend/frontend.h>
|
||||
#include <alloy/runtime/entry_table.h>
|
||||
#include <alloy/runtime/module.h>
|
||||
#include <alloy/runtime/register_access.h>
|
||||
#include <alloy/runtime/symbol_info.h>
|
||||
#include <alloy/runtime/thread_state.h>
|
||||
|
||||
|
||||
namespace alloy {
|
||||
namespace runtime {
|
||||
|
||||
|
||||
class Runtime {
|
||||
public:
|
||||
Runtime(Memory* memory);
|
||||
virtual ~Runtime();
|
||||
|
||||
Memory* memory() const { return memory_; }
|
||||
frontend::Frontend* frontend() const { return frontend_; }
|
||||
backend::Backend* backend() const { return backend_; }
|
||||
|
||||
int Initialize(frontend::Frontend* frontend, backend::Backend* backend = 0);
|
||||
|
||||
int AddModule(Module* module);
|
||||
|
||||
int LookupFunctionInfo(uint64_t address, FunctionInfo** out_symbol_info);
|
||||
int ResolveFunction(uint64_t address, Function** out_function);
|
||||
|
||||
void AddRegisterAccessCallbacks(RegisterAccessCallbacks callbacks);
|
||||
|
||||
//uint32_t CreateCallback(void (*callback)(void* data), void* data);
|
||||
|
||||
private:
|
||||
int DemandFunction(FunctionInfo* symbol_info, Function** out_function);
|
||||
|
||||
protected:
|
||||
Memory* memory_;
|
||||
|
||||
frontend::Frontend* frontend_;
|
||||
backend::Backend* backend_;
|
||||
|
||||
EntryTable entry_table_;
|
||||
Mutex* modules_lock_;
|
||||
typedef std::vector<Module*> ModuleList;
|
||||
ModuleList modules_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace runtime
|
||||
} // namespace alloy
|
||||
|
||||
|
||||
#endif // ALLOY_RUNTIME_RUNTIME_H_
|
||||
13
src/alloy/runtime/simple/sources.gypi
Normal file
13
src/alloy/runtime/simple/sources.gypi
Normal file
@@ -0,0 +1,13 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'simple_context.cc',
|
||||
'simple_context.h',
|
||||
'simple_memory.cc',
|
||||
'simple_memory.h',
|
||||
'simple_runtime.cc',
|
||||
'simple_runtime.h',
|
||||
'simple_thread_state.cc',
|
||||
'simple_thread_state.h',
|
||||
],
|
||||
}
|
||||
25
src/alloy/runtime/sources.gypi
Normal file
25
src/alloy/runtime/sources.gypi
Normal file
@@ -0,0 +1,25 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'entry_table.cc',
|
||||
'entry_table.h',
|
||||
'function.cc',
|
||||
'function.h',
|
||||
'module.cc',
|
||||
'module.h',
|
||||
'raw_module.cc',
|
||||
'raw_module.h',
|
||||
'register_access.h',
|
||||
'runtime.cc',
|
||||
'runtime.h',
|
||||
'symbol_info.cc',
|
||||
'symbol_info.h',
|
||||
'thread_state.cc',
|
||||
'thread_state.h',
|
||||
'tracing.h',
|
||||
],
|
||||
|
||||
'includes': [
|
||||
#'simple/sources.gypi',
|
||||
],
|
||||
}
|
||||
37
src/alloy/runtime/symbol_info.cc
Normal file
37
src/alloy/runtime/symbol_info.cc
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <alloy/runtime/symbol_info.h>
|
||||
|
||||
using namespace alloy;
|
||||
using namespace alloy::runtime;
|
||||
|
||||
|
||||
SymbolInfo::SymbolInfo(Type type, Module* module, uint64_t address) :
|
||||
type_(type), status_(STATUS_DEFINING),
|
||||
module_(module), address_(address) {
|
||||
}
|
||||
|
||||
SymbolInfo::~SymbolInfo() {
|
||||
}
|
||||
|
||||
FunctionInfo::FunctionInfo(Module* module, uint64_t address) :
|
||||
end_address_(0), function_(0),
|
||||
SymbolInfo(SymbolInfo::TYPE_FUNCTION, module, address) {
|
||||
}
|
||||
|
||||
FunctionInfo::~FunctionInfo() {
|
||||
}
|
||||
|
||||
VariableInfo::VariableInfo(Module* module, uint64_t address) :
|
||||
SymbolInfo(SymbolInfo::TYPE_VARIABLE, module, address) {
|
||||
}
|
||||
|
||||
VariableInfo::~VariableInfo() {
|
||||
}
|
||||
84
src/alloy/runtime/symbol_info.h
Normal file
84
src/alloy/runtime/symbol_info.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ALLOY_RUNTIME_SYMBOL_INFO_H_
|
||||
#define ALLOY_RUNTIME_SYMBOL_INFO_H_
|
||||
|
||||
#include <alloy/core.h>
|
||||
|
||||
|
||||
namespace alloy {
|
||||
namespace runtime {
|
||||
|
||||
class Function;
|
||||
class Module;
|
||||
|
||||
|
||||
class SymbolInfo {
|
||||
public:
|
||||
enum Type {
|
||||
TYPE_FUNCTION,
|
||||
TYPE_VARIABLE,
|
||||
};
|
||||
enum Status {
|
||||
STATUS_NEW,
|
||||
STATUS_DECLARING,
|
||||
STATUS_DECLARED,
|
||||
STATUS_DEFINING,
|
||||
STATUS_DEFINED,
|
||||
STATUS_FAILED,
|
||||
};
|
||||
public:
|
||||
SymbolInfo(Type type, Module* module, uint64_t address);
|
||||
virtual ~SymbolInfo();
|
||||
|
||||
Type type() const { return type_; }
|
||||
Module* module() const { return module_; }
|
||||
Status status() const { return status_; }
|
||||
void set_status(Status value) { status_ = value; }
|
||||
uint64_t address() const { return address_; }
|
||||
|
||||
protected:
|
||||
Type type_;
|
||||
Module* module_;
|
||||
Status status_;
|
||||
uint64_t address_;
|
||||
};
|
||||
|
||||
class FunctionInfo : public SymbolInfo {
|
||||
public:
|
||||
FunctionInfo(Module* module, uint64_t address);
|
||||
virtual ~FunctionInfo();
|
||||
|
||||
bool has_end_address() const { return end_address_ > 0; }
|
||||
uint64_t end_address() const { return end_address_; }
|
||||
void set_end_address(uint64_t value) { end_address_ = value; }
|
||||
|
||||
Function* function() const { return function_; }
|
||||
void set_function(Function* value) { function_ = value; }
|
||||
|
||||
private:
|
||||
uint64_t end_address_;
|
||||
Function* function_;
|
||||
};
|
||||
|
||||
class VariableInfo : public SymbolInfo {
|
||||
public:
|
||||
VariableInfo(Module* module, uint64_t address);
|
||||
virtual ~VariableInfo();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace runtime
|
||||
} // namespace alloy
|
||||
|
||||
|
||||
#endif // ALLOY_RUNTIME_SYMBOL_INFO_H_
|
||||
56
src/alloy/runtime/thread_state.cc
Normal file
56
src/alloy/runtime/thread_state.cc
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <alloy/runtime/thread_state.h>
|
||||
|
||||
#include <alloy/runtime/runtime.h>
|
||||
|
||||
using namespace alloy;
|
||||
using namespace alloy::runtime;
|
||||
|
||||
|
||||
namespace {
|
||||
__declspec(thread) ThreadState* thread_state_ = NULL;
|
||||
}
|
||||
|
||||
|
||||
ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id) :
|
||||
runtime_(runtime), memory_(runtime->memory()),
|
||||
thread_id_(thread_id),
|
||||
backend_data_(0), raw_context_(0) {
|
||||
if (thread_id_ == UINT_MAX) {
|
||||
// System thread. Assign the system thread ID with a high bit
|
||||
// set so people know what's up.
|
||||
uint32_t system_thread_handle = GetCurrentThreadId();
|
||||
thread_id_ = 0x80000000 | system_thread_handle;
|
||||
}
|
||||
backend_data_ = runtime->backend()->AllocThreadData();
|
||||
}
|
||||
|
||||
ThreadState::~ThreadState() {
|
||||
if (backend_data_) {
|
||||
runtime_->backend()->FreeThreadData(backend_data_);
|
||||
}
|
||||
if (thread_state_ == this) {
|
||||
thread_state_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadState::Bind(ThreadState* thread_state) {
|
||||
thread_state_ = thread_state;
|
||||
}
|
||||
|
||||
ThreadState* ThreadState::Get() {
|
||||
return thread_state_;
|
||||
}
|
||||
|
||||
uint32_t ThreadState::GetThreadID() {
|
||||
XEASSERT(thread_state_);
|
||||
return thread_state_->thread_id_;
|
||||
}
|
||||
52
src/alloy/runtime/thread_state.h
Normal file
52
src/alloy/runtime/thread_state.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ALLOY_RUNTIME_THREAD_STATE_H_
|
||||
#define ALLOY_RUNTIME_THREAD_STATE_H_
|
||||
|
||||
#include <alloy/core.h>
|
||||
|
||||
#include <alloy/memory.h>
|
||||
|
||||
|
||||
namespace alloy {
|
||||
namespace runtime {
|
||||
|
||||
class Runtime;
|
||||
|
||||
|
||||
class ThreadState {
|
||||
public:
|
||||
ThreadState(Runtime* runtime, uint32_t thread_id);
|
||||
virtual ~ThreadState();
|
||||
|
||||
Runtime* runtime() const { return runtime_; }
|
||||
Memory* memory() const { return memory_; }
|
||||
uint32_t thread_id() const { return thread_id_; }
|
||||
void* backend_data() const { return backend_data_; }
|
||||
void* raw_context() const { return raw_context_; }
|
||||
|
||||
static void Bind(ThreadState* thread_state);
|
||||
static ThreadState* Get();
|
||||
static uint32_t GetThreadID();
|
||||
|
||||
protected:
|
||||
Runtime* runtime_;
|
||||
Memory* memory_;
|
||||
uint32_t thread_id_;
|
||||
void* backend_data_;
|
||||
void* raw_context_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace runtime
|
||||
} // namespace alloy
|
||||
|
||||
|
||||
#endif // ALLOY_RUNTIME_THREAD_STATE_H_
|
||||
94
src/alloy/runtime/tracing.h
Normal file
94
src/alloy/runtime/tracing.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ALLOY_RUNTIME_TRACING_H_
|
||||
#define ALLOY_RUNTIME_TRACING_H_
|
||||
|
||||
#include <alloy/tracing/tracing.h>
|
||||
#include <alloy/tracing/event_type.h>
|
||||
|
||||
|
||||
namespace alloy {
|
||||
namespace runtime {
|
||||
|
||||
const uint32_t ALLOY_RUNTIME = alloy::tracing::EventType::ALLOY_RUNTIME;
|
||||
|
||||
|
||||
class EventType {
|
||||
public:
|
||||
enum {
|
||||
ALLOY_RUNTIME_INIT = ALLOY_RUNTIME | (1),
|
||||
ALLOY_RUNTIME_DEINIT = ALLOY_RUNTIME | (2),
|
||||
|
||||
ALLOY_RUNTIME_THREAD = ALLOY_RUNTIME | (1 << 25),
|
||||
ALLOY_RUNTIME_THREAD_INIT = ALLOY_RUNTIME_THREAD | (1),
|
||||
ALLOY_RUNTIME_THREAD_DEINIT = ALLOY_RUNTIME_THREAD | (2),
|
||||
|
||||
ALLOY_RUNTIME_MEMORY = ALLOY_RUNTIME | (2 << 25),
|
||||
ALLOY_RUNTIME_MEMORY_INIT = ALLOY_RUNTIME_MEMORY | (1),
|
||||
ALLOY_RUNTIME_MEMORY_DEINIT = ALLOY_RUNTIME_MEMORY | (2),
|
||||
ALLOY_RUNTIME_MEMORY_HEAP = ALLOY_RUNTIME_MEMORY | (1000),
|
||||
ALLOY_RUNTIME_MEMORY_HEAP_INIT = ALLOY_RUNTIME_MEMORY_HEAP | (1),
|
||||
ALLOY_RUNTIME_MEMORY_HEAP_DEINIT = ALLOY_RUNTIME_MEMORY | (2),
|
||||
ALLOY_RUNTIME_MEMORY_HEAP_ALLOC = ALLOY_RUNTIME_MEMORY | (3),
|
||||
ALLOY_RUNTIME_MEMORY_HEAP_FREE = ALLOY_RUNTIME_MEMORY | (4),
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
static const uint32_t event_type = ALLOY_RUNTIME_INIT;
|
||||
} Init;
|
||||
typedef struct {
|
||||
static const uint32_t event_type = ALLOY_RUNTIME_DEINIT;
|
||||
} Deinit;
|
||||
|
||||
typedef struct {
|
||||
static const uint32_t event_type = ALLOY_RUNTIME_THREAD_INIT;
|
||||
} ThreadInit;
|
||||
typedef struct {
|
||||
static const uint32_t event_type = ALLOY_RUNTIME_THREAD_DEINIT;
|
||||
} ThreadDeinit;
|
||||
|
||||
typedef struct {
|
||||
static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_INIT;
|
||||
// map of memory, etc?
|
||||
} MemoryInit;
|
||||
typedef struct {
|
||||
static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_DEINIT;
|
||||
} MemoryDeinit;
|
||||
typedef struct {
|
||||
static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_INIT;
|
||||
uint32_t heap_id;
|
||||
uint64_t low_address;
|
||||
uint64_t high_address;
|
||||
uint32_t is_physical;
|
||||
} MemoryHeapInit;
|
||||
typedef struct {
|
||||
static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_DEINIT;
|
||||
uint32_t heap_id;
|
||||
} MemoryHeapDeinit;
|
||||
typedef struct {
|
||||
static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_ALLOC;
|
||||
uint32_t heap_id;
|
||||
uint32_t flags;
|
||||
uint64_t address;
|
||||
size_t size;
|
||||
} MemoryHeapAlloc;
|
||||
typedef struct {
|
||||
static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_FREE;
|
||||
uint32_t heap_id;
|
||||
uint64_t address;
|
||||
} MemoryHeapFree;
|
||||
};
|
||||
|
||||
|
||||
} // namespace runtime
|
||||
} // namespace alloy
|
||||
|
||||
|
||||
#endif // ALLOY_RUNTIME_TRACING_H_
|
||||
Reference in New Issue
Block a user