develooper Front page | perl.perl5.porters | Postings from January 2008

SvOOK() now doesn't (ab)use SvIVX

Thread Next
From:
Nicholas Clark
Date:
January 4, 2008 15:38
Subject:
SvOOK() now doesn't (ab)use SvIVX
Message ID:
20080104233826.GO7829@plum.flirble.org
I did this:

Change 32836 by nicholas@nicholas-bouvard on 2008/01/04 23:12:01

	Re-implement the SvOOK() hack to store the offset as a BER encoded
	number in the part of the PVX that is being released. (It will always
	fit, as chopping off 1 byte gives just enough space for recording a
	delta of up to 127). This allows SvOOK() to co-exist with SvIOK_on(),
	which means all the calls to SvOOK_off() [with the possibility of a
	call to sv_backoff()] in SvIOK_on() can be removed. This ought to make
	a lot of straight line code a little bit simpler.
	OOK()d scalars can now be SVt_PV, as the IVX isn't needed.


Mainly so that I can get SvIOK_on() from this:

# 3 "SvIOK_on expands to"
(({;}), ((void)(((A0)->sv_flags & 0x02000000) && Perl_sv_backoff(A0))), (A0)->sv_flags |= (0x00000100|0x00001000))

to this:

# 3 "SvIOK_on expands to"
(({;}), (A0)->sv_flags |= (0x00000100|0x00001000))


as I can't think that the code for a flag check and possible function call
inlined everywhere is that helpful.


For those who weren't aware, the "OOK" hack is a way of efficiently removing
octets from the start of the PVX buffer by moving the pointer, and recording
how far it moved, hence giving the appearance of moving the rest of the
buffer's contents in memory, viz:

$ perl -MDevel::Peek -e '$_ = "Pie"; s/..//; Dump $_; $_ = 3; Dump $_'
SV = PVIV(0x805982c) at 0x8057118
  REFCNT = 1
  FLAGS = (POK,OOK,pPOK)
  IV = 2  (OFFSET)
  PV = 0x805a82a ( "Pi" . ) "e"\0
  CUR = 1
  LEN = 2
SV = PVIV(0x805982c) at 0x8057118
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 3
  PV = 0x805a828 "e"\0
  CUR = 1
  LEN = 4


Only the old implementation required that the scalar be upgraded to (at least)
SVt_PVIV, and the IVX be "borrowed", which in turn meant that if you need to
set the IVX, you have to undo the OOK:

$ perl -MDevel::Peek -e '$_ = "Pie"; s/..//; Dump $_; $_ = 3; Dump $_'
SV = PVIV(0x805982c) at 0x8057118
  REFCNT = 1
  FLAGS = (POK,OOK,pPOK)
  IV = 2  (OFFSET)
  PV = 0x805a82a ( "Pi" . ) "e"\0
  CUR = 1
  LEN = 2
SV = PVIV(0x805982c) at 0x8057118
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 3
  PV = 0x805a828 "e"\0
  CUR = 1
  LEN = 4


The new implementation doesn't "borrow" the IVX, but instead stores the offset
BER encoded in the part of the buffer that has just been chopped off. It needs
to be BER, because if you chop off less than 4 characters, you don't have
space to store a longer integer. So the examples now look like this:

$ ./perl -Ilib -MDevel::Peek -e '$_ = "Pie"; Dump $_; s/..//; Dump $_'
SV = PV(0x8117038) at 0x813cce0
  REFCNT = 1
  FLAGS = (POK,pPOK)
  PV = 0x81151c0 "Pie"\0
  CUR = 3
  LEN = 4
SV = PV(0x8117038) at 0x813cce0
  REFCNT = 1
  FLAGS = (POK,OOK,pPOK)
  OFFSET = 2
  PV = 0x81151c2 ( "P\2" . ) "e"\0
  CUR = 1
  LEN = 2

$ ./perl -Ilib -MDevel::Peek -e '$_ = "Pie"; s/..//; Dump $_; $_ = 3; Dump $_'
SV = PV(0x8117038) at 0x813cce0
  REFCNT = 1
  FLAGS = (POK,OOK,pPOK)
  OFFSET = 2
  PV = 0x81151c2 ( "P\2" . ) "e"\0
  CUR = 1
  LEN = 2
SV = PVIV(0x8119004) at 0x813cce0
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 3
  PV = 0x81151c0 "e"\0
  CUR = 1
  LEN = 4


Slight "annoyance" is that the OOK is still being undone thanks to this:

#define SvOK_off(sv)		(assert_not_ROK(sv) assert_not_glob(sv)	\
				 SvFLAGS(sv) &=	~(SVf_OK|		\
						  SVf_IVisUV|SVf_UTF8),	\
							SvOOK_off(sv))
#define SvOK_off_exc_UV(sv)	(assert_not_ROK(sv)			\
				 SvFLAGS(sv) &=	~(SVf_OK|		\
						  SVf_UTF8),		\
							SvOOK_off(sv))


I'm not sure whether to change that to remove the SvOOK_off() (as that is
forcing the copy)

However, I notice from the above example that the copy is done even if
SvPOK() is false - ie there is a buffer, but its contents aren't considered
useful. I'll try removing that.

Nicholas Clark

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About