To start with the new storage management, I added four new standard functions to the Pascal system:
ALLOC, which gets a length and returns a pointer to a new area of that length
ALLOCX, which does the same, but does not use the (yet to come) sophisticated logic like LE, but does a pure GETMAIN on every ALLOCX call, which is simple, but slow
FREE, which frees the storage retrieved by ALLOC
FREEX, which frees the storage retrieved by ALLOCX, that is: FREEMAIN
Now the problem was: all the new functions should be written in Pascal; they should be located in a single module called PASLIBX and accessed by an entry $PASLIB and different function codes, and only the GETMAIN and FREEMAIN macros (with minimal interface code) should stay in the Pascal Monitor (which is coded in ASSEMBLER).
To make this possible, the compiler had to be extended; the standard procs until now only had one attribute, that is the number of the CSP call generated (called KEY). I added to the standard procs attributes like LIBNAME (8 characters), FUNCCODE (integer), PARMCNT (parameter count) and PROCTYP (result type). If LIBNAME is not blank, the standard proc will not be implemented by a CSP call (which was the only technique until now), but by a call to a certain library module, where the first parameter is the function code. The compiler will generate a normal nonstandard procedure or function call (CUP) using the attributes of the standard proc definition.
Furthermore, the compiler contains a new table where all those new standard library functions are defined. On compiler startup, in the procedure ENTSTDNAMES, the new procedures and their attributes are entered into the compiler's general identifier repository (using procedure ENTERID), in the same way as it is done for the other predefined functions and procedures.
When all this worked, I changed the compare utility called XCOMP (see above) to use the new ALLOCX and FREEX functions instead of NEW (no DISPOSE available). Having done this, XCOMP now was able to compare very large files without problems, because the GETMAIN / FREEMAIN implementation of CMS indeed frees storage, so that it can be reused later in the same run.
The Resource files (see below) have been updated; they now contain:
the newest release of the compiler (both passes)
the newest release of PASMONN.ASS (the Pascal Monitor, written in ASSEMBLER)
PASSNAP, which is the new version of the SNAPSHOT subroutine (now a MODULE)
PASLIBX, this is still work in progress; the ALLOC and FREE functions still have to be completed, but ALLOCX and FREEX are working
the XCOMP compare utility (which may be incomplete, too)
The Binaries (AWS Tape) has not yet been updated. This will be done in the next days.
This is a short example program which shows the usage of ALLOCX and FREEX:
|
Update - 16.10.2016
The new ALLOC and FREE functions (inspired by LE) are working, but there are still problems; at a certain point in time after millions of allocs and frees, some area of storage is overwritten.
I found out,
that this is due to the fact that the file access routines (QSAM)
start to write at places (when reading input data), where they should
not.
But the culprit must be my storage routines - I guess that they
affect the DCBs or any other file handling control block, but I didn't
find the error so far.
While trying to find the error, I did additional extensions to the compiler:
pointers of any type can be written directly using WRITE; the output is 8 hex digits (implemented by a new P-Code instruction WRP)
the function PTRADD, which can be used without arguments to cast pointers of any type, can be written as PTRCAST, too (implemented inline, no change to PASCAL2)
there is a new function FILEFCB, which gets a file name as an argument and returns a pointer to the internal file control block (containing the DCB etc.); this is implemented in PASLIBX and in PASMONN, no change to PASCAL2 and no P-Code extension
Before I publish new binaries, I want to resolve the problem with the storage management, first.
Update - 20.10.2016
I finally fixed the problem in the storage functions similar to the LE storage handler. It was kind of strange, because due to a logic error in these storage management functions, a QSAM file buffer got overlaid by an allocated storage area, which in turn leaded to a QSAM read overwriting the QSAM file management area, but this did not stop QSAM from working, but it did the subsequent reads to different (wrong) places, and this (finally) destroyed the meta information of the storage management system.
I only found this, when I monitored the QSAM buffers all the time and checked the moment when the contents changed from right to wrong. This was a storage allocation of a certain type, which did something wrong with respect to the management of the free areas in the heap segment, and the QSAM buffer, which followed directly in storage, was affected.
When I repaired this, all was ok. And: the change from normal GETMAIN/FREEMAIN to the new allocation functions (similar to LE) lead to a 5 percent overall CPU reduction of the compare utility XCOMP in my testcase.
So this topic is closed; the storage management functions work as they are designed, and the XCOMP utility, too.
Here are two examples; the first one compares two versions of the compiler (12000 lines), and the second one compares RUNPARM ASSEMBLE with my improved version XRUNPARM ASSEMBLE. Both versions were compared with -m9, that is: 9 lines have to match to synchronize (this is a value that I use very often; it is a good compromise and yields good results). The ASSEMBLER compare was done using -w, that is: differences involving only white space are ignored. This is important, because I aligned many comments, and those lines should be considered unchanged. The only significant change I made to XRUNPARM is that it inserts blank between the parameter tokens coming from CMS (which RUNPARM did not; this was an error IMO).
XCOMP-Example: Comparing Compiler versions