[fpc-pascal] Inclocked/declocked

Sven Barth pascaldragon at googlemail.com
Mon Sep 11 21:35:11 CEST 2017


On 11.09.2017 11:46, Ryan Joseph wrote:
> 
>> On Sep 11, 2017, at 4:20 PM, Sven Barth via fpc-pascal <fpc-pascal at lists.freepascal.org> wrote:
>>
>> They're used for the reference counter of the array (or string or interface). The reference counter changes each time you assign an array or pass it to a by-value parameter or if you change a value (cause the compiler/RTL needs to make sure that the reference to the array is unique then).
>>
>>
> 
> Maybe this is relevant to my poor performance then but perhaps it’s just the way the time profiler works? It’s telling me the program is spending  16% in system_delocked which seems extreme.
> 
> See if I have a dynamic array and call arr[0] := xxx then those functions will be called (or FPC_DYNARRAY_ASSIGN)? I also have a dynamic array in an object which is passed a function parameter, but not by value so that doesn’t fit your description.

I've rechecked and the thing is as follows:
- the IncLocked call happens each time you assign a dynamic array to
another dynamic array variable or a by-value parameter (this also
includes being part of a record, but not a class instance or TP-style
object)
- the DecLocked call happens each time the array is cleared (as long as
the reference count is > 0 this only means a decrement of the count)
which happens if you assign Nil, assign a different array (the
destination array is "cleared") or if the array variable goes out of scope

The two routines are also used in context of Ansi- and UnicodeString
variables as well as reference counted interfaces (aka COM-style
interfaces).

In contrast to what I wrote earlier the compiler does however not ensure
a unique array if you only change an element, so given the following
example:

=== code begin ===

program tarrtest;

procedure Test(aArg: array of LongInt);
var
  i: LongInt;
begin
  for i in aArg do
    Writeln(i);
end;

var
  ia1, ia2: array of LongInt;
begin
  ia1 := [1, 2, 3];
  ia2 := ia1;
  ia1[1] := 5;
  Test(ia1);
  Test(ia2);
end.

=== code end ===

The output will be

=== output begin ===

1
5
3
1
5
3

== output end ===

Regards,
Sven



More information about the fpc-pascal mailing list