Caching function list and only sending deltas.
This commit is contained in:
parent
1c9fb97b5e
commit
d368e0cb74
|
@ -64,6 +64,7 @@ module.service('DataSource', function($q) {
|
||||||
|
|
||||||
this.cache_ = {
|
this.cache_ = {
|
||||||
modules: {},
|
modules: {},
|
||||||
|
moduleFunctionLists: {},
|
||||||
functions: {}
|
functions: {}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -104,10 +105,29 @@ module.service('DataSource', function($q) {
|
||||||
};
|
};
|
||||||
|
|
||||||
DataSource.prototype.getFunctionList = function(moduleName) {
|
DataSource.prototype.getFunctionList = function(moduleName) {
|
||||||
return this.issue({
|
var d = $q.defer();
|
||||||
|
var cached = this.cache_.moduleFunctionLists[moduleName];
|
||||||
|
this.issue({
|
||||||
command: 'cpu.get_function_list',
|
command: 'cpu.get_function_list',
|
||||||
module: moduleName
|
module: moduleName,
|
||||||
});
|
since: cached ? cached.version : 0
|
||||||
|
}).then((function(result) {
|
||||||
|
if (cached) {
|
||||||
|
cached.version = result.version;
|
||||||
|
for (var n = 0; n < result.list.length; n++) {
|
||||||
|
cached.list.push(result.list[n]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cached = this.cache_.moduleFunctionLists[moduleName] = {
|
||||||
|
version: result.version,
|
||||||
|
list: result.list
|
||||||
|
};
|
||||||
|
}
|
||||||
|
d.resolve(cached.list);
|
||||||
|
}).bind(this), (function(e) {
|
||||||
|
d.reject(e);
|
||||||
|
}).bind(this));
|
||||||
|
return d.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
DataSource.prototype.getFunction = function(address) {
|
DataSource.prototype.getFunction = function(address) {
|
||||||
|
|
|
@ -97,6 +97,7 @@ SymbolInfo::Status Module::DeclareSymbol(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
map_[address] = symbol_info;
|
map_[address] = symbol_info;
|
||||||
|
list_.push_back(symbol_info);
|
||||||
status = SymbolInfo::STATUS_NEW;
|
status = SymbolInfo::STATUS_NEW;
|
||||||
}
|
}
|
||||||
UnlockMutex(lock_);
|
UnlockMutex(lock_);
|
||||||
|
@ -160,10 +161,25 @@ SymbolInfo::Status Module::DefineVariable(VariableInfo* symbol_info) {
|
||||||
|
|
||||||
void Module::ForEachFunction(std::function<void (FunctionInfo*)> callback) {
|
void Module::ForEachFunction(std::function<void (FunctionInfo*)> callback) {
|
||||||
LockMutex(lock_);
|
LockMutex(lock_);
|
||||||
for (SymbolMap::iterator it = map_.begin();
|
for (auto it = list_.begin(); it != list_.end(); ++it) {
|
||||||
it != map_.end(); ++it) {
|
SymbolInfo* symbol_info = *it;
|
||||||
if (it->second->type() == SymbolInfo::TYPE_FUNCTION) {
|
if (symbol_info->type() == SymbolInfo::TYPE_FUNCTION) {
|
||||||
FunctionInfo* info = (FunctionInfo*)it->second;
|
FunctionInfo* info = (FunctionInfo*)symbol_info;
|
||||||
|
callback(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnlockMutex(lock_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::ForEachFunction(size_t since, size_t& version,
|
||||||
|
std::function<void (FunctionInfo*)> callback) {
|
||||||
|
LockMutex(lock_);
|
||||||
|
size_t count = list_.size();
|
||||||
|
version = count;
|
||||||
|
for (size_t n = since; n < count; n++) {
|
||||||
|
SymbolInfo* symbol_info = list_[n];
|
||||||
|
if (symbol_info->type() == SymbolInfo::TYPE_FUNCTION) {
|
||||||
|
FunctionInfo* info = (FunctionInfo*)symbol_info;
|
||||||
callback(info);
|
callback(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,8 @@ public:
|
||||||
SymbolInfo::Status DefineVariable(VariableInfo* symbol_info);
|
SymbolInfo::Status DefineVariable(VariableInfo* symbol_info);
|
||||||
|
|
||||||
void ForEachFunction(std::function<void (FunctionInfo*)> callback);
|
void ForEachFunction(std::function<void (FunctionInfo*)> callback);
|
||||||
|
void ForEachFunction(size_t since, size_t& version,
|
||||||
|
std::function<void (FunctionInfo*)> callback);
|
||||||
|
|
||||||
int ReadMap(const char* file_name);
|
int ReadMap(const char* file_name);
|
||||||
|
|
||||||
|
@ -62,6 +64,8 @@ private:
|
||||||
Mutex* lock_;
|
Mutex* lock_;
|
||||||
typedef std::tr1::unordered_map<uint64_t, SymbolInfo*> SymbolMap;
|
typedef std::tr1::unordered_map<uint64_t, SymbolInfo*> SymbolMap;
|
||||||
SymbolMap map_;
|
SymbolMap map_;
|
||||||
|
typedef std::vector<SymbolInfo*> SymbolList;
|
||||||
|
SymbolList list_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -225,6 +225,32 @@ void Processor::OnDebugClientDisconnected(uint32_t client_id) {
|
||||||
runtime_->debugger()->ResumeAllThreads(true);
|
runtime_->debugger()->ResumeAllThreads(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_t* json_object_set_string_new(
|
||||||
|
json_t* object, const char* key, const char* value) {
|
||||||
|
json_t* value_json = json_string(value);
|
||||||
|
json_object_set_new(object, key, value_json);
|
||||||
|
return value_json;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_t* json_object_set_string_format_new(
|
||||||
|
json_t* object, const char* key, const char* format, ...) {
|
||||||
|
char buffer[1024];
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
xevsnprintfa(buffer, XECOUNT(buffer), format, args);
|
||||||
|
va_end(args);
|
||||||
|
json_t* value_json = json_string(buffer);
|
||||||
|
json_object_set_new(object, key, value_json);
|
||||||
|
return value_json;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_t* json_object_set_integer_new(
|
||||||
|
json_t* object, const char* key, json_int_t value) {
|
||||||
|
json_t* value_json = json_integer(value);
|
||||||
|
json_object_set_new(object, key, value_json);
|
||||||
|
return value_json;
|
||||||
|
}
|
||||||
|
|
||||||
json_t* Processor::OnDebugRequest(
|
json_t* Processor::OnDebugRequest(
|
||||||
uint32_t client_id, const char* command, json_t* request,
|
uint32_t client_id, const char* command, json_t* request,
|
||||||
bool& succeeded) {
|
bool& succeeded) {
|
||||||
|
@ -240,8 +266,7 @@ json_t* Processor::OnDebugRequest(
|
||||||
for (auto it = modules.begin(); it != modules.end(); ++it) {
|
for (auto it = modules.begin(); it != modules.end(); ++it) {
|
||||||
XexModule* module = (XexModule*)(*it);
|
XexModule* module = (XexModule*)(*it);
|
||||||
json_t* module_json = json_object();
|
json_t* module_json = json_object();
|
||||||
json_t* module_name_json = json_string(module->name());
|
json_object_set_string_new(module_json, "name", module->name());
|
||||||
json_object_set_new(module_json, "name", module_name_json);
|
|
||||||
json_array_append_new(list, module_json);
|
json_array_append_new(list, module_json);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
|
@ -270,8 +295,16 @@ json_t* Processor::OnDebugRequest(
|
||||||
succeeded = false;
|
succeeded = false;
|
||||||
return json_string("Module not found");
|
return json_string("Module not found");
|
||||||
}
|
}
|
||||||
|
json_t* since_json = json_object_get(request, "since");
|
||||||
|
if (since_json && !json_is_number(since_json)) {
|
||||||
|
succeeded = false;
|
||||||
|
return json_string("Version since is an invalid type");
|
||||||
|
}
|
||||||
|
size_t since = since_json ?
|
||||||
|
(size_t)json_number_value(since_json) : 0;
|
||||||
json_t* list = json_array();
|
json_t* list = json_array();
|
||||||
module->ForEachFunction([&](FunctionInfo* info) {
|
size_t version = 0;
|
||||||
|
module->ForEachFunction(since, version, [&](FunctionInfo* info) {
|
||||||
json_t* fn_json = json_object();
|
json_t* fn_json = json_object();
|
||||||
const char* name = info->name();
|
const char* name = info->name();
|
||||||
char name_buffer[32];
|
char name_buffer[32];
|
||||||
|
@ -280,15 +313,15 @@ json_t* Processor::OnDebugRequest(
|
||||||
info->address());
|
info->address());
|
||||||
name = name_buffer;
|
name = name_buffer;
|
||||||
}
|
}
|
||||||
json_t* name_json = json_string(name);
|
json_object_set_string_new(fn_json, "name", name);
|
||||||
json_object_set_new(fn_json, "name", name_json);
|
json_object_set_integer_new(fn_json, "address", info->address());
|
||||||
json_t* address_json = json_integer(info->address());
|
json_object_set_integer_new(fn_json, "linkStatus", info->status());
|
||||||
json_object_set_new(fn_json, "address", address_json);
|
|
||||||
json_t* link_status_json = json_integer(info->status());
|
|
||||||
json_object_set_new(fn_json, "linkStatus", link_status_json);
|
|
||||||
json_array_append_new(list, fn_json);
|
json_array_append_new(list, fn_json);
|
||||||
});
|
});
|
||||||
return list;
|
json_t* result = json_object();
|
||||||
|
json_object_set_integer_new(result, "version", version);
|
||||||
|
json_object_set_new(result, "list", list);
|
||||||
|
return result;
|
||||||
} else if (xestrcmpa(command, "get_function") == 0) {
|
} else if (xestrcmpa(command, "get_function") == 0) {
|
||||||
json_t* address_json = json_object_get(request, "address");
|
json_t* address_json = json_object_get(request, "address");
|
||||||
if (!address_json || !json_is_number(address_json)) {
|
if (!address_json || !json_is_number(address_json)) {
|
||||||
|
@ -397,32 +430,6 @@ json_t* Processor::OnDebugRequest(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
json_t* json_object_set_string_new(
|
|
||||||
json_t* object, const char* key, const char* value) {
|
|
||||||
json_t* value_json = json_string(value);
|
|
||||||
json_object_set_new(object, key, value_json);
|
|
||||||
return value_json;
|
|
||||||
}
|
|
||||||
|
|
||||||
json_t* json_object_set_string_format_new(
|
|
||||||
json_t* object, const char* key, const char* format, ...) {
|
|
||||||
char buffer[1024];
|
|
||||||
va_list args;
|
|
||||||
va_start(args, format);
|
|
||||||
xevsnprintfa(buffer, XECOUNT(buffer), format, args);
|
|
||||||
va_end(args);
|
|
||||||
json_t* value_json = json_string(buffer);
|
|
||||||
json_object_set_new(object, key, value_json);
|
|
||||||
return value_json;
|
|
||||||
}
|
|
||||||
|
|
||||||
json_t* json_object_set_integer_new(
|
|
||||||
json_t* object, const char* key, json_int_t value) {
|
|
||||||
json_t* value_json = json_integer(value);
|
|
||||||
json_object_set_new(object, key, value_json);
|
|
||||||
return value_json;
|
|
||||||
}
|
|
||||||
|
|
||||||
json_t* Processor::DumpModule(XexModule* module, bool& succeeded) {
|
json_t* Processor::DumpModule(XexModule* module, bool& succeeded) {
|
||||||
auto xex = module->xex();
|
auto xex = module->xex();
|
||||||
auto header = xe_xex2_get_header(xex);
|
auto header = xe_xex2_get_header(xex);
|
||||||
|
|
Loading…
Reference in New Issue