Aleksey V. Vaneev wrote 9 lines
> That's the problem in your project not from the compiler. You need to rethink your module
> structure in your project to solve this or think about an different initialization using
> InitModule and DoneModule procedures and calling those yourselves.
That's impossible in all the cases. I will need then to join all
modules or at least a huge amount of them into one module.
Regarding "initmodule" and "donemodule".. Can't understand why
initialization and finalization things be needed if I will be forced to
do things this way. FPC will look like C after all.
It's just the way things are supposed to work: initialize everything in the order they are declared. How on earth is the compiler supposed to to know that unit x's initialization code depends on unit y being initialized already except from the order of declaration in the uses clauses??
I really don't see what kind of algorithm could solve that. It's as Peter said: you have to desing your project in such a way that the initialization routines are called int he correct order and if that isn't possible, use some initmodule/donemodule technique.
BTW, can you briefly explain work of built in FPC memory manager (what
kind of trees are used if any, etc)? Just wanted to know - maybe
there's some place for the development...
It's a hashtable based on the size of the memory blocks rounded up to a multiple of 16bytes. Each location in the hashtable contains a linked list of blocks of that size * 16. The maximum blocksize for which such a list is kept, is 512 bytes. All blocks > 512 bytes end up in a separate (common) linked list.
If you allocate a block and it's <= 512, we first look in the hashtable to see if there are any free blocks of that size. If so, it is returned and removed from its list. If not, we first search bigger blocks to split into smaller ones (upto 8 times the size of the requested block) and otherwise we simply create a new block at the end of the heap.
If you allocate a block > 512 bytes we search the freelist of large blocks (linear search) and if no large enough block is found, then we allocate a new one at the end of the heap. By default, we search the freelist of the large blocks to find the best match (enabled via a define in rtl/inc/heap.inc).
When releasing a block,
a) if it's <= 512 bytes, it's added to the appropriate freelist in the hashtable
b) otherwise we first check whether there aren't any other blocks coming after it and if so, we concatenate those (it's possible to disable this, again using a define)
But as Peter already said, the heap manager is very optimized. We got some patches a couple of months ago to make it slightly faster (10% or so), but I don't think they're already applied.
Jonas