in reply to Re^2: Circular reference testing.
in thread Circular reference testing.

If we're on a 64-bit machine, the SV headers are always more than 12 bytes, so using 12 as my divisor is safe?

(Do they becomes 16 or 24 bytes on 64-bit systems?)

SVs (and their friends AVs, HVs, etc) are defined in sv.h. They look like:

struct STRUCT_SV { /* struct sv { */ void* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ U32 sv_flags; /* what we are */ };
(AVs, HVs, etc, look the same, except they have a differently typed pointer as the first member of the struct). So their size is 8 bytes (assuming 8 bit bytes), plus the size of a pointer. On a system with 64 bits of addressable memory, pointers will be 8 bytes, giving a struct size of 16 bytes.

As for your other memory related questions, I think you have to dive into malloc.c in the Perl source to get your answer. I looked in the file, and it looks like it's written by someone not familiar with the rest of the perl source code: it actually has large comment sections.

Replies are listed 'Best First'.
Re^4: Circular reference testing.
by BrowserUk (Patriarch) on Mar 09, 2005 at 11:04 UTC

    Thanks for the info on the 64-bit headers.

    With respect to malloc.h. I've been there before, but the picture gets a little confused if you are not able to use Perl's malloc(), as is the case if you want USE_IMP_SYS, which is a pre-requisite for USE_MULTI which is a pre-requisite for both threads and fork. Which basically translates into: if you want threads, you have to use the CRT malloc (on win32 at least).

    That gets further confused by the presence of the routines in win32\vmem.h, which use the CRT memory routines, but then wrap other stuff around them which I won't pretend to understand.

    For my lower bound, I'm still looking to find a system global that gets allocated early and is unlikely to change.

    For the upper bound, I'm still looking at the idea of allocating a largish array and then hoping that undefing it and immediately allocating my bitstring will re-use the space.

    Earlier I was afraid that an array and a string would be allocated from different pools, but I now remember that Perl's arrays are not linked lists, but a continuous block of SVs. So, in theory, once the array is freed, it's space would be eligable for reuse by the string--but there is a lot of supposition in that. I was looking for confirmation/disuassion.


    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.
      For the upper bound, I'm still looking at the idea of allocating a largish array and then hoping that undefing it and immediately allocating my bitstring will re-use the space.

      That should be easy to try and find out? Devel::Peek will tell you the memory locations.

        In my simple tests, the SV is being reused, but that isn't the space I am concerned about being reused. The hope ws that the PVAV used by the array and the PV used by the bitvector would reuse the same space, but that isn't the case here.

        use Devel::Peek;; my @a = 1 .. 87382; Dump \@a; <STDIN>; undef @a; <STDIN>; my $b = 'x'x2**20; Dump \$b; <STDIN>; SV = RV(0x183573c) at 0x1cd99fc REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x195d6d0 SV = PVAV(0x195cb7c) at 0x195d6d0 REFCNT = 2 FLAGS = (PADBUSY,PADMY) IV = 0 NV = 0 ARRAY = 0x1d2fbbc FILL = 87381 MAX = 87381 ARYLEN = 0x0 FLAGS = (REAL) Elt No. 0 SV = IV(0x194246c) at 0x195d82c REFCNT = 1 FLAGS = (IOK,pIOK) IV = 1 Elt No. 1 SV = IV(0x1942468) at 0x195d814 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 2 Elt No. 2 SV = IV(0x1942470) at 0x1824704 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 3 Elt No. 3 SV = IV(0x1942474) at 0x195d7fc REFCNT = 1 FLAGS = (IOK,pIOK) IV = 4 SV = RV(0x183573c) at 0x195d82c REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x1cd999c SV = PV(0x225584) at 0x1cd999c REFCNT = 2 FLAGS = (PADBUSY,PADMY,POK,pPOK) PV = 0x203002c "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx... CUR = 1048576 LEN = 1048577

        There is also the problem that when the function is called, there would be no way to know what amount of reusable memory is alredy available in the system.

        On win32 I can query the VM size directly from the OS and form my upper bound from that, but I have no idea how to make that cross system compatible. Perl almost certainly has a good idea of where the end of it's memory is. I just don't have any clues how I could tap into that information?


        Examine what is said, not who speaks.
        Silence betokens consent.
        Love the truth but pardon error.