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_ = {
|
||||
modules: {},
|
||||
moduleFunctionLists: {},
|
||||
functions: {}
|
||||
};
|
||||
};
|
||||
|
@ -104,10 +105,29 @@ module.service('DataSource', function($q) {
|
|||
};
|
||||
|
||||
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',
|
||||
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) {
|
||||
|
|
|
@ -97,6 +97,7 @@ SymbolInfo::Status Module::DeclareSymbol(
|
|||
break;
|
||||
}
|
||||
map_[address] = symbol_info;
|
||||
list_.push_back(symbol_info);
|
||||
status = SymbolInfo::STATUS_NEW;
|
||||
}
|
||||
UnlockMutex(lock_);
|
||||
|
@ -160,10 +161,25 @@ SymbolInfo::Status Module::DefineVariable(VariableInfo* symbol_info) {
|
|||
|
||||
void Module::ForEachFunction(std::function<void (FunctionInfo*)> callback) {
|
||||
LockMutex(lock_);
|
||||
for (SymbolMap::iterator it = map_.begin();
|
||||
it != map_.end(); ++it) {
|
||||
if (it->second->type() == SymbolInfo::TYPE_FUNCTION) {
|
||||
FunctionInfo* info = (FunctionInfo*)it->second;
|
||||
for (auto it = list_.begin(); it != list_.end(); ++it) {
|
||||
SymbolInfo* symbol_info = *it;
|
||||
if (symbol_info->type() == SymbolInfo::TYPE_FUNCTION) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@ public:
|
|||
SymbolInfo::Status DefineVariable(VariableInfo* symbol_info);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -62,6 +64,8 @@ private:
|
|||
Mutex* lock_;
|
||||
typedef std::tr1::unordered_map<uint64_t, SymbolInfo*> SymbolMap;
|
||||
SymbolMap map_;
|
||||
typedef std::vector<SymbolInfo*> SymbolList;
|
||||
SymbolList list_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -225,6 +225,32 @@ void Processor::OnDebugClientDisconnected(uint32_t client_id) {
|
|||
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(
|
||||
uint32_t client_id, const char* command, json_t* request,
|
||||
bool& succeeded) {
|
||||
|
@ -240,8 +266,7 @@ json_t* Processor::OnDebugRequest(
|
|||
for (auto it = modules.begin(); it != modules.end(); ++it) {
|
||||
XexModule* module = (XexModule*)(*it);
|
||||
json_t* module_json = json_object();
|
||||
json_t* module_name_json = json_string(module->name());
|
||||
json_object_set_new(module_json, "name", module_name_json);
|
||||
json_object_set_string_new(module_json, "name", module->name());
|
||||
json_array_append_new(list, module_json);
|
||||
}
|
||||
return list;
|
||||
|
@ -270,8 +295,16 @@ json_t* Processor::OnDebugRequest(
|
|||
succeeded = false;
|
||||
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();
|
||||
module->ForEachFunction([&](FunctionInfo* info) {
|
||||
size_t version = 0;
|
||||
module->ForEachFunction(since, version, [&](FunctionInfo* info) {
|
||||
json_t* fn_json = json_object();
|
||||
const char* name = info->name();
|
||||
char name_buffer[32];
|
||||
|
@ -280,15 +313,15 @@ json_t* Processor::OnDebugRequest(
|
|||
info->address());
|
||||
name = name_buffer;
|
||||
}
|
||||
json_t* name_json = json_string(name);
|
||||
json_object_set_new(fn_json, "name", name_json);
|
||||
json_t* address_json = json_integer(info->address());
|
||||
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_object_set_string_new(fn_json, "name", name);
|
||||
json_object_set_integer_new(fn_json, "address", info->address());
|
||||
json_object_set_integer_new(fn_json, "linkStatus", info->status());
|
||||
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) {
|
||||
json_t* address_json = json_object_get(request, "address");
|
||||
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) {
|
||||
auto xex = module->xex();
|
||||
auto header = xe_xex2_get_header(xex);
|
||||
|
|
Loading…
Reference in New Issue