in reply to Moving an OP and replacing it

Not all OP objects are the same size so do I have to be concerned that a 28 byte hole would have to accomodate a 56 byte op? Is there slack space built in?

Put the question in C terms. If you wanted 28 bytes to store a C struct and had an array of such structs in memory would you:

  1. Expect that these structs will be represented in memory by a contiguous array of 28 byte chunks
  2. Expect that just in case someone wanted to hand insert a 56 byte struct the programmer/compiler allocated 28 bytes + 28 spare??????

Now I don't know the real answer but I would be a little suprised if writing 56 bytes into a 28 byte hole did not overwrite the neighbouring 28 byte struct. Why have 28 and 56 byte structs if you always allocate 56 (which is what you are asking for)?

The only way I could see it working is if you replace the old object with a new object (less than or equal in size to the old) that points to a freshly allocated OP object in a free chunk of memory.

cheers

tachyon

Replies are listed 'Best First'.
Re: Re: Moving an OP and replacing it
by diotalevi (Canon) on Jun 01, 2004 at 02:59 UTC
    I would be surprised as well but I don't know if the memory for the optree is actually packed that way or if it really could be treated that way.

      If you have a look at memory allocation and the op tree with -MO=Debug then you can see that Perl appears to be allocating space in line with requirements. You can see ops 60 32 40 32 40 124 40 76 bytes appart in physical memory.... Pot luck not overwriting a neighbouring op I would have thought:

      C:\>type test.pl my $greet = "Hello World!\n"; print $greet; C:\>perl -MO=Debug test.pl LISTOP (0x1bb3c00) op_next 0x0 op_sibling 0x0 op_ppaddr PL_ppaddr[OP_LEAVE] op_targ 1 op_type 178 op_seq 6616 op_flags 13 op_private 64 op_first 0x1bb3b1c op_last 0x1bb3bb8 op_children 5 OP (0x1bb3b1c) op_next 0x1bb3c28 op_sibling 0x1bb3c28 op_ppaddr PL_ppaddr[OP_ENTER] op_targ 0 op_type 177 op_seq 6607 op_flags 0 op_private 0 COP (0x1bb3c28) op_next 0x1bb3ccc op_sibling 0x1bb3ca4 op_ppaddr PL_ppaddr[OP_NEXTSTATE] op_targ 0 op_type 174 op_seq 6608 op_flags 1 op_private 0 cop_label cop_stashpv main cop_file test.pl cop_seq 6608 cop_arybase 0 cop_line 1 cop_warnings 0x0 BINOP (0x1bb3ca4) op_next 0x1bb3b5c op_sibling 0x1bb3b5c op_ppaddr PL_ppaddr[OP_SASSIGN] op_targ 0 op_type 36 op_seq 6611 op_flags 69 op_private 2 op_first 0x1bb3ccc op_last 0x1bb3d18 SVOP (0x1bb3ccc) op_next 0x1bb3d18 op_sibling 0x1bb3d18 op_ppaddr PL_ppaddr[OP_CONST] op_targ 3 op_type 5 op_seq 6609 op_flags 2 op_private 0 op_sv 0x0 Nullsv OP (0x1bb3d18) op_next 0x1bb3ca4 op_sibling 0x0 op_ppaddr PL_ppaddr[OP_PADSV] op_targ 1 op_type 9 op_seq 6610 op_flags 178 op_private 128 COP (0x1bb3b5c) op_next 0x1bb3b98 op_sibling 0x1bb3bb8 op_ppaddr PL_ppaddr[OP_NEXTSTATE] op_targ 0 op_type 174 op_seq 6612 op_flags 1 op_private 0 cop_label cop_stashpv main cop_file test.pl cop_seq 6612 cop_arybase 0 cop_line 2 cop_warnings 0x0 LISTOP (0x1bb3bb8) op_next 0x1bb3c00 op_sibling 0x0 op_ppaddr PL_ppaddr[OP_PRINT] op_targ 0 op_type 209 op_seq 6615 op_flags 5 op_private 0 op_first 0x1bb3b98 op_last 0x1bb3be0 op_children 2 OP (0x1bb3b98) op_next 0x1bb3be0 op_sibling 0x1bb3be0 op_ppaddr PL_ppaddr[OP_PUSHMARK] op_targ 0 op_type 3 op_seq 6613 op_flags 2 op_private 0 OP (0x1bb3be0) op_next 0x1bb3bb8 op_sibling 0x0 op_ppaddr PL_ppaddr[OP_PADSV] op_targ 1 op_type 9 op_seq 6614 op_flags 3 op_private 0 test.pl syntax OK C:\>perl -MO=Debug test.pl >debug test.pl syntax OK C:\>perl -ne "m/op_next\s*(\S+)/ and $h{$1}++;END{print \"$_\n\" for s +ort{$a<=>$b}map{hex}keys %h}" debug 0 29047644 29047704 29047736 29047776 29047808 29047848 29047972 29048012 29048088 C:\>perl -ne "m/op_next\s*(\S+)/ and $h{$1}++;END{print \"$_\n\" for s +ort{$a<=>$b}map{hex}keys %h}" debug >memloc C:\>perl -ne "print $_-$a,$/;$a=$_" memloc 0 29047644 60 32 40 32 40 124 40 76 C:\>

      cheers

      tachyon