Hi! I need some help in understanding three things viewed in heap.inc.
1) Why is variable "heap_lock_use" declared as "integer"? Apparently this
variable never gets a negative value. Also, this variable never gets used as a
parameter to a function/procedure call that would require a transformation of
variable content(longint to byte as example). If this variable never gets a
negative value then using an unsigned integer might improve in certain
circumstances a little bit the code produced because apparently fpc trunk has
improved zero and near zero integer comparisons at high optimization levels. If
this is the case then comparing actual "signed_integer>0" should not be faster
than "unsigned_integer<>0" automatically produced code at high optimization
levels. Am I wrong here? As a side note, I would prefer manually changing those
">0" with "<>0" inside "InitHeapThread", "RelocateHeap" and "FinalizeHeap"
but...whatever.
2) I'm not interested in the importance of the presented function. Why the
"existing" code is preferred over "alternative" code?
"Existing" code:
Function SysFreeMemSize(p: pointer; size: ptruint):ptruint;
begin
if size=0 then
exit(0);
{ can't free partial blocks, ignore size }
result := SysFreeMem(p);
end;
"Alternative" code:
Function SysFreeMemSize(p: pointer; size: ptruint):ptruint;
begin
if size<>0 then SysFreeMem(p) else Result:=nil; { can't free partial blocks,
ignore size }
end;
There are two things that puzzle me:
a) The alternative code appears better to me because I think this function will
have size<>0 more often than size=0. Why the existing code design was preferred?
b) As found out working at the "slow if...then...else" report, the existing of
an "exit" procedure, starting with level 2 optimization, leads to different
registers used within assembly code. Is this a reason why main developers use
so often the "exit" procedure? Is there something that I'm missing at the
moment, something like: "starting with level2 optimizations, existence of
"exit" procedure in a pascal code requires additional analysis that, as a side
effect, usually improve register allocation "...or whatever reason to use this
procedure?
3) I'm not interested in the importance of the presented function. Why the
"existing" code design is preferred over "alternative" code?
Existing code:
function SysAllocMem(size: ptruint): pointer;
begin
result := MemoryManager.GetMem(size);
if result<>nil then
FillChar(result^,MemoryManager.MemSize(result),0);
end;
Alternative code:
function SysAllocMem(size: ptruint): pointer;
begin
result:=MemoryManager.GetMem(size);
if result<>nil then FillChar(result^,size,0);
end;
The only things I could find to support the "existing" code over "alternative"
code are that(now or in the future):
a) Maybe there is a possibility that the value of variable size gets changed
after "result:=MemoryManager.GetMem(size);"
b) Maybe there is a possibility that following
"result:=MemoryManager.GetMem(size);" variable result would point to a memory
block that has allocated a size different than variable "size"'s content.
I would feel confortable if these things would be explained to me straight
from the horse's mouth. Meaning people that understand the importance of the
existing code, not people that would send me to find out using "try&error"
techniques, as those "try&error" results would mean nothing to me regarding
this subject for too many reasons to be written here.
_______________________________________________
fpc-devel maillist - [email protected]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel