diff options
| author | ruki <[email protected]> | 2025-04-27 22:33:55 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2025-08-28 11:35:53 +0800 |
| commit | 8b976dd744fc18d617e00655631cbca8a1f19035 (patch) | |
| tree | 058fdb2342441ac49e7123fe6ae96f5fed4d7aee | |
| parent | ec3153a9254fb8d3f93371b4026dc1000afcae7c (diff) | |
optimize thread load/save
| -rw-r--r-- | xmake/core/base/serialize.lua | 42 | ||||
| -rw-r--r-- | xmake/core/thread/thread.lua | 57 |
2 files changed, 59 insertions, 40 deletions
diff --git a/xmake/core/base/serialize.lua b/xmake/core/base/serialize.lua index 665fe04a6..87c810536 100644 --- a/xmake/core/base/serialize.lua +++ b/xmake/core/base/serialize.lua @@ -25,12 +25,26 @@ local stub = serialize._stub or {} serialize._stub = stub serialize._dump = serialize._dump or string._dump or string.dump serialize._BCTAG = xmake._LUAJIT and "\27LJ" or "\27Lua" +stub.isstub = setmetatable({}, { __tostring = function() return "stub indentifier" end }) +stub.__index = stub -- load modules local math = require("base/math") local table = require("base/table") local hashset = require("base/hashset") +function stub:__call(root, fenv) + return self.resolver(root, fenv, table.unpack(self.params, 1, self.params.n)) +end + +function stub:__tostring() + local fparams = {} + for i = 1, self.params.n do + fparams[i] = serialize._make(self.params[i], {}) + end + return string.format("%s(%s)", self.name, table.concat(fparams, ", ")) +end + -- reserved keywords in lua function serialize._keywords() local keywords = serialize._KEYWORDS @@ -339,22 +353,6 @@ function serialize.save(obj, opt) return (#dump < #result) and dump or result end --- init stub metatable -stub.isstub = setmetatable({}, { __tostring = function() return "stub indentifier" end }) -stub.__index = stub - -function stub:__call(root, fenv) - return self.resolver(root, fenv, table.unpack(self.params, 1, self.params.n)) -end - -function stub:__tostring() - local fparams = {} - for i = 1, self.params.n do - fparams[i] = serialize._make(self.params[i], {}) - end - return string.format("%s(%s)", self.name, table.concat(fparams, ", ")) -end - -- called by functions in deserialize environment -- create a function (called stub) to finish deserialization function serialize._createstub(name, resolver, env, ...) @@ -408,23 +406,13 @@ end -- create a env for deserialze load() call function serialize._createenv() - - -- init env local env = { nan = math.nan, inf = math.huge } - - -- resolve reference function env.ref(...) - -- load ref return serialize._createstub("ref", serialize._resolveref, env, ...) end - - -- load function function env.func(...) - -- load func return serialize._createstub("func", serialize._resolvefunction, env, ...) end - - -- return new env return env end @@ -442,7 +430,6 @@ function serialize._load(str) local env = serialize._createenv() local script, errors = load(str, binary and "=(b)" or "=(t)", binary and "b" or "t", env) if script then - -- load obj local ok, obj = pcall(script) if ok then result = obj @@ -451,7 +438,6 @@ function serialize._load(str) result, errors = serialize._resolvestub(result, result, fenv, "<root>") end else - -- error errors = tostring(obj) end end diff --git a/xmake/core/thread/thread.lua b/xmake/core/thread/thread.lua index 9571c981b..dcb74e282 100644 --- a/xmake/core/thread/thread.lua +++ b/xmake/core/thread/thread.lua @@ -92,11 +92,12 @@ function _instance:start() assert(not self:cdata()) -- serialize and pass callback and arguments to this thread - local callinfo = { - callback = self._CALLBACK, - argv = self._ARGV - } - callinfo = string.serialize(callinfo, {strip = true, indent = false}) + -- we do not use string.serialize to serialize callback, because it's slower (deserialize) + local callinfo = string._dump(self._CALLBACK, true) + local argv = self._ARGV + if argv ~= nil then + callinfo = string.serialize(argv, {strip = true, indent = false}) .. "<Argv\27>" .. callinfo + end -- init and start thread local handle, errors = thread.thread_init(self:name(), callinfo, self._STACKSIZE) @@ -205,14 +206,46 @@ end -- run thread function thread._run_thread(callinfo_str) - -- get callback info - local callinfo, errors = string.deserialize(callinfo_str) - if not callinfo then - return false, string.format("invalid thread callinfo, %s!", errors or "unknown") + -- get callinfo + local parts = callinfo_str:split("<Argv\27>", {plain = true}) + local callback_str, argv_str + if #parts > 1 then + callback_str = parts[2] + argv_str = parts[1] + else + callback_str = parts[1] + end + + -- load callback + local fenv = debug.getfenv(debug.getinfo(2, "f").func) + local callback + if callback_str then + local script, errors = load(callback_str, "=(thread)", "b", fenv) + if not script then + return false, string.format("cannot load thread callback, %s!", errors or "unknown") + end + --[[ + for i = 1, math.huge do + local upname, upvalue = debug.getupvalue(script, i) + if upname == nil or upname == "" then + break + end + print("upname", i, upname, upvalue) + end]] + callback = script end - local callback = callinfo.callback if not callback then - return false, string.format("no callback") + return false, "no thread callback" + end + + -- load argument list + local argv + if argv_str then + local result, errors = string.deserialize(argv_str) + if not result then + return false, string.format("invalid thread arguments, %s!", errors or "unknown") + end + argv = result end -- bind sandbox @@ -224,7 +257,7 @@ function thread._run_thread(callinfo_str) end -- do callback - return sandbox.load(sandbox_inst:script(), table.unpack(callinfo.argv or {})) + return sandbox.load(sandbox_inst:script(), table.unpack(argv or {})) end -- return module |
