Clear questions and runnable code get the best and fastest answer |
|
PerlMonks |
Re: Understanding Devel::Peek outputby ikegami (Patriarch) |
on Nov 29, 2020 at 20:39 UTC ( [id://11124375]=note: print w/replies, xml ) | Need Help?? |
I'll be referring to this PDF, Reini Urban's PerlGuts Illustrated. It contains all the information needed to answer your question, but I'll arrange in the information in a more convenient format here. There isn't just one type of scalar. See the graph at the bottom of the first page of the linked document. The ident that follows "SV =" indicates the type of the scalar. In this case, we have a SVt_IV. The type of scalar controls what kind of values can be stored in that scalar. In a SVt_IV, one can store an IV (signed int) or a UV (unsigned int), but not a string or floating point number. So what happens if you want to store a string inside the scalar? Well, Perl must first upgrade the scalar to a type that can handle the string. In this case, it will switch to a SVt_PVIV which can store a string in addition to a IV or UV.
Tangent: Note that while the upgraded scalar can hold both a string and an IV/UV, it only contains a string because POK is set but not IOK. In other words, while the slot for an IV exists (and holds the old IV value), the slot isn't storing any part of the scalar's value at this time because of the flags. The scalar is potentially referenced by multiple pointers, so how does Perl manage to upgrade the scalar to a larger one without invalidating those pointers? It does so by using two memory blocks to represent a scalar. The second address in the dump is the address of the head. This is what the various pointers reference. As you can see, the address of the head didn't change when the scalar was upgraded. Inside the head is a pointer to the second block, called the body. This is the first address in the dump. Upgrading a scalar upgrades a field in the head indicating the type of the scalar, and it replaces this block with a larger one. Now, let's look at the 64-bit example. Memory allocation is relatively expensive, so SVt_IV and SVt_RV utilize a hack to avoid memory allocation. One would expects a SVt_IV scalar to look like this:
Instead, it looks like this:
Buy why? Perl gets (probably significant) performance gains by keeping the IV slot at the same offset into the body of a scalar regardless of the type of the scalar. But I talked of a hack to avoid allocating a second memory block. We can avoid a memory allocation by overlapping both blocks!
Now we have a single memory block that points to itself. This is found at the very top of page 12 of the linked document. Finally, the answer to your question. The size of some fields in the head and body are independent of architecture (especially since you set the integer size to 64-bits for both builds), and the size of other fields in the head and body are dependent of architecture (e.g. the size of a pointer). The difference in the offset is based on differences in the total size of the head and body in the two builds.
In Section
Seekers of Perl Wisdom
|
|