31template<
class PROGRAM_CLASS>
class TeXMFMemoryHandlerImpl :
37 TeXMFMemoryHandlerImpl(PROGRAM_CLASS& program,
TeXMFApp& texmfapp) :
40 trace_mem(MiKTeX::Trace::TraceStream::Open(MIKTEX_TRACE_MEM))
44 void Allocate(
const std::unordered_map<std::string, int>& userParams)
override
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());
51#if defined(HAVE_EXTRA_MEM_TOP)
52 program.extramemtop = GetParameter(
"extra_mem_top", userParams, texmfapp::texmfapp::extra_mem_top());
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;
60 const int infmainmemory = program.infmainmemory;
61 const int supmainmemory = program.supmainmemory;
63 program.mainmemory = GetCheckedParameter(
"main_memory", infmainmemory, supmainmemory, userParams, texmfapp::texmfapp::main_memory());
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;
71 const int infparamsize = program.infparamsize;
72 const int supparamsize = program.supparamsize;
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());
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());
83 program.stringvacancies = GetCheckedParameter(
"string_vacancies", program.infstringvacancies, program.supstringvacancies, userParams, texmfapp::texmfapp::string_vacancies());
85 program.maxstrings += 0x100;
87#if defined(HAVE_EXTRA_MEM_BOT)
88 if (texmfapp.IsInitProgram())
90 program.extramembot = 0;
92 if (program.extramembot > supmainmemory)
94 program.extramembot = supmainmemory;
98#if defined(HAVE_EXTRA_MEM_TOP)
99 if (texmfapp.IsInitProgram())
101 program.extramemtop = 0;
103 if (program.extramemtop > supmainmemory)
105 program.extramemtop = supmainmemory;
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 + program.mainmemory - 1;
116 program.memmax = program.memtop;
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);
124 if (texmfapp.IsInitProgram() || texmfapp.AmI(
"mf"))
126 AllocateArray(
"strpool", program.strpool, program.poolsize);
129 if (texmfapp.IsInitProgram())
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;
137 AllocateArray(
"mem", program.mem, program.memtop - 0 + 2);
141 AllocateArray(
"strstart", program.strstart, program.maxstrings);
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);
154 FreeArray(
"mem", program.mem);
156 FreeArray(
"strstart", program.strstart);
159 void Check()
override
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);
165 MIKTEX_ASSERT_VALID_HEAP_POINTER_OR_NIL(program.mem);
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);
174 void* ReallocateArray(
const std::string& arrayName,
void* ptr, std::size_t elemSize, std::size_t numElem,
const MiKTeX::Core::SourceLocation& sourceLocation)
override
184 amount = (numElem + 1) * elemSize;
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);
193 int GetConfigValue(
const std::string& valueName,
int defaultValue)
const
195 std::shared_ptr<MiKTeX::Core::Session> session = texmfapp.GetSession();
204 int GetParameter(
const std::string& parameterName,
const std::unordered_map<std::string, int>& userParams,
int defaultValue)
207 auto it = userParams.find(parameterName);
208 if (it == userParams.end())
210 result = GetConfigValue(parameterName, defaultValue);
216 if (trace_mem->IsEnabled(
"libtexmf", MiKTeX::Trace::TraceLevel::Trace))
223 int GetCheckedParameter(
const std::string& parameterName,
int minValue,
int maxValue,
const std::unordered_map<std::string, int>& userParams,
int defaultValue)
226 auto it = userParams.find(parameterName);
227 if (it == userParams.end())
229 result = GetConfigValue(parameterName, defaultValue);
235 if (result < minValue || result > maxValue)
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)
244 if (trace_mem->IsEnabled(
"libtexmf", MiKTeX::Trace::TraceLevel::Trace))
251 template<
typename T> T* AllocateArray(
const std::string& arrayName, T*& ptr, std::size_t n)
253 ptr = (T*)ReallocateArray(arrayName,
nullptr,
sizeof(*ptr), n, MIKTEX_SOURCE_LOCATION_DEBUG());
257 template<
typename T>
void FreeArray(
const std::string& arrayName, T*& ptr)
259 ReallocateArray(arrayName, ptr,
sizeof(*ptr), 0, MIKTEX_SOURCE_LOCATION_DEBUG());
263 PROGRAM_CLASS& program;
265 std::unique_ptr<MiKTeX::Trace::TraceStream> trace_mem;