From 6300e191ee1a36b79e70bf572614d4638df1c4c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Wed, 13 Mar 2019 14:46:52 +0800 Subject: =?UTF-8?q?=E4=B8=80=E5=A4=84=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/src/vm/source.lua | 4 ++++ server/src/vm/value.lua | 44 ++++++++++++++++++++++++++++++++++++++------ server/src/vm/vm.lua | 18 ++++++++++++++++++ 3 files changed, 60 insertions(+), 6 deletions(-) (limited to 'server') diff --git a/server/src/vm/source.lua b/server/src/vm/source.lua index e6e15e9c..247788b0 100644 --- a/server/src/vm/source.lua +++ b/server/src/vm/source.lua @@ -80,6 +80,10 @@ function mt:getName() return self[1] end +function mt:isDead() + return self._dead +end + return function (vm, source) if source._hasInstant then return false diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua index ece9e856..2463e646 100644 --- a/server/src/vm/value.lua +++ b/server/src/vm/value.lua @@ -16,6 +16,8 @@ local mt = {} mt.__index = mt mt.type = 'value' mt.uri = '' +mt._infoCount = 0 +mt._infoLimit = 10 local function create (tp, source, literal) if tp == '...' then @@ -25,7 +27,7 @@ local function create (tp, source, literal) source = source or getDefaultSource(), _type = {}, _literal = literal, - _info = setmetatable({}, weakMt), + _info = {}, }, mt) if type(tp) == 'table' then for i = 1, #tp do @@ -87,7 +89,11 @@ function mt:rawGet(index) if not self._child then return nil end - return self._child[index] + local child = self._child[index] + if not child then + return nil + end + return child end function mt:setChild(index, value) @@ -222,8 +228,15 @@ function mt:mergeValue(value) self._child[k] = v end end + for source, info in pairs(value._info) do - self._info[source] = info + if source:isDead() then + value._info[source] = nil + value._infoCount = value._infoCount - 1 + else + self._infoCount = self._infoCount + 1 + self._info[source] = info + end end if value._meta then self._meta = value._meta @@ -246,7 +259,7 @@ function mt:addInfo(tp, source, ...) if self._info[source] then return end - if not source then + if not source or not source._hasInstant then return end Sort = Sort + 1 @@ -257,12 +270,31 @@ function mt:addInfo(tp, source, ...) ... } self._info[source] = info + self._infoCount = self._infoCount + 1 + + if self._infoCount > self._infoLimit then + for src in pairs(self._info) do + if src:isDead() then + self._info[src] = nil + self._infoCount = self._infoCount - 1 + end + end + self._infoLimit = self._infoCount * 2 + if self._infoLimit < 10 then + self._infoLimit = 10 + end + end end function mt:eachInfo(callback) local list = {} - for _, info in pairs(self._info) do - list[#list+1] = info + for source, info in pairs(self._info) do + if source:isDead() then + self._info[source] = nil + self._infoCount = self._infoCount - 1 + else + list[#list+1] = info + end end table.sort(list, function (a, b) return a._sort < b._sort diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua index 4a54aeae..00fce559 100644 --- a/server/src/vm/vm.lua +++ b/server/src/vm/vm.lua @@ -8,6 +8,8 @@ local buildGlobal = require 'vm.global' local createMulti = require 'vm.multi' local libraryBuilder = require 'vm.library' +local CachedSource = setmetatable({}, { __mode = 'kv' }) + local mt = {} mt.__index = mt @@ -1075,6 +1077,7 @@ function mt:instantSource(source) if instantSource(self, source) then source:setUri(self:getUri()) self.sources[#self.sources+1] = source + CachedSource[source] = true end return source end @@ -1142,7 +1145,13 @@ function mt:isRemoved() end function mt:remove() + if self._removed then + return + end self._removed = true + for _, source in ipairs(self.sources) do + source._dead = true + end end local function compile(ast, lsp, uri) @@ -1174,5 +1183,14 @@ return function (ast, lsp, uri) if not suc then return nil, res end + local total = 0 + local alive = 0 + for source in pairs(CachedSource) do + if not source:isDead() then + alive = alive + 1 + end + total = total + 1 + end + log.debug(('CachedSource: %d/%d'):format(alive, total)) return res end -- cgit v1.2.3