without excessive memory needs. The assumption is that your CPU cache
works :-) (And that we're not going to bust it) */
-#define ALIGN_BITS ( sizeof(void*) >> 1 )
#define BYTE_BITS 3
#define LEAF_BITS (16 - BYTE_BITS)
#define LEAF_MASK 0x1FFF
(and hence hot in the cache) but we can still deal with any unaligned
pointers. */
const size_t cooked_p
- = (raw_p >> ALIGN_BITS) | (raw_p << (bits - BYTE_BITS));
+ = (raw_p >> ALIGN_BITS) | (raw_p << (bits - ALIGN_BITS));
const U8 this_bit = 1 << (cooked_p & 0x7);
U8 **leaf_p;
U8 *leaf;
if(isGV_with_GP(thing)) {
st->total_size += GvNAMELEN(thing);
#ifdef GvFILE
- /* Is there a file? */
+# if !defined(USE_ITHREADS) || (PERL_VERSION > 8 || (PERL_VERSION == 8 && PERL_SUBVERSION > 8))
+ /* With itreads, before 5.8.9, this can end up pointing to freed memory
+ if the GV was created in an eval, as GvFILE() points to CopFILE(),
+ and the relevant COP has been freed on scope cleanup after the eval.
+ 5.8.9 adds a binary compatible fudge that catches the vast majority
+ of cases. 5.9.something added a proper fix, by converting the GP to
+ use a shared hash key (porperly reference counted), instead of a
+ char * (owned by who knows? possibly no-one now) */
check_new_and_strlen(st, GvFILE(thing));
+# endif
#endif
/* Is there something hanging off the glob? */
if (check_new(st, GvGP(thing))) {
/* If they passed us a reference then dereference it. This is the
only way we can check the sizes of arrays and hashes */
-#if (PERL_VERSION < 11)
- if (SvOK(thing) && SvROK(thing)) {
- thing = SvRV(thing);
- }
-#else
if (SvROK(thing)) {
thing = SvRV(thing);
}
-#endif
sv_size(aTHX_ st, thing, ix);
RETVAL = st->total_size;