Avoid resolving loaded request entries twice

This commit is contained in:
udo
2026-07-18 03:08:01 +00:00
parent 339031b6c3
commit a043fb8fc7
4 changed files with 69 additions and 44 deletions
+46 -26
View File
@@ -193,6 +193,10 @@ struct WasmRequestProfile
u64 context_guest_apply_us = 0;
u64 context_free_us = 0;
u64 entry_invoke_us = 0;
u64 entry_load_us = 0;
u64 entry_presence_us = 0;
u64 entry_link_us = 0;
u64 entry_dispatch_us = 0;
u64 output_collect_us = 0;
u64 workspace_complete_us = 0;
u64 component_resolve_count = 0;
@@ -1560,45 +1564,61 @@ public:
// empty body, a missing cli/serve handler to a 404).
String invoke_entry(const String& entry_source_path, const String& handler, bool* handler_present = 0)
{
auto phase_started = std::chrono::steady_clock::now();
auto phase_us = [&]() {
auto now = std::chrono::steady_clock::now();
u64 elapsed = (u64)std::chrono::duration_cast<std::chrono::microseconds>(now - phase_started).count();
phase_started = now;
return(elapsed);
};
entry_dir = dir_of(entry_source_path);
size_t unit_index = 0;
String error = load_unit(entry_source_path, "entry", unit_index);
entry_load_us = phase_us();
if(error != "")
return(error);
bool present = (bool)unit_func(unit_index, handler_export_symbol(handler));
String handler_symbol = handler_export_symbol(handler);
auto handler_fn = unit_func(unit_index, handler_symbol);
bool present = (bool)handler_fn;
entry_presence_us = phase_us();
if(handler_present)
*handler_present = present;
if(!present)
return("");
// Invoke through the core: it resolves the same handler and runs ONCE +
// dispatch (unit is pre-loaded above; resolution is cached). The core
// entry takes two guest buffers — the unit path and the handler name.
auto entry = core_func("uce_wasm_invoke_entry");
// The entry unit is already loaded above. Place its handler and optional
// ONCE export directly in the shared table, then let the core retain ONCE
// deduplication and dispatch without resolving the same unit via hostcall.
auto entry = core_func("uce_wasm_invoke_loaded_entry");
if(!entry)
return("core does not export uce_wasm_invoke_entry");
int32_t path_ptr = 0, handler_ptr = 0;
error = call_core("uce_alloc", { (int32_t)entry_source_path.size() }, &path_ptr);
if(error != "" || path_ptr == 0)
return(error == "" ? String("guest uce_alloc failed for entry path") : error);
error = guest_write((u32)path_ptr, entry_source_path);
return("core does not export uce_wasm_invoke_loaded_entry");
auto link_handler = [&](const String& symbol, const std::optional<wasmtime::Func>& func, u32& slot) {
if(!func)
{
slot = 0;
return(String(""));
}
String slot_key = entry_source_path + ":" + symbol;
auto cached = handler_slots.find(slot_key);
if(cached != handler_slots.end())
{
slot = cached->second;
return(String(""));
}
String link_error = place_funcref(*func, slot);
if(link_error == "")
handler_slots[slot_key] = slot;
return(link_error);
};
u32 handler_slot = 0, once_slot = 0;
error = link_handler(handler_symbol, handler_fn, handler_slot);
String once_symbol = handler_export_symbol("once");
if(error == "")
{
error = call_core("uce_alloc", { (int32_t)handler.size() }, &handler_ptr);
if(error == "" && handler_ptr == 0)
error = "guest uce_alloc failed for handler";
}
if(error == "")
error = guest_write((u32)handler_ptr, handler);
error = link_handler(once_symbol, unit_func(unit_index, once_symbol), once_slot);
if(error != "")
{
if(path_ptr) call_core("uce_free", { path_ptr }, 0);
if(handler_ptr) call_core("uce_free", { handler_ptr }, 0);
return(error);
}
auto result = entry->call(ctx(), { wasmtime::Val(path_ptr), wasmtime::Val((int32_t)entry_source_path.size()),
wasmtime::Val(handler_ptr), wasmtime::Val((int32_t)handler.size()) });
call_core("uce_free", { path_ptr }, 0);
call_core("uce_free", { handler_ptr }, 0);
entry_link_us = phase_us();
auto result = entry->call(ctx(), { wasmtime::Val((int32_t)handler_slot), wasmtime::Val((int32_t)once_slot) });
entry_dispatch_us = phase_us();
if(!result)
return(trap_text(result.err()));
return("");