3 ms·
Hey Bob. Still a big fan of this project. Thank you! This chapter introduces not only strings but the concept of more complex value types that use an auxiliary
by smueller1234 8y ago
Hey Bob. Still a big fan of this project. Thank you!
This chapter introduces not only strings but the concept of more complex value types that use an auxiliary struct. There's an anecdote related to that which you might find amusing - and maybe a bit appalling.
In the implementation of perl, there's multiple kinds of integer value type in order to support it's complex implicit casting semantics and additional edge cases. To pick the least wonky, there's plain integer values, "IVs", and those which have a stringified representation of the int attached for caching the expensive conversion, "PVIVs". The former store the int in the primary value struct. The latter use an auxiliary struct with extra space.
Now, the reason for all this prep is that in order to make the two behave the same, and not introduce a lot of branches to low level code, perl always uses the indirect access to the integer value (essentially "x->aux.intval"). This works because for basic integer values, it initializes the aux pointer in the main struct to point to the right place in memory before the location of the main struct such that this access always points at the right slot of the main struct. Madness! So much fun!
(A better explanation is at https://medium.com/booking-com-development/how-we-spent-two-days-making-perl-faster-939457ef16a1 https://medium.com/booking-com-development/how-we-spent-two-...)
- munificent 8y agoThis is fascinating!
- smueller1234 8y agoIs that code for nausea inducing? ;) The perl implementation is full of this sort of stuff. Some corners are hardly penetrable because of it. I'll be visiting the offices in MSN and KIR/SEA next week. Happy to rant over coffee or a drink some night if timing works out.
- Serow225 8y agoFYI stray period at the end of your link breaks it :)
- smueller1234 8y agoFixed, thank you!
- _old_dude_ 8y agoShenandoah, one of the GCs in Java uses a similar trick, each time there is an access to a field, instead of directly accessing to it, the VM access to a pointer at the top of the structure that point just to the address below itself, so each field is read using a double indirection. This allows the application to run when the GC move the objects (during the evacuation phase), because each time the GC relocate an object, it also changes the top pointer in the old region to reference the new region. The GC also rewrites the pointers inside the stacks by replacing the pointer to the old region by the value of the top pointer, so the pointers in the stack now reference the new region too.
- smueller1234 8y agoAh, and I'd always wanted to read up on that and never prioritized it. Thank you! This might be a naive question, but how do you do all that redirection under concurrent accesses? Clearly that amount of rewiring isn't going to be atomic? Or am I misunderstand and the only change that needs to be atomic is the top-of-structure redirection?
- _old_dude_ 8y agoAs you said, only the top pointer need a CAS. If you want more info, the is a good presentation by Christine Flood about Shenandoah at FOSDEM 2017 https://archive.fosdem.org/2017/schedule/event/shenandoah/ https://archive.fosdem.org/2017/schedule/event/shenandoah/