MiKTeX 26.5-next
A scalable TeX distribution
Loading...
Searching...
No Matches
TeXMFMemoryHandlerImpl.h
Go to the documentation of this file.
1
13
14#pragma once
15
16#include <miktex/Configuration/ConfigNames>
17
18#include <miktex/TeXAndFriends/config.h>
19
20#include <miktex/Trace/TraceStream>
21#include <miktex/Trace/Trace>
22
23#include "TeXMFApp.h"
24
25MIKTEX_TEXMF_BEGIN_NAMESPACE;
26
27namespace texmfapp {
28#include <miktex/texmfapp.defaults.h>
29}
30
31template<class PROGRAM_CLASS> class TeXMFMemoryHandlerImpl :
33{
34
35public:
36
37 TeXMFMemoryHandlerImpl(PROGRAM_CLASS& program, TeXMFApp& texmfapp) :
38 program(program),
39 texmfapp(texmfapp),
40 trace_mem(MiKTeX::Trace::TraceStream::Open(MIKTEX_TRACE_MEM))
41 {
42 }
43
44 void Allocate(const std::unordered_map<std::string, int>& userParams) override
45 {
46 program.bufsize = GetCheckedParameter("buf_size", program.infbufsize, program.supbufsize, userParams, texmfapp::texmfapp::buf_size());
47 program.errorline = GetParameter("error_line", userParams, texmfapp::texmfapp::error_line());
48#if defined(HAVE_EXTRA_MEM_BOT)
49 program.extramembot = GetParameter("extra_mem_bot", userParams, texmfapp::texmfapp::extra_mem_bot());
50#endif
51#if defined(HAVE_EXTRA_MEM_TOP)
52 program.extramemtop = GetParameter("extra_mem_top", userParams, texmfapp::texmfapp::extra_mem_top());
53#endif
54 program.halferrorline = GetParameter("half_error_line", userParams, texmfapp::texmfapp::half_error_line());
55#if defined(HAVE_MAIN_MEMORY)
56# if defined(MIKTEX_METAFONT) || defined(MIKTEX_TEX) || defined(MIKTEX_PDFTEX) || defined(MIKTEX_PTEX_FAMILY) || defined(MIKTEX_XETEX)
57 const int infmainmemory = 3000;
58 const int supmainmemory = 256000000;
59# else
60 const int infmainmemory = program.infmainmemory;
61 const int supmainmemory = program.supmainmemory;
62# endif
63 program.mainmemory = GetCheckedParameter("main_memory", infmainmemory, supmainmemory, userParams, texmfapp::texmfapp::main_memory());
64#endif
65 program.maxprintline = GetParameter("max_print_line", userParams, texmfapp::texmfapp::max_print_line());
66 program.maxstrings = GetCheckedParameter("max_strings", program.infmaxstrings, program.supmaxstrings, userParams, texmfapp::texmfapp::max_strings());
67#if defined(MIKTEX_METAFONT)
68 const int infparamsize = 60;
69 const int supparamsize = 600000;
70#else
71 const int infparamsize = program.infparamsize;
72 const int supparamsize = program.supparamsize;
73#endif
74 program.paramsize = GetCheckedParameter("param_size", infparamsize, supparamsize, userParams, texmfapp::texmfapp::param_size());
75#if defined(HAVE_POOL_FREE)
76 program.poolfree = GetCheckedParameter("pool_free", program.infpoolfree, program.suppoolfree, userParams, texmfapp::texmfapp::pool_free());
77#endif
78 program.poolsize = GetCheckedParameter("pool_size", program.infpoolsize, program.suppoolsize, userParams, texmfapp::texmfapp::pool_size());
79 program.stacksize = GetCheckedParameter("stack_size", program.infstacksize, program.supstacksize, userParams, texmfapp::texmfapp::stack_size());
80#if defined(HAVE_STRINGS_FREE)
81 program.stringsfree = GetCheckedParameter("strings_free", program.infstringsfree, program.supstringsfree, userParams, texmfapp::texmfapp::strings_free());
82#endif
83 program.stringvacancies = GetCheckedParameter("string_vacancies", program.infstringvacancies, program.supstringvacancies, userParams, texmfapp::texmfapp::string_vacancies());
84
85 program.maxstrings += 0x100;
86
87#if defined(HAVE_EXTRA_MEM_BOT)
88 if (texmfapp.IsInitProgram())
89 {
90 program.extramembot = 0;
91 }
92 if (program.extramembot > supmainmemory)
93 {
94 program.extramembot = supmainmemory;
95 }
96#endif
97
98#if defined(HAVE_EXTRA_MEM_TOP)
99 if (texmfapp.IsInitProgram())
100 {
101 program.extramemtop = 0;
102 }
103 if (program.extramemtop > supmainmemory)
104 {
105 program.extramemtop = supmainmemory;
106 }
107#endif
108
109#if defined(MIKTEX_TEX_COMPILER)
110 MIKTEX_ASSERT(program.membot == 0);
111 program.memtop = program.membot + program.mainmemory - 1;
112 program.memmin = program.membot;
113 program.memmax = program.memtop;
114#elif defined(MIKTEX_META_COMPILER)
115 program.memtop = 0/*memmin*/ + program.mainmemory - 1;
116 program.memmax = program.memtop;
117#endif
118
119 AllocateArray("buffer", program.buffer, program.bufsize);
120 AllocateArray("inputstack", program.inputstack, program.stacksize);
121 AllocateArray("paramstack", program.paramstack, program.paramsize);
122 AllocateArray("trickbuf", program.trickbuf, program.errorline);
123
124 if (texmfapp.IsInitProgram() || texmfapp.AmI("mf"))
125 {
126 AllocateArray("strpool", program.strpool, program.poolsize);
127 }
128
129 if (texmfapp.IsInitProgram())
130 {
131#if defined(MIKTEX_TEX_COMPILER)
132 AllocateArray("mem", program.yzmem, program.memtop - program.membot + 2);
133 MIKTEX_ASSERT(program.membot == 0);
134 program.zmem = program.yzmem - program.membot;
135 program.mem = program.zmem;
136#else
137 AllocateArray("mem", program.mem, program.memtop - 0/*memmin*/ + 2);
138#endif
139 }
140
141 AllocateArray("strstart", program.strstart, program.maxstrings);
142 }
143
144 void Free() override
145 {
146 FreeArray("buffer", program.buffer);
147 FreeArray("inputstack", program.inputstack);
148 FreeArray("paramstack", program.paramstack);
149 FreeArray("trickbuf", program.trickbuf);
150 FreeArray("strpool", program.strpool);
151#if defined(MIKTEX_TEX_COMPILER)
152 FreeArray("yzmem", program.yzmem);
153#else
154 FreeArray("mem", program.mem);
155#endif
156 FreeArray("strstart", program.strstart);
157 }
158
159 void Check() override
160 {
161 MIKTEX_ASSERT_VALID_HEAP_POINTER_OR_NIL(program.buffer);
162#if defined(MIKTEX_TEX_COMPILER)
163 MIKTEX_ASSERT_VALID_HEAP_POINTER_OR_NIL(program.yzmem);
164#else
165 MIKTEX_ASSERT_VALID_HEAP_POINTER_OR_NIL(program.mem);
166#endif
167 MIKTEX_ASSERT_VALID_HEAP_POINTER_OR_NIL(program.inputstack);
168 MIKTEX_ASSERT_VALID_HEAP_POINTER_OR_NIL(program.paramstack);
169 MIKTEX_ASSERT_VALID_HEAP_POINTER_OR_NIL(program.strpool);
170 MIKTEX_ASSERT_VALID_HEAP_POINTER_OR_NIL(program.trickbuf);
171 MIKTEX_ASSERT_VALID_HEAP_POINTER_OR_NIL(program.strstart);
172 }
173
174 void* ReallocateArray(const std::string& arrayName, void* ptr, std::size_t elemSize, std::size_t numElem, const MiKTeX::Core::SourceLocation& sourceLocation) override
175 {
176 std::size_t amount;
177 if (numElem == 0)
178 {
179 amount = 0;
180 }
181 else
182 {
183 // one extra element because Pascal arrays are 1-based
184 amount = (numElem + 1) * elemSize;
185 }
186 trace_mem->WriteLine("libtexmf", "reallocate " + arrayName + ": ptr == " + std::string(ptr == nullptr ? "nullptr" : "...") + ", elementSize == " + std::to_string(elemSize) + ", nElements == " + std::to_string(numElem));
187 ptr = MiKTeX::Debug::Realloc(ptr, amount, sourceLocation);
188 return ptr;
189 }
190
191protected:
192
193 int GetConfigValue(const std::string& valueName, int defaultValue) const
194 {
195 std::shared_ptr<MiKTeX::Core::Session> session = texmfapp.GetSession();
196 int value = session->GetConfigValue(MIKTEX_CONFIG_SECTION_NONE, valueName, MiKTeX::Configuration::ConfigValue(-1)).GetInt();
197 if (value < 0)
198 {
199 value = session->GetConfigValue(texmfapp.GetProgramName(), valueName, MiKTeX::Configuration::ConfigValue(defaultValue)).GetInt();
200 }
201 return value;
202 }
203
204 int GetParameter(const std::string& parameterName, const std::unordered_map<std::string, int>& userParams, int defaultValue)
205 {
206 int result;
207 auto it = userParams.find(parameterName);
208 if (it == userParams.end())
209 {
210 result = GetConfigValue(parameterName, defaultValue);
211 }
212 else
213 {
214 result = it->second;
215 }
216 if (trace_mem->IsEnabled("libtexmf", MiKTeX::Trace::TraceLevel::Trace))
217 {
218 // TODO: trace_mem->WriteLine("libtexmf", fmt::format(MIKTEXTEXT("Parameter {0}: {1}"), parameterName, result));
219 }
220 return result;
221 }
222
223 int GetCheckedParameter(const std::string& parameterName, int minValue, int maxValue, const std::unordered_map<std::string, int>& userParams, int defaultValue)
224 {
225 int result;
226 auto it = userParams.find(parameterName);
227 if (it == userParams.end())
228 {
229 result = GetConfigValue(parameterName, defaultValue);
230 }
231 else
232 {
233 result = it->second;
234 }
235 if (result < minValue || result > maxValue)
236 {
237 MIKTEX_FATAL_ERROR_2(MIKTEXTEXT("Bad parameter value."),
238 "maxValue", std::to_string(maxValue),
239 "minValue", std::to_string(minValue),
240 "parameterName", parameterName,
241 "value", std::to_string(result)
242 );
243 }
244 if (trace_mem->IsEnabled("libtexmf", MiKTeX::Trace::TraceLevel::Trace))
245 {
246 // TODO: trace_mem->WriteLine("libtexmf", fmt::format(MIKTEXTEXT("Parameter {0}: {1}"), parameterName, result));
247 }
248 return result;
249 }
250
251 template<typename T> T* AllocateArray(const std::string& arrayName, T*& ptr, std::size_t n)
252 {
253 ptr = (T*)ReallocateArray(arrayName, nullptr, sizeof(*ptr), n, MIKTEX_SOURCE_LOCATION_DEBUG());
254 return ptr;
255 }
256
257 template<typename T> void FreeArray(const std::string& arrayName, T*& ptr)
258 {
259 ReallocateArray(arrayName, ptr, sizeof(*ptr), 0, MIKTEX_SOURCE_LOCATION_DEBUG());
260 ptr = nullptr;
261 }
262
263 PROGRAM_CLASS& program;
264 TeXMFApp& texmfapp;
265 std::unique_ptr<MiKTeX::Trace::TraceStream> trace_mem;
266};
267
268MIKTEX_TEXMF_END_NAMESPACE;
MiKTeX TeXMF base implementation.
MiKTeX configuration value.
Definition ConfigValue.h:68
Definition TeXMFApp.h:75
Definition Exceptions.h:38