Binary search import records.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3742 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2022-01-08 21:56:57 +00:00
parent bb81fc87b9
commit 26150f98e1

View File

@ -95,7 +95,7 @@ typedef struct _tf_task_t {
int _export_count; int _export_count;
exportid_t _nextExport; exportid_t _nextExport;
import_record_t* _imports; import_record_t** _imports;
int _import_count; int _import_count;
JSValue _requires; JSValue _requires;
JSValue _loadedFiles; JSValue _loadedFiles;
@ -143,64 +143,85 @@ static tf_taskstub_t* _tf_task_get_stub(tf_task_t* task, taskid_t id);
static void _tf_task_release_export(tf_taskstub_t* stub, exportid_t exportId); static void _tf_task_release_export(tf_taskstub_t* stub, exportid_t exportId);
typedef struct _import_record_t { typedef struct _import_record_t {
tf_task_t* _owner;
JSValue _function; JSValue _function;
exportid_t _export; exportid_t _export;
taskid_t _task; taskid_t _task;
tf_task_t* _owner;
int _useCount; int _useCount;
import_record_t* _next;
} import_record_t; } import_record_t;
static int _import_compare(const void* a, const void* b)
{
const import_record_t* ia = a;
const import_record_t* const* ib = b;
if (ia->_task != (*ib)->_task)
{
return ia->_task < (*ib)->_task ? -1 : 1;
}
else if (ia->_export != (*ib)->_export)
{
return ia->_export < (*ib)->_export ? -1 : 1;
}
else
{
return 0;
}
}
static import_record_t** _tf_task_find_import(tf_task_t* task, taskid_t task_id, exportid_t export_id)
{
if (!task->_imports)
{
return NULL;
}
import_record_t search =
{
._task = task_id,
._export = export_id,
};
import_record_t** it = bsearch(&search, task->_imports, task->_import_count, sizeof(import_record_t*), _import_compare);
return it;
}
static void _tf_task_trace_imports(tf_task_t* task) static void _tf_task_trace_imports(tf_task_t* task)
{ {
tf_trace_counter(task->_trace, "imports", 1, (const char*[]) { "count" }, (int64_t[]) { task->_import_count }); tf_trace_counter(task->_trace, "imports", 1, (const char*[]) { "count" }, (int64_t[]) { task->_import_count });
} }
static void _import_record_release(import_record_t* import) static void _import_record_release(import_record_t** import)
{ {
JSContext* context = import->_owner->_context; JSContext* context = (*import)->_owner->_context;
if (--import->_useCount > 0) tf_task_t* task = (*import)->_owner;
import_record_t* record = *import;
if (--record->_useCount > 0)
{ {
return; return;
} }
JS_SetOpaque(import->_function, NULL); JS_SetOpaque(record->_function, NULL);
JS_FreeValue(context, import->_function); JS_FreeValue(context, record->_function);
import->_function = JS_UNDEFINED; record->_function = JS_UNDEFINED;
_tf_task_release_export(_tf_task_get_stub(import->_owner, import->_task), import->_export); _tf_task_release_export(_tf_task_get_stub(task, record->_task), record->_export);
for (import_record_t** it = &import->_owner->_imports; int index = import - task->_imports;
*it; memmove(import, import + 1, sizeof(import_record_t*) * (task->_import_count - index - 1));
it = &(*it)->_next) task->_import_count--;
{ _tf_task_trace_imports(task);
if (*it == import)
{
*it = import->_next;
import->_owner->_import_count--;
_tf_task_trace_imports(import->_owner);
import->_next = NULL;
break;
}
}
free(import); free(record);
} }
static void _import_record_release_for_task(tf_task_t* task, taskid_t task_id) static void _import_record_release_for_task(tf_task_t* task, taskid_t task_id)
{ {
bool any = false; bool any = false;
import_record_t** next = NULL; for (int i = 0; i < task->_import_count; i++)
for (import_record_t** it = &task->_imports;
*it;
it = next)
{ {
next = &(*it)->_next; if (task->_imports[i]->_task == task_id)
if ((*it)->_task == task_id)
{ {
import_record_t* import = *it; _import_record_release(&task->_imports[i]);
_import_record_release(import);
next = it;
any = true; any = true;
--i;
} }
} }
@ -644,12 +665,34 @@ static JSValue _tf_task_getFile(JSContext* context, JSValueConst this_val, int a
return result; return result;
} }
const char* _tf_task_get_message_type(tf_task_message_t type)
{
switch (type)
{
case kResolvePromise: return "kResolvePromise";
case kRejectPromise: return "kRejectPromise";
case kInvokeExport: return "kInvokeExport";
case kReleaseExport: return "kReleaseExport";
case kReleaseImport: return "kReleaseImport";
case kSetRequires: return "kSetRequires";
case kActivate: return "kActivate";
case kExecute: return "kExecute";
case kKill: return "kKill";
case kSetImports: return "kSetImports";
case kGetExports: return "kGetExports";
case kLoadFile: return "kLoadFile";
case kTaskError: return "kTaskError";
case kTaskTrace: return "kTaskTrace";
}
return "unknown";
}
void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, void* userData) void tf_task_on_receive_packet(int packetType, const char* begin, size_t length, void* userData)
{ {
tf_taskstub_t* stub = userData; tf_taskstub_t* stub = userData;
tf_taskstub_t* from = stub; tf_taskstub_t* from = stub;
tf_task_t* to = tf_taskstub_get_owner(stub); tf_task_t* to = tf_taskstub_get_owner(stub);
tf_trace_begin(to->_trace, "tf_task_on_receive_packet"); tf_trace_begin(to->_trace, _tf_task_get_message_type(packetType));
switch (packetType) switch (packetType)
{ {
@ -721,13 +764,10 @@ void tf_task_on_receive_packet(int packetType, const char* begin, size_t length,
assert(length == sizeof(exportid_t)); assert(length == sizeof(exportid_t));
exportid_t exportId; exportid_t exportId;
memcpy(&exportId, begin, sizeof(exportId)); memcpy(&exportId, begin, sizeof(exportId));
for (import_record_t* it = to->_imports; it; it = it->_next) import_record_t** it = _tf_task_find_import(to, tf_taskstub_get_id(from), exportId);
{ if (it)
if (it->_task == tf_taskstub_get_id(from) && it->_export == exportId)
{ {
_import_record_release(it); _import_record_release(it);
break;
}
} }
} }
break; break;
@ -1091,7 +1131,10 @@ promiseid_t tf_task_allocate_promise(tf_task_t* task)
promise.values[0] = JS_NewPromiseCapability(task->_context, &promise.values[1]); promise.values[0] = JS_NewPromiseCapability(task->_context, &promise.values[1]);
int index = _insert_index((void*)(intptr_t)promiseId, task->_promises, task->_promise_count, sizeof(promise_t), _promise_compare); int index = _insert_index((void*)(intptr_t)promiseId, task->_promises, task->_promise_count, sizeof(promise_t), _promise_compare);
task->_promises = realloc(task->_promises, sizeof(promise_t) * (task->_promise_count + 1)); task->_promises = realloc(task->_promises, sizeof(promise_t) * (task->_promise_count + 1));
memmove(task->_promises + index, task->_promises + index + 1, sizeof(promise_t) * (task->_promise_count - index)); if (task->_promise_count - index)
{
memmove(task->_promises + index + 1, task->_promises + index, sizeof(promise_t) * (task->_promise_count - index));
}
task->_promises[index] = promise; task->_promises[index] = promise;
task->_promise_count++; task->_promise_count++;
_tf_task_trace_promises(task); _tf_task_trace_promises(task);
@ -1187,7 +1230,11 @@ void tf_task_remove_child(tf_task_t* task, tf_taskstub_t* child)
static void _import_finalizer(JSRuntime* runtime, JSValue value) static void _import_finalizer(JSRuntime* runtime, JSValue value)
{ {
import_record_t* import = JS_GetOpaque(value, _import_class_id); import_record_t* import = JS_GetOpaque(value, _import_class_id);
_import_record_release(import); if (import)
{
import_record_t** it = _tf_task_find_import(import->_owner, import->_task, import->_export);
_import_record_release(it);
}
} }
static void _import_mark_func(JSRuntime* runtime, JSValueConst value, JS_MarkFunc mark_func) static void _import_mark_func(JSRuntime* runtime, JSValueConst value, JS_MarkFunc mark_func)
@ -1346,15 +1393,14 @@ JSContext* tf_task_get_context(tf_task_t* task)
void tf_task_destroy(tf_task_t* task) void tf_task_destroy(tf_task_t* task)
{ {
import_record_t* it = task->_imports; for (int i = 0; i < task->_import_count; i++)
while (it)
{ {
import_record_t* next = it->_next; JS_FreeValue(task->_context, task->_imports[i]->_function);
JS_FreeValue(task->_context, it->_function); free(task->_imports[i]);
free(it);
it = next;
} }
free(task->_imports);
task->_imports = NULL; task->_imports = NULL;
task->_import_count = 0;
while (task->_exports) while (task->_exports)
{ {
@ -1429,10 +1475,15 @@ JSValue tf_task_add_import(tf_task_t* task, taskid_t stub_id, exportid_t export_
._owner = task, ._owner = task,
._task = stub_id, ._task = stub_id,
._useCount = 1, ._useCount = 1,
._next = task->_imports,
}; };
task->_imports = import; int index = _insert_index(import, task->_imports, task->_import_count, sizeof(import_record_t*), _import_compare);
task->_imports = realloc(task->_imports, sizeof(import_record_t*) * (task->_import_count + 1));
if (task->_import_count - index)
{
memmove(task->_imports + index + 1, task->_imports + index, sizeof(import_record_t*) * (task->_import_count - index));
}
task->_imports[index] = import;
task->_import_count++; task->_import_count++;
_tf_task_trace_imports(task); _tf_task_trace_imports(task);
return function; return function;