OSDN Git Service

try to reduce memory leak (ticket #33016)
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Thu, 15 Jan 2015 04:00:11 +0000 (13:00 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Thu, 15 Jan 2015 04:00:11 +0000 (13:00 +0900)
 143850 words of node memory still in use:
   22 hlist, 2 vlist, 7 rule, 12 glue, 117 kern, 5 penalty, 2 glyph, 63253 attri
bute, 2452 glue_spec, 3084 attribute_list, 3 action, 1 write, 1 pdf_literal, 1 p
df_setmatrix, 2 pdf_save, 2 pdf_restore, 37 user_defined nodes
   avail lists: 1:5,2:157048,3:3623,4:16650,5:6634,6:4956,7:10016,8:81,9:9416,10
:680

doc/luatexja.dtx
src/ltj-base.lua
src/ltj-direction.lua
src/ltj-jfmglue.lua
src/ltj-jfont.lua
src/luatexja.lua

index bb3a8cf..9eb1541 100644 (file)
@@ -1086,8 +1086,7 @@ plain \TeX で和文フォントを変更するためには,
 For \LaTeXe, \LuaTeX-ja adopted most of the font selection system of \pLaTeXe\ (in \texttt{plfonts.dtx}).
 %</en>
 %<*ja>
-\LaTeXe については,\LuaTeX-jaではフォント選択システムを\pLaTeXe\ (\texttt{plfonts.dtx})
-の大部分をそのまま採用している.
+\LaTeX で用いる際には,\pLaTeXe\ (\texttt{plfonts.dtx})用のフォント選択機構の大部分を流用している.
 %</ja>
 \begin{itemize}
 %<*en>
@@ -1096,8 +1095,8 @@ For \LaTeXe, \LuaTeX-ja adopted most of the font selection system of \pLaTeXe\ (
       attributes of Japanese fonts.
 %</en>
 %<*ja>
-\item \cs{fontfamily}, \cs{fontseries}, \cs{fontshape}, そして
-      \cs{selectfont} ã\81\8cå\92\8cæ\96\87ã\83\95ã\82©ã\83³ã\83\88ã\81®å±\9eæ\80§ã\82\92å¤\89æ\9b´ã\81\99ã\82\8bã\81\9fã\82\81ã\81«ä½¿ç\94¨ã\81§ã\81\8dる.
+\item 和文フォントの属性を変更するには,\cs{fontfamily}, \cs{fontseries}, \cs{fontshape}, そして
+      \cs{selectfont} ã\82\92ç\94¨ã\81\84る.
 %</ja>
 
 %<*en>
@@ -2439,6 +2438,48 @@ $\Phi\vdash F(x)\ \hbox{for all}\ x\in A$
 \end{table}
 %</ja>
 
+%<*en>
+\subsection{\emph{kinsoku} parameters and OpenType features}
+Among parameters which related to Japanese word-wrapping process (\emph{kinsoku shori}),
+\begin{quote}
+ \Param{jaxspmode},~\Param{alxspmode}, \Param{prebreakpenalty}, 
+ \Param{postbreakpenalty}~and~\Param{kcatcode}
+\end{quote}
+are stored by each character codes. ...
+
+For example, a fullwidth katakana ``ア'' on line~10 in the below input is replaced to
+its halfwidth variant ``ア'', by \verb+hwid+ feature. 
+However, the penalty inserted after it is 10 which is the \Param{postbreakpenalty} of
+``ア'', not 20.
+%</en>
+%<*ja>
+\subsection{禁則処理関連パラメータとfont feature}
+禁則処理や \Param{kanjiskip}, \Param{xkanjiskip} の挿入に関連したパラメータのうち
+\begin{quote}
+ \Param{jaxspmode},~\Param{alxspmode}, \Param{prebreakpenalty},
+ \Param{postbreakpenalty}, \Param{kcatcode}
+\end{quote}
+は,文字コードごとに設定する量である.
+
+\Pkg{fontspec}パッケージを使う(\ref{ssec-fontspec}節)場合など,
+各種のOpenType featureを適用することもあると思うが,前段落に述べたパラメータ類は,
+\emph{OpenType featureの適用前の文字コードによって判定される.}
+例えば,以下の例において10行目の「ア」は,\verb+hwid+ featureの適用により半角カタカナの「ア」
+に置き換わる.しかし,その直後に挿入される \Param{postbreakpenalty}は,置換前の「ア」に対する値10である.
+%</ja>
+
+\begin{LTXexample}[width=0.2\textwidth]
+\ltjsetparameter{postbreakpenalty={`ア, 10}}
+\ltjsetparameter{postbreakpenalty={`ア, 20}}
+
+\newcommand\showpostpena[1]{%
+  \leavevmode\setbox0=\hbox{#1\hbox{}}%
+  \unhbox0\setbox0=\lastbox\the\lastpenalty}
+
+\showpostpena{ア},
+\showpostpena{ア},
+{\addjfontfeatures{CharacterWidth=Half}\showpostpena{ア}}
+\end{LTXexample}
 
 \clearpage
 %<en>\part{Reference}
@@ -4220,8 +4261,8 @@ we specify <ratio> to
 
 %<*ja>
 \paragraph{文字クラスの決定}
\96\87å­\97ã\81\8bã\82\89ã\81\9dã\81®æ\96\87å­\97ã\81®å±\9eã\81\99ã\82\8bæ\96\87å­\97ã\82¯ã\83©ã\82¹ã\82\92ç®\97å\87ºã\81\99ã\82\8bé\81\8eç¨\8bã\81¯å°\91ã\80\85è¤\87é\9b\91ã\81§ã\81\82ã\82\8bï¼\8e
-次の内容を一部に含んだ \texttt{jfm-test.lua} を用いて説明する.
\96\87å­\97ã\81\8bã\82\89ã\81\9dã\81®æ\96\87å­\97ã\81®å±\9eã\81\99ã\82\8bæ\96\87å­\97ã\82¯ã\83©ã\82¹ã\82\92ç®\97å\87ºã\81\99ã\82\8bé\81\8eç¨\8bã\81«ã\81¤ã\81\84ã\81¦ï¼\8c
+次の内容を含んだ \texttt{jfm-test.lua} を用いて説明する.
 %</ja>
 %<*en>
 \paragraph{Character to character classes}
@@ -4265,17 +4306,17 @@ applying font features by \Pkg{luaotfload}}.
 \item JFMによれば,この「ヒ」のグリフの文字クラスは2000である.
 \item 以上により文字クラス2000とみなされるため,結果として「ヒ」の幅は半角だと認識される.
 \end{enumerate}
-この例は,\emph{文字クラスの決定はfont featureの適用によるグリフ置換の後に行われる}ことを
+この例は,\emph{文字クラスの決定はfont featureの適用によるグリフ置換の結果に基づく}ことを
 示している.
 %</ja>
 
 %<*en>
-However, ...
-Consider the following input:
+However, if the class determined by the glyph after application of features is zero,
+\LuaTeX-ja adopts the class determined by the glyph \emph{before} application of features.
+The following input is an example.
 %</en>
 %<*ja>
-但し,JFMによって決まる置換後のグリフの文字クラスが0である場合は,
-状況は異なる.
+但し,JFMによって決まる置換後のグリフの文字クラスが0である場合は,置換前の文字クラスを採用する.
 %</ja>
 \begin{LTXexample}[width=0.3\textwidth]
 \jfont\a=file:KozMinPr6N-Regular.otf:jfm=test;+vert
@@ -4283,11 +4324,11 @@ Consider the following input:
 \end{LTXexample}
 %<*en>
 Here, the character class of the ideographic full stop ``。''~(\texttt{U+3002}) is determined
-as following:
+as follows:
 \begin{enumerate}
 \item As the case of ``ヒ'', the ideographic full stop ``。'' is converted to its vertical
-      form ``\char"FE12''~(\texttt{U+FE12}).%"
-\item The character class of ``\char"FE12'' is \emph{zero}.
+      form ``\char"FE12''~(\texttt{U+FE12}) by \verb+vert+ feature.%"
+\item The character class of ``\char"FE12'', according to the JFM  is \emph{zero}.
 \item However, \LuaTeX-ja remembers that this ``\char"FE12'' is obtained from ``。'' by
       font features. The character class of ``。'' is \emph{non-zero value}, namely, 2000.
 \item Hence the ideographic full stop ``。'' in above belongs the character class~2000.
@@ -4755,7 +4796,7 @@ is the position of \verb+hpack_filter+ callback in the source
 of \LuaTeX, see Section~\ref{sec-para}.
 %</en>
 %<*ja>
-先に述べたように,\LuaTeX-jaのほとんどの内部パラメータにアクセスするには
+先に述べたように,\LuaTeX-jaの内部パラメータにアクセスするには
 \cs{ltjsetparameter}(または \cs{ltjglobalsetparameter})と \cs{ltjgetparameter} を用いる.
 \LuaTeX-jaが\pTeX のような文法(例えば,\verb+\prebreakpenalty`)=10000+)を
 採用しない理由の一つは,\LuaTeX のソースにおける \verb+hpack_filter+
@@ -4850,7 +4891,15 @@ At the present version, the lowermost bit of <natural number> indicates
 \end{lstlisting}
 と,最大値の10000が標準で指定されている.他にも,小書きのカナなど,絶対禁止とい
             うわけではないができれば行頭にはきて欲しくない場合に,0と
-            10000の間の値を指定するのも有用であろう.
+            10000の間の値を指定するのも有用であろう.
+
+\pTeX では,\cs{prebreakpenalty}, \cs{postbreakpenalty}において,
+\begin{itemize}
+\item 一つの文字に対して,pre, postどちらか一つしか指定することができない%
+  \footnote{後から指定した方で上書きされる.}
+\item pre, post合わせて256文字分の情報を格納することしかできない
+\end{itemize}
+という制限があったが,\LuaTeX-jaではこれらの制限は解消されている.
 %</ja>
 %<*en>
 Set a penalty which is inserted automatically before the character <chr\_code>,
@@ -4860,8 +4909,15 @@ with one of closing brackets ``〗'', so \LuaTeX-ja sets
 \ltjsetparameter{prebreakpenalty={`〙,10000}}
 \end{lstlisting}
 by default.
-%</en>
 
+\pTeX\ has following restrictions on \cs{prebreakpenalty} and \cs{postbreakpenalty},
+but they don't exist in \LuaTeX-ja:
+\begin{itemize}
+ \item Both \cs{prebreakpenalty} and \cs{postbreakpenalty} cannot be set
+for the same character.
+ \item We can set \cs{prebreakpenalty} and \cs{postbreakpenalty} up to 256~characters.
+\end{itemize}
+%</en>
 
 \item[\DParam{postbreakpenalty}\,=\{<chr\_code>,<penalty>\}$^\ast$]
           [\cs{postbreakpenalty}]\
@@ -4869,25 +4925,10 @@ by default.
 %<*ja>
 文字コード<chr\_code>の\textbf{JAchar}が行末にくることを抑止するために,
             この文字の後に挿入/追加されるペナルティの量を指定する.
-
-\pTeX では,\cs{prebreakpenalty}, \cs{postbreakpenalty}において,
-\begin{itemize}
-\item 一つの文字に対して,pre, postどちらか一つしか指定することができない%
-  \footnote{後から指定した方で上書きされる.}
-\item pre, post合わせて256文字分の情報を格納することしかできない
-\end{itemize}
-という制限があったが,\LuaTeX-jaではこれらの制限は解消されている.
 %</ja>
 %<*en>
 Set a penalty which is inserted automatically after the character <chr\_code>,
 to prevent a line ends with this character.
-\pTeX\ has following restrictions on \cs{prebreakpenalty} and \cs{postbreakpenalty},
-but they don't exist in \LuaTeX-ja:
-\begin{itemize}
- \item Both \cs{prebreakpenalty} and \cs{postbreakpenalty} cannot be set
-for the same character.
- \item We can set \cs{prebreakpenalty} and \cs{postbreakpenalty} up to 256~characters.
-\end{itemize}
 %</en>
 
 \item[\DParam{jatextfont}\,=\{<jfam>,<jfont\_cs>\}$^\ast$]
index a560df6..f80301a 100644 (file)
@@ -563,6 +563,19 @@ do
    ltjb.save_cache = save_cache
 end
 
+
+----
+do
+   local tex_set_attr, tex_get_attr = tex.setattribute, tex.getattribute
+   function ltjb.ensure_tex_attr(a, v)
+      if tex_get_attr(a)~=v then
+        tex_set_attr(a, v)
+      end
+   end
+end
+
+----
+
 ltjb._error_set_break = _error_set_break
 ltjb._error_set_message = _error_set_message
 ltjb._error_show = _error_show
index 88ea22a..03b7295 100644 (file)
@@ -45,6 +45,7 @@ local sid_user = node.subtype('user_defined')
 
 local tex_nest = tex.nest
 local tex_getcount = tex.getcount
+local ensure_tex_attr = ltjb.ensure_tex_attr
 local PROCESSED    = luatexja.icflag_table.PROCESSED
 local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
 local PACKED       = luatexja.icflag_table.PACKED
@@ -62,26 +63,17 @@ end
 
 local page_direction
 --
-local ensure_tex_attr, copy_dir_pool
+local dir_pool
 do
-   local tex_set_attr = tex.setattribute
-   local tex_get_attr, node_copy = tex.getattribute, Dnode.copy
-   function ensure_tex_attr(a, v)
-      if tex_get_attr(a)~=v then
-        tex_set_attr('global', a, v)
-      end
-   end
-   local dir_pool = {}
+   local node_copy = Dnode.copy
+   dir_pool = {}
    for _,i in pairs({dir_tate, dir_yoko, dir_dtou, dir_utod}) do
       local w = node_new(id_whatsit, sid_user)
       set_attr(w, attr_dir, i)
       setfield(w, 'user_id', DIR)
       setfield(w, 'type', 110)
       setfield(w, 'next', nil)
-      dir_pool[i] = w
-   end
-   function copy_dir_pool(d)
-      return node_copy(dir_pool[d])
+      dir_pool[i] = function () return node_copy(w) end
    end
 end
 
@@ -189,7 +181,7 @@ do
          v = get_adjust_dir_count()
       end
       local h = to_direct(tex_nest[lv].head)
-      local w = copy_dir_pool(v)
+      local w = dir_pool[v]()
       insert_after(h, h, w)
       tex_nest[lv].tail = to_node(node_tail(w))
       ensure_tex_attr(attr_icflag, 0)
@@ -229,8 +221,7 @@ do
            node_set_attr(w, attr_dir, v)
            if lv==0 then page_direction = v end
         else
-           local w = copy_dir_pool(v)
-           Dnode.write(w)
+           Dnode.write(dir_pool[v]())
            if lv==0 then page_direction = v end
         end
          ensure_tex_attr(attr_icflag, 0)
@@ -254,7 +245,7 @@ local function create_dir_whatsit(hd, gc, new_dir)
       ensure_tex_attr(attr_icflag, 0)
       return hd
    else
-      local w = copy_dir_pool(new_dir)
+      local w = dir_pool[new_dir]()
       setfield(w, 'next', hd)
       set_attr(w, attr_icflag, PROCESSED_BEGIN_FLAG)
       set_attr(hd, attr_icflag,
@@ -290,11 +281,9 @@ do
    local function create_dir_whatsit_parbox(h, gc)
       stop_time_measure('tex_linebreak')
       -- start 側は ltj-debug.lua に
-      local new_dir, hd = ltjs.list_dir, to_direct(h)
-      for line in traverse_id(id_hlist, hd) do
-         local nh = getlist(line)
-        setfield(line, 'head', create_dir_whatsit(nh, gc, new_dir) )
-        --set_attr(line, attr_dir, new_dir)
+      local new_dir =  ltjs.list_dir
+      for line in traverse_id(id_hlist, to_direct(h)) do
+        setfield(line, 'head', create_dir_whatsit(getlist(line), gc, new_dir) )
       end
       ensure_tex_attr(attr_dir, 0)
       return h
@@ -943,8 +932,7 @@ do
         end
         for box_rule in traverse(h) do
            if getid(box_rule)<id_rule then
-              local w = copy_dir_pool(list_dir)
-              h = insert_before(h, box_rule, w)
+              h = insert_before(h, box_rule, dir_pool[list_dir]())
            end
         end
         ensure_tex_attr(attr_dir, 0)
@@ -1023,10 +1011,8 @@ do
    local function dir_adjust_buildpage(info)
       if info=='box' then
         local head = to_direct(tex.lists.contrib_head)
-        local nb
         if head then
-           head, _, nb
-              = make_dir_whatsit(head,
+           head = make_dir_whatsit(head,
                                  node_tail(head),
                                  get_dir_count(),
                                  'buildpage')
@@ -1046,16 +1032,15 @@ do
    local function finalize_dir_node(db,new_dir)
       local b = getlist(db)
       finalize_inner(b)
-      local box_dir = get_box_dir(b, dir_yoko)%dir_math_mod
-      setfield(db, 'head', nil)
       local w = getfield(b, 'width')
       local h = getfield(b, 'height')
       local d = getfield(b, 'depth')
       local dn_w = getfield(db, 'width')
       local dn_h = getfield(db, 'height')
       local dn_d = getfield(db, 'depth')
-      local db_head, db_tail  = nil
-      for _,v in ipairs(dir_node_aux[box_dir][new_dir][getid(b)]) do
+      local db_head, db_tail
+      for _,v in ipairs(dir_node_aux
+                       [get_box_dir(b, dir_yoko)%dir_math_mod][new_dir][getid(b)]) do
          local cmd, arg, nn = v[1], v[2]
          if cmd=='kern' then
             nn = node_new(id_kern)
@@ -1073,9 +1058,9 @@ do
             insert_after(db_head, db_tail, nn)
             db_tail = nn
          else
+           setfield(db, 'head', nn)
             db_head, db_tail = nn, nn
          end
-         setfield(db, 'head', db_head)
       end
    end
 
@@ -1098,6 +1083,7 @@ do
    end
    local getbox = tex.getbox
    local setbox, copy = Dnode.setbox, Dnode.copy
+   local lua_mem_kb = 0
    function luatexja.direction.finalize()
       local a = to_direct(tex.getbox("AtBeginShipoutBox"))
       local a_dir = get_box_dir(a, dir_yoko)
@@ -1109,6 +1095,12 @@ do
       finalize_inner(shipout_temp)
       setbox('global', "AtBeginShipoutBox", copy(getlist(shipout_temp)))
       setfield(shipout_temp, 'head',nil)
-      --print('MM', collectgarbage('count'))
+
+      -- garbage collect
+      --local m = collectgarbage('count')
+      --if m>lua_mem_kb+20480 then
+      --   collectgarbage(); lua_mem_kb = collectgarbage('count')
+      --end
+      --print('Lua Memory Usage', lua_mem_kb)
    end
 end
index 25b7aef..b080005 100644 (file)
@@ -700,17 +700,17 @@ do
    end
    function new_jfm_glue(m, bc, ac)
       -- bc, ac: char classes
-      local g, d = m.char_type[bc][ac], 0
-      local n
+      local g = m.char_type[bc][ac]
       if g then
-        n,d = node_copy(g[2]), g[3]
         if g[1] then
            local f = node_copy(glue_skel[g[4]])
-           setfield(f, 'spec', n)
-           return f, d
+           setfield(f, 'spec', node_copy(g[2]))
+           return f, g[3]
+        else
+           return node_copy(g[2]), g[3]
         end
       end
-      return n, d
+      return nil, 0
    end
 end
 
index bb89104..05ee1fd 100644 (file)
@@ -136,6 +136,11 @@ end
 
 local update_jfm_cache
 do
+   local node_copy = Dnode.copy
+   local kern_skel = node_new(id_kern)
+   set_attr(kern_skel, attr_icflag, FROM_JFM)
+   setfield(kern_skel, 'subtype', 1)
+
    local function mult_table(old,scale) -- modified from table.fastcopy
       if old then
         local new = { }
@@ -172,10 +177,8 @@ do
               setfield(h, 'shrink_order', 0)
            end
            for k,w in pairs(v.kern) do
-              local g = node_new(id_kern)
+              local g = node_copy(kern_skel)
               setfield(g, 'kern', w[1])
-              setfield(g, 'subtype', 1)
-              set_attr(g, attr_icflag, FROM_JFM)
               v[k] = {false, g, w[2]/sz}
            end
         end
@@ -878,7 +881,7 @@ end
 do
    local get_dir_count = ltjd.get_dir_count
    local is_ucs_in_japanese_char = ltjc.is_ucs_in_japanese_char_direct
-   local tex_set_attr = tex.setattribute
+   local ensure_tex_attr = ltjb.ensure_tex_attr
    local font = font
    -- EXT: italic correction
    function append_italic()
@@ -897,12 +900,12 @@ do
            if h then
               setfield(g, 'kern', h.characters[getchar(p)].italic)
            else
-              tex_set_attr(attr_icflag, 0)
+              ensure_tex_attr(attr_icflag, 0)
               return node_free(g)
            end
         end
         node_write(g)
-        tex_set_attr(attr_icflag, 0)
+        ensure_tex_attr(attr_icflag, 0)
       end
    end
 end
index 5bb2811..3d83401 100644 (file)
@@ -285,9 +285,12 @@ do
    local to_node = (Dnode ~= node) and Dnode.tonode or nullfunc
    local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc
    local tex_set_attr = tex.setattribute
+   local tex_get_attr, node_copy = tex.getattribute, Dnode.copy
+   local ensure_tex_attr = ltjb.ensure_tex_attr
+
    -- mode = true iff main_process is called from pre_linebreak_filter
    local function main_process(head, mode, dir, gc)
-      tex_set_attr('global', attr_icflag, 0)
+      ensure_tex_attr(attr_icflag, 0)
       if gc == 'fin_row' then return head
       else
             --luatexja.ext_show_node_list(head, 'T> ', print)
@@ -301,7 +304,7 @@ do
    local function adjust_icflag(h)
       -- kern from luaotfload will have icflag = 1
       -- (same as italic correction)
-      tex_set_attr('global', attr_icflag, 1)
+      ensure_tex_attr(attr_icflag, 1)
       return h
    end