On Sat, 15 Feb 2025 23:32:37 -0500
David Malcolm <dmalc...@redhat.com> wrote:

> > +  free(copier);
> 
> There?s a manual free of "copier" here, but there?s are various error-
> handling early returns paths that will leak. Maybe just use a
> std::string?
> 
> Similarly with ?path?; I think this is always leaked. Maybe
> std::string here too.
> 
> Have you tried running the compiler under valgrind?  Configure with
> ?enable-valgrind-annotations and pass -wrap per=valgrind to the
> driver.

It's no accident, comrade.  ;-) 

My design criterion: the parser's memory requirements are linear with the 
input.  As grows the COBOL text, so grows the memory consumption.  Any more 
would be wrong; any less is pointless.  

The parser makes a single pass over the input.  It can't "leak" except in a 
loop.  In general it therefore never calls free(3).  Only when a string is 
being built up of consecutive allocations in a loop do we take any care with 
free.  

Before anyone suggests that's wasteful of memory, let's remind ourselves of the 
compiler's design.  The input text is transformed into a GENERIC tree.  The 
compiled program *must* fit in memory.  Much of that input needs to be retained 
as debug strings and supplied values.  

We have tested gcobol on large COBOL inputs, hundreds of thousands of lines.  
gcobol compiles those programs, as is, without freeing memory, on virtual 
machines that can barely link cc1.  

In the instant case, when open_file() fails, the compiler will soon terminate 
for lack of input.  Code generation will not be engaged.  The lost strings are 
literally no concern at all.  (I can see why that might not be obvious on first 
reading, and I hope I don't sound harsh or dismissive.)  

As for std::string, it would only complicate the front end.  Most strings in 
the parser are either fed back in to some C API or become parts of GENERIC 
nodes.  I admit having been tempted by std::stringstream for concatenation but 
in the end asprintf did most of what was needed.  

> Have you tried running the compiler under valgrind?  Configure with
> ?enable-valgrind-annotations and pass -wrap per=valgrind to the driver.

We have not tried that incantation, no.  We used valgrind for corruption 
problems, both times.  ;-)   We measured performance and memory use with the 
excellent Linux perf tool.  That is how we found the astonishing problems with 
std::regex (and also with how we were using it).  

I hope you see that we're taking care, but not too much care, with memory.  If 
there is a loop that is missing a free, we'll fix it, but I bet it won't 
matter, because these are just string fragments for filenames and such.  To 
dutifully call free for every allocated scrap of parsed input would be 
counterproductive: error-prone, and little if anything saved.  

--jkl

Reply via email to