libcwal  Hex Artifact Content

Artifact 461a66c48507a74eddf2df49fd7204f420ab77b7:

Wiki page [MemoryModel] by stephan 2014-05-09 15:22:20.
0000: 44 20 32 30 31 34 2d 30 35 2d 30 39 54 31 35 3a  D 2014-05-09T15:
0010: 32 32 3a 32 30 2e 34 32 39 0a 4c 20 4d 65 6d 6f  22:20.429.L Memo
0020: 72 79 4d 6f 64 65 6c 0a 50 20 31 62 37 36 38 64  ryModel.P 1b768d
0030: 34 62 30 62 33 61 36 62 65 37 36 39 33 39 39 64  4b0b3a6be769399d
0040: 35 37 65 35 33 39 64 62 33 62 33 35 30 65 33 36  57e539db3b350e36
0050: 64 63 0a 55 20 73 74 65 70 68 61 6e 0a 57 20 31  dc.U stephan.W 1
0060: 34 39 30 33 0a 53 65 65 20 61 6c 73 6f 3a 20 5b  4903.See also: [
0070: 44 61 74 61 54 79 70 65 73 5d 2c 20 5b 63 77 61  DataTypes], [cwa
0080: 6c 5f 67 63 5d 0d 0a 0d 0a 3c 68 31 3e 63 77 61  l_gc]....<h1>cwa
0090: 6c 27 73 20 4d 65 6d 6f 72 79 20 4d 6f 64 65 6c  l's Memory Model
00a0: 3c 2f 68 31 3e 0d 0a 0d 0a 63 77 61 6c 20 67 65  </h1>....cwal ge
00b0: 74 73 20 69 74 73 20 6d 65 6d 6f 72 79 20 66 72  ts its memory fr
00c0: 6f 6d 20 61 20 63 6c 69 65 6e 74 2d 73 75 70 70  om a client-supp
00d0: 6c 69 65 64 20 61 6c 6c 6f 63 61 74 6f 72 20 28  lied allocator (
00e0: 61 20 64 65 66 61 75 6c 74 20 77 68 69 63 68 20  a default which 
00f0: 75 73 65 73 20 74 68 65 20 73 79 73 74 65 6d 20  uses the system 
0100: 61 6c 6c 6f 63 61 74 6f 72 20 69 73 20 70 72 6f  allocator is pro
0110: 76 69 64 65 64 2c 20 6f 66 20 63 6f 75 72 73 65  vided, of course
0120: 29 2e 20 4f 6e 20 74 6f 70 20 6f 66 20 74 68 61  ). On top of tha
0130: 74 20 61 6c 6c 6f 63 61 74 6f 72 20 63 77 61 6c  t allocator cwal
0140: 20 70 65 72 66 6f 72 6d 73 20 76 61 72 69 6f 75   performs variou
0150: 73 20 68 69 67 68 65 72 2d 6c 65 76 65 6c 20 6d  s higher-level m
0160: 65 6d 6f 72 79 2d 6d 61 6e 61 67 65 6d 65 6e 74  emory-management
0170: 20 74 61 73 6b 73 20 73 75 63 68 20 61 73 20 74   tasks such as t
0180: 68 65 20 69 6e 69 74 69 61 6c 69 7a 61 74 69 6f  he initializatio
0190: 6e 2c 20 64 65 73 74 72 75 63 74 69 6f 6e 2c 20  n, destruction, 
01a0: 61 6e 64 20 72 65 63 79 63 6c 69 6e 67 20 6f 66  and recycling of
01b0: 20 61 62 73 74 72 61 63 74 20 56 61 6c 75 65 73   abstract Values
01c0: 2e 20 0d 0a 0d 0a 63 77 61 6c 27 73 20 70 72 69  . ....cwal's pri
01d0: 6d 61 72 79 20 66 65 61 74 75 72 65 20 69 73 20  mary feature is 
01e0: 69 74 73 20 6d 61 6e 61 67 65 6d 65 6e 74 20 6f  its management o
01f0: 66 20 56 61 6c 75 65 73 20 6f 6e 20 62 65 68 61  f Values on beha
0200: 6c 66 20 6f 66 20 74 68 65 20 63 6c 69 65 6e 74  lf of the client
0210: 2e 20 49 74 20 6d 61 6e 61 67 65 73 20 73 75 63  . It manages suc
0220: 68 20 6d 65 6d 6f 72 79 20 69 6e 20 73 63 6f 70  h memory in scop
0230: 65 73 2c 20 77 68 69 63 68 20 62 65 68 61 76 65  es, which behave
0240: 20 6d 6f 72 65 20 6f 72 20 6c 65 73 73 20 6c 69   more or less li
0250: 6b 65 20 43 2b 2b 20 73 63 6f 70 65 73 2c 20 69  ke C++ scopes, i
0260: 6e 20 74 68 61 74 20 6f 6e 6c 79 20 6f 6e 65 20  n that only one 
0270: 63 61 6e 20 62 65 20 61 63 74 69 76 65 20 61 74  can be active at
0280: 20 61 20 74 69 6d 65 2c 20 74 68 65 72 65 20 69   a time, there i
0290: 73 20 61 20 73 74 61 63 6b 20 6f 66 20 74 68 65  s a stack of the
02a0: 6d 2c 20 61 6e 64 20 77 68 65 6e 20 6f 6e 65 20  m, and when one 
02b0: 65 6e 64 73 20 28 69 73 20 70 6f 70 70 65 64 20  ends (is popped 
02c0: 66 72 6f 6d 20 74 68 65 20 73 74 61 63 6b 29 20  from the stack) 
02d0: 61 6c 6c 20 76 61 6c 75 65 73 20 63 72 65 61 74  all values creat
02e0: 65 64 20 69 6e 20 74 68 61 74 20 73 63 6f 70 65  ed in that scope
02f0: 20 62 75 74 20 6e 6f 74 20 73 6f 6d 65 68 6f 77   but not somehow
0300: 20 70 61 73 73 65 64 20 6f 75 74 20 6f 66 20 74   passed out of t
0310: 68 61 74 20 73 63 6f 70 65 20 61 72 65 20 63 6c  hat scope are cl
0320: 65 61 6e 65 64 20 75 70 2e 20 54 68 61 74 27 73  eaned up. That's
0330: 20 6d 6f 72 65 20 6f 72 20 6c 65 73 73 20 63 77   more or less cw
0340: 61 6c 27 73 20 63 6f 72 65 20 66 75 6e 63 74 69  al's core functi
0350: 6f 6e 61 6c 69 74 79 2e 20 49 74 20 64 6f 65 73  onality. It does
0360: 20 74 68 69 73 20 74 68 72 6f 75 67 68 20 74 68   this through th
0370: 65 20 75 73 65 20 6f 66 20 73 65 76 65 72 61 6c  e use of several
0380: 20 61 62 73 74 72 61 63 74 69 6f 6e 73 2e 2e 2e   abstractions...
0390: 0d 0a 0d 0a 56 61 6c 75 65 73 20 61 72 65 20 61  ....Values are a
03a0: 6c 6c 20 6f 66 20 61 20 62 61 73 65 20 74 79 70  ll of a base typ
03b0: 65 20 77 68 69 63 68 20 70 72 6f 76 69 64 65 73  e which provides
03c0: 20 73 6f 6d 65 20 73 6d 61 6c 6c 20 64 65 67 72   some small degr
03d0: 65 65 20 70 6f 6c 79 6d 6f 72 70 68 69 63 20 62  ee polymorphic b
03e0: 65 68 61 76 69 6f 75 72 20 76 69 61 20 61 20 73  ehaviour via a s
03f0: 69 6d 70 6c 65 20 73 75 62 63 6c 61 73 73 69 6e  imple subclassin
0400: 67 20 6d 65 63 68 61 6e 69 73 6d 2c 20 61 6c 6c  g mechanism, all
0410: 6f 77 69 6e 67 20 74 68 65 20 65 6e 67 69 6e 65  owing the engine
0420: 20 74 6f 20 77 6f 72 6b 20 77 69 74 68 20 61 20   to work with a 
0430: 62 61 73 65 20 69 6e 74 65 72 66 61 63 65 20 6d  base interface m
0440: 6f 72 65 20 6f 66 74 65 6e 20 74 68 61 6e 20 6e  ore often than n
0450: 6f 74 2e 20 53 6f 6d 65 74 69 6d 65 73 2c 20 66  ot. Sometimes, f
0460: 6f 72 20 74 68 65 20 73 61 6b 65 20 6f 66 20 68  or the sake of h
0470: 61 6e 64 6c 69 6e 67 20 63 79 63 6c 65 73 2c 20  andling cycles, 
0480: 77 65 20 68 61 76 65 20 74 6f 20 64 69 66 66 65  we have to diffe
0490: 72 65 6e 74 69 61 74 65 20 62 65 74 77 65 65 6e  rentiate between
04a0: 20 22 63 6f 6e 74 61 69 6e 65 72 73 22 20 61 6e   "containers" an
04b0: 64 20 22 73 69 6d 70 6c 65 22 20 76 61 6c 75 65  d "simple" value
04c0: 73 20 28 74 68 6f 73 65 20 77 68 69 63 68 20 63  s (those which c
04d0: 61 6e 20 63 6f 6e 74 61 69 6e 20 63 68 69 6c 64  an contain child
04e0: 20 76 61 6c 75 65 73 20 61 6e 64 20 74 68 6f 73   values and thos
04f0: 65 20 77 68 69 63 68 20 63 61 6e 6e 6f 74 29 20  e which cannot) 
0500: 62 65 63 61 75 73 65 20 63 6f 6e 74 61 69 6e 65  because containe
0510: 72 73 20 63 61 6e 20 6c 65 61 64 20 74 6f 20 63  rs can lead to c
0520: 79 63 6c 65 73 2e 0d 0a 0d 0a 53 63 6f 70 65 73  ycles.....Scopes
0530: 20 61 63 74 20 61 73 20 61 20 22 72 6f 6f 74 22   act as a "root"
0540: 20 66 6f 72 20 61 6c 6c 6f 63 61 74 69 6f 6e 73   for allocations
0550: 2c 20 61 6e 64 20 6e 65 77 6c 79 2d 61 6c 6c 6f  , and newly-allo
0560: 63 61 74 65 64 20 76 61 6c 75 65 73 20 61 72 65  cated values are
0570: 20 6f 77 6e 65 64 20 62 79 20 74 68 65 20 63 75   owned by the cu
0580: 72 72 65 6e 74 6c 79 2d 61 63 74 69 76 65 20 73  rrently-active s
0590: 63 6f 70 65 2e 20 57 68 65 6e 20 61 20 73 63 6f  cope. When a sco
05a0: 70 65 20 69 73 20 63 6c 65 61 6e 65 64 2c 20 61  pe is cleaned, a
05b0: 6c 6c 20 76 61 6c 75 65 73 20 69 74 20 63 75 72  ll values it cur
05c0: 72 65 6e 74 6c 79 20 6f 77 6e 73 20 61 72 65 20  rently owns are 
05d0: 63 6c 65 61 6e 65 64 20 75 70 20 69 6e 20 73 75  cleaned up in su
05e0: 63 68 20 61 20 77 61 79 20 61 73 20 74 6f 20 70  ch a way as to p
05f0: 72 6f 76 69 64 65 20 64 65 74 65 72 6d 69 6e 69  rovide determini
0600: 73 74 69 63 20 62 65 68 61 76 69 6f 75 72 20 69  stic behaviour i
0610: 6e 20 74 68 65 20 66 61 63 65 20 6f 66 20 63 79  n the face of cy
0620: 63 6c 65 73 2c 20 73 75 63 68 20 74 68 61 74 20  cles, such that 
0630: 61 6c 6c 20 63 79 63 6c 65 73 20 63 61 6e 20 62  all cycles can b
0640: 65 20 62 72 6f 6b 65 6e 20 61 6e 64 20 63 6c 65  e broken and cle
0650: 61 6e 65 64 20 75 70 20 70 72 6f 70 65 72 6c 79  aned up properly
0660: 2e 0d 0a 0d 0a 4f 77 6e 65 72 73 68 69 70 20 6f  .....Ownership o
0670: 66 20 76 61 6c 75 65 73 20 75 73 65 73 20 61 20  f values uses a 
0680: 6d 69 78 74 75 72 65 20 6f 66 20 73 63 6f 70 65  mixture of scope
0690: 2d 6c 65 76 65 6c 20 61 6e 64 20 72 65 66 65 72  -level and refer
06a0: 65 6e 63 65 20 63 6f 75 6e 74 69 6e 67 2e 20 41  ence counting. A
06b0: 74 20 74 68 65 20 62 61 73 65 2c 20 72 65 66 65  t the base, refe
06c0: 72 65 6e 63 65 20 63 6f 75 6e 74 69 6e 67 20 74  rence counting t
06d0: 65 6c 6c 73 20 75 73 20 77 68 65 6e 20 61 20 76  ells us when a v
06e0: 61 6c 75 65 20 63 61 6e 20 62 65 20 66 72 65 65  alue can be free
06f0: 64 2e 20 53 63 6f 70 65 20 6f 77 6e 65 72 73 68  d. Scope ownersh
0700: 69 70 20 74 65 6c 6c 73 20 75 73 20 77 68 6f 20  ip tells us who 
0710: 69 73 20 72 65 73 70 6f 6e 73 69 62 6c 65 20 66  is responsible f
0720: 6f 72 20 65 76 65 6e 74 75 61 6c 6c 79 20 74 72  or eventually tr
0730: 69 67 67 65 72 69 6e 67 20 74 68 65 20 64 65 73  iggering the des
0740: 74 72 75 63 74 69 6f 6e 20 69 66 20 61 20 63 6c  truction if a cl
0750: 69 65 6e 74 20 64 6f 65 73 20 6e 6f 74 20 64 6f  ient does not do
0760: 20 69 74 20 6f 6e 20 68 69 73 20 6f 77 6e 2e 20   it on his own. 
0770: 28 57 65 72 65 20 69 74 20 6e 6f 74 20 66 6f 72  (Were it not for
0780: 20 63 79 63 6c 65 73 2c 20 74 68 69 73 20 77 6f   cycles, this wo
0790: 75 6c 64 20 62 65 20 61 20 6c 6f 74 20 73 69 6d  uld be a lot sim
07a0: 70 6c 65 72 2c 20 62 79 20 74 68 65 20 77 61 79  pler, by the way
07b0: 2e 29 20 41 73 20 61 20 76 61 6c 75 65 20 22 69  .) As a value "i
07c0: 73 20 72 65 66 65 72 65 6e 63 65 64 20 62 79 22  s referenced by"
07d0: 20 61 20 68 69 67 68 65 72 2d 6c 65 76 65 6c 20   a higher-level 
07e0: 28 6f 6c 64 65 72 29 20 73 63 6f 70 65 2c 20 69  (older) scope, i
07f0: 74 73 20 6f 77 6e 65 72 73 68 69 70 20 6d 69 67  ts ownership mig
0800: 72 61 74 65 73 20 74 6f 20 74 68 61 74 20 73 63  rates to that sc
0810: 6f 70 65 2c 20 73 75 63 68 20 74 68 61 74 20 6f  ope, such that o
0820: 6e 6c 79 20 6f 6e 65 20 73 63 6f 70 65 20 77 69  nly one scope wi
0830: 6c 6c 20 65 76 65 72 20 74 61 6b 65 20 72 65 73  ll ever take res
0840: 70 6f 6e 73 69 62 69 6c 69 74 79 20 66 6f 72 20  ponsibility for 
0850: 63 6c 65 61 6e 69 6e 67 20 75 70 20 61 20 76 61  cleaning up a va
0860: 6c 75 65 2e 20 54 68 65 20 72 75 6c 65 73 20 67  lue. The rules g
0870: 75 61 72 61 6e 74 79 20 28 69 6e 73 6f 66 61 72  uaranty (insofar
0880: 20 61 73 20 74 68 65 20 63 6f 64 65 20 69 73 20   as the code is 
0890: 62 75 67 2d 66 72 65 65 21 29 20 74 68 61 74 20  bug-free!) that 
08a0: 76 61 6c 75 65 73 20 69 6e 20 61 20 73 63 6f 70  values in a scop
08b0: 65 20 63 61 6e 6e 6f 74 20 72 65 66 65 72 65 6e  e cannot referen
08c0: 63 65 20 76 61 6c 75 65 73 20 69 6e 20 6c 6f 77  ce values in low
08d0: 65 72 2d 6c 65 76 65 6c 20 28 6e 65 77 65 72 29  er-level (newer)
08e0: 20 73 63 6f 70 65 73 20 62 65 63 61 75 73 65 20   scopes because 
08f0: 72 65 66 65 72 65 6e 63 69 6e 67 20 73 75 63 68  referencing such
0900: 20 76 61 6c 75 65 73 20 6d 69 67 72 61 74 65 73   values migrates
0910: 20 74 68 65 6d 20 69 6e 20 74 6f 20 74 68 65 20   them in to the 
0920: 6f 6c 64 65 72 20 73 63 6f 70 65 2c 20 61 6e 64  older scope, and
0930: 20 74 68 65 72 65 66 6f 72 65 20 63 61 6e 20 62   therefore can b
0940: 65 20 63 6c 65 61 6e 65 64 20 75 70 20 77 69 74  e cleaned up wit
0950: 68 6f 75 74 20 72 69 73 6b 20 6f 66 20 73 74 6f  hout risk of sto
0960: 6d 70 69 6e 67 20 6f 6e 20 63 79 63 6c 65 73 20  mping on cycles 
0970: 63 72 65 61 74 65 64 20 76 69 61 20 6f 74 68 65  created via othe
0980: 72 20 73 63 6f 70 65 73 20 28 69 2e 65 2e 20 74  r scopes (i.e. t
0990: 68 65 20 63 6c 65 61 6e 75 70 2d 72 6f 6f 74 73  he cleanup-roots
09a0: 29 2e 20 49 74 20 69 73 20 6e 6f 74 20 70 6f 73  ). It is not pos
09b0: 73 69 62 6c 65 20 74 6f 20 68 61 76 65 20 61 20  sible to have a 
09c0: 63 79 63 6c 65 20 77 68 69 63 68 20 72 65 61 63  cycle which reac
09d0: 68 65 73 20 69 6e 74 6f 20 61 20 6c 6f 77 65 72  hes into a lower
09e0: 20 28 6e 65 77 65 72 29 20 73 63 6f 70 65 20 62   (newer) scope b
09f0: 65 63 61 75 73 65 20 73 75 63 68 20 61 20 72 65  ecause such a re
0a00: 66 65 72 65 6e 63 65 20 77 6f 75 6c 64 20 63 61  ference would ca
0a10: 75 73 65 20 74 68 65 20 6c 6f 77 65 72 2d 73 63  use the lower-sc
0a20: 6f 70 65 64 20 28 6e 65 77 65 72 29 20 76 61 6c  oped (newer) val
0a30: 75 65 20 74 6f 20 62 65 20 6d 69 67 72 61 74 65  ue to be migrate
0a40: 64 20 74 6f 20 74 68 65 20 68 69 67 68 65 72 20  d to the higher 
0a50: 28 6f 6c 64 65 72 29 20 73 63 6f 70 65 20 28 3c  (older) scope (<
0a60: 65 6d 3e 6f 6e 6c 79 3c 2f 65 6d 3e 20 66 6f 72  em>only</em> for
0a70: 20 6d 65 6d 6f 72 79 20 6d 61 6e 61 67 65 6d 65   memory manageme
0a80: 6e 74 20 70 75 72 70 6f 73 65 73 2c 20 6e 6f 74  nt purposes, not
0a90: 20 63 6c 69 65 6e 74 2d 73 69 64 65 2d 76 69 73   client-side-vis
0aa0: 69 62 69 6c 69 74 79 20 70 75 72 70 6f 73 65 73  ibility purposes
0ab0: 21 29 2e 0d 0a 0d 0a 44 65 73 74 72 75 63 74 69  !).....Destructi
0ac0: 6f 6e 20 6f 66 20 61 20 76 61 6c 75 65 20 69 73  on of a value is
0ad0: 20 72 65 61 6c 6c 79 20 61 20 74 68 72 65 65 2d   really a three-
0ae0: 73 74 65 70 20 70 72 6f 63 65 73 73 3a 20 74 68  step process: th
0af0: 65 20 66 69 72 73 74 20 69 73 20 22 75 6e 72 65  e first is "unre
0b00: 66 65 72 65 6e 63 69 6e 67 22 20 74 68 65 20 6f  ferencing" the o
0b10: 62 6a 65 63 74 20 2d 20 72 65 64 75 63 69 6e 67  bject - reducing
0b20: 20 69 74 73 20 72 65 66 65 72 65 6e 63 65 20 63   its reference c
0b30: 6f 75 6e 74 20 76 69 61 20 3c 74 74 3e 63 77 61  ount via <tt>cwa
0b40: 6c 5f 76 61 6c 75 65 5f 75 6e 72 65 66 28 29 3c  l_value_unref()<
0b50: 2f 74 74 3e 2e 20 41 73 20 6c 6f 6e 67 20 61 73  /tt>. As long as
0b60: 20 74 68 65 20 61 64 6a 75 73 74 65 64 20 72 65   the adjusted re
0b70: 66 63 6f 75 6e 74 20 69 73 20 61 62 6f 76 65 20  fcount is above 
0b80: 7a 65 72 6f 2c 20 75 6e 72 65 66 27 69 6e 67 20  zero, unref'ing 
0b90: 64 6f 65 73 20 6e 6f 74 68 69 6e 67 2e 20 4f 6e  does nothing. On
0ba0: 63 65 20 69 74 20 72 65 61 63 68 65 73 20 7a 65  ce it reaches ze
0bb0: 72 6f 2c 20 61 20 76 61 6c 75 65 2d 74 79 70 65  ro, a value-type
0bc0: 2d 73 70 65 63 69 66 69 63 20 63 6c 65 61 6e 75  -specific cleanu
0bd0: 70 20 66 75 6e 63 74 69 6f 6e 20 28 70 61 72 74  p function (part
0be0: 20 6f 66 20 56 61 6c 75 65 27 73 20 76 69 72 74   of Value's virt
0bf0: 75 61 6c 20 69 6e 74 65 72 66 61 63 65 29 20 69  ual interface) i
0c00: 73 20 63 61 6c 6c 65 64 20 74 6f 20 66 72 65 65  s called to free
0c10: 20 61 6e 79 20 72 65 73 6f 75 72 63 65 73 20 6f   any resources o
0c20: 77 6e 65 64 20 62 79 20 74 68 61 74 20 76 61 6c  wned by that val
0c30: 75 65 2c 20 62 75 74 20 6e 6f 74 20 66 72 65 65  ue, but not free
0c40: 20 74 68 65 20 56 61 6c 75 65 20 6d 65 6d 6f 72   the Value memor
0c50: 79 2e 20 41 66 74 65 72 20 28 74 79 70 65 2d 73  y. After (type-s
0c60: 70 65 63 69 66 69 63 29 20 63 6c 65 61 6e 75 70  pecific) cleanup
0c70: 2c 20 74 68 65 20 76 61 6c 75 65 27 73 20 6d 65  , the value's me
0c80: 6d 6f 72 79 20 69 73 20 73 65 6e 74 20 74 6f 20  mory is sent to 
0c90: 74 68 65 20 72 65 63 79 63 6c 69 6e 67 20 73 75  the recycling su
0ca0: 62 73 79 73 74 65 6d 2e 20 54 68 69 73 20 6d 65  bsystem. This me
0cb0: 6d 6f 72 79 20 69 73 20 73 74 69 6c 6c 20 22 73  mory is still "s
0cc0: 74 61 6d 70 65 64 22 20 77 69 74 68 20 65 6e 6f  tamped" with eno
0cd0: 75 67 68 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  ugh information 
0ce0: 74 6f 20 61 6c 6c 6f 77 20 75 73 20 74 6f 20 72  to allow us to r
0cf0: 65 2d 75 73 65 20 6d 75 63 68 20 6f 66 20 69 74  e-use much of it
0d00: 20 66 6f 72 20 66 75 74 75 72 65 20 61 6c 6c 6f   for future allo
0d10: 63 61 74 69 6f 6e 73 20 6f 66 20 74 68 65 20 73  cations of the s
0d20: 61 6d 65 20 56 61 6c 75 65 20 74 79 70 65 73 2e  ame Value types.
0d30: 20 28 57 65 20 63 61 6e 6e 6f 74 20 72 65 63 79   (We cannot recy
0d40: 63 6c 65 20 6d 65 6d 6f 72 79 20 61 63 72 6f 73  cle memory acros
0d50: 73 20 64 69 66 66 65 72 65 6e 74 20 56 61 6c 75  s different Valu
0d60: 65 20 74 79 70 65 73 20 62 65 63 61 75 73 65 20  e types because 
0d70: 6f 66 20 72 65 73 74 72 69 63 74 69 6f 6e 73 20  of restrictions 
0d80: 69 6d 70 6f 73 65 64 20 62 79 20 6f 74 68 65 72  imposed by other
0d90: 20 6d 61 6c 6c 6f 63 2d 72 65 64 75 63 74 69 6f   malloc-reductio
0da0: 6e 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 73 2e  n optimizations.
0db0: 29 20 54 68 65 72 65 20 61 72 65 20 63 61 73 65  ) There are case
0dc0: 73 20 77 68 65 72 65 20 72 65 61 63 68 69 6e 67  s where reaching
0dd0: 20 61 20 7a 65 72 6f 20 72 65 66 63 6f 75 6e 74   a zero refcount
0de0: 20 63 61 75 73 65 73 20 61 20 76 61 6c 75 65 20   causes a value 
0df0: 74 6f 20 72 65 2d 65 6e 74 65 72 20 74 68 65 20  to re-enter the 
0e00: 22 74 65 6d 70 6f 72 61 72 79 22 20 73 74 61 74  "temporary" stat
0e10: 65 20 69 6e 20 61 20 68 69 67 68 65 72 20 73 63  e in a higher sc
0e20: 6f 70 65 2c 20 72 61 74 68 65 72 20 74 68 61 6e  ope, rather than
0e30: 20 62 65 69 6e 67 20 64 65 73 74 72 6f 79 65 64   being destroyed
0e40: 2c 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 61 76  , in order to av
0e50: 6f 69 64 20 68 61 76 69 6e 67 20 74 6f 20 22 6c  oid having to "l
0e60: 65 61 6b 22 20 61 20 72 65 66 65 72 65 6e 63 65  eak" a reference
0e70: 20 69 6e 20 73 6f 6d 65 20 63 61 73 65 73 20 69   in some cases i
0e80: 6e 76 6f 6c 76 69 6e 67 20 76 61 6c 75 65 20 70  nvolving value p
0e90: 72 6f 70 61 67 61 74 69 6f 6e 2e 0d 0a 0d 0a 63  ropagation.....c
0ea0: 77 61 6c 20 75 73 65 73 20 61 20 73 69 6d 70 6c  wal uses a simpl
0eb0: 65 20 72 65 63 79 63 6c 69 6e 67 20 6d 65 63 68  e recycling mech
0ec0: 61 6e 69 73 6d 20 74 6f 20 6b 65 65 70 20 73 6f  anism to keep so
0ed0: 6d 65 20 63 6f 6e 66 69 67 75 72 61 62 6c 65 20  me configurable 
0ee0: 6e 75 6d 62 65 72 20 6f 66 20 76 61 6c 75 65 20  number of value 
0ef0: 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 28 63 6f 6e  allocations (con
0f00: 66 69 67 75 72 65 64 20 6f 6e 20 61 20 70 65 72  figured on a per
0f10: 2d 56 61 6c 75 65 2d 74 79 70 65 20 62 61 73 69  -Value-type basi
0f20: 73 29 20 69 6e 20 6d 65 6d 6f 72 79 20 69 6e 73  s) in memory ins
0f30: 74 65 61 64 20 6f 66 20 66 72 65 65 69 6e 67 20  tead of freeing 
0f40: 74 68 65 6d 20 69 6d 6d 65 64 69 61 74 65 6c 79  them immediately
0f50: 20 77 68 65 6e 20 74 68 65 69 72 20 74 69 6d 65   when their time
0f60: 20 68 61 73 20 63 6f 6d 65 2e 20 57 68 65 6e 20   has come. When 
0f70: 63 72 65 61 74 69 6e 67 20 6e 65 77 20 76 61 6c  creating new val
0f80: 75 65 73 20 6f 66 20 74 68 65 20 73 61 6d 65 20  ues of the same 
0f90: 74 79 70 65 2c 20 74 68 65 20 72 65 63 79 63 6c  type, the recycl
0fa0: 65 20 62 69 6e 20 69 73 20 63 68 65 63 6b 65 64  e bin is checked
0fb0: 2c 20 61 6e 64 20 69 66 20 61 6e 20 65 6e 74 72  , and if an entr
0fc0: 79 20 65 78 69 73 74 73 20 69 74 20 69 73 20 72  y exists it is r
0fd0: 65 63 79 63 6c 65 64 2e 20 54 68 69 73 20 6d 65  ecycled. This me
0fe0: 61 6e 73 20 74 68 61 74 20 61 20 6c 6f 6f 70 20  ans that a loop 
0ff0: 77 68 69 63 68 20 73 69 6d 70 6c 79 20 61 6c 6c  which simply all
1000: 6f 63 61 74 65 73 20 61 6e 64 20 64 65 61 6c 6c  ocates and deall
1010: 6f 63 61 74 65 73 20 61 20 76 61 6c 75 65 20 6d  ocates a value m
1020: 69 67 68 74 20 61 63 74 75 61 6c 6c 79 20 6f 6e  ight actually on
1030: 6c 79 20 61 6c 6c 6f 63 61 74 65 20 6f 6e 63 65  ly allocate once
1040: 2e 20 53 6f 6d 65 20 74 79 70 65 73 20 28 6e 61  . Some types (na
1050: 6d 65 6c 79 20 73 74 72 69 6e 67 73 29 20 61 72  mely strings) ar
1060: 65 20 6e 6f 74 20 22 61 73 20 72 65 63 79 63 6c  e not "as recycl
1070: 61 62 6c 65 22 20 62 65 63 61 75 73 65 20 77 65  able" because we
1080: 20 63 61 6e 20 6f 6e 6c 79 20 72 65 63 79 63 6c   can only recycl
1090: 65 20 73 74 72 69 6e 67 73 20 66 6f 72 20 6e 65  e strings for ne
10a0: 77 20 73 74 72 69 6e 67 73 20 6f 66 20 28 72 6f  w strings of (ro
10b0: 75 67 68 6c 79 29 20 74 68 65 20 73 61 6d 65 20  ughly) the same 
10c0: 73 69 7a 65 2c 20 62 75 74 20 61 75 74 6f 2d 69  size, but auto-i
10d0: 6e 74 65 72 6e 69 6e 67 20 6f 66 20 73 74 72 69  nterning of stri
10e0: 6e 67 73 20 6d 61 6b 65 73 20 6f 66 74 65 6e 2d  ngs makes often-
10f0: 75 73 65 64 20 73 74 72 69 6e 67 73 20 76 65 72  used strings ver
1100: 79 20 63 68 65 61 70 2e 20 52 65 63 79 63 6c 69  y cheap. Recycli
1110: 6e 67 20 64 6f 65 73 20 6e 6f 74 20 72 65 71 75  ng does not requ
1120: 69 72 65 20 61 6e 79 20 61 64 64 69 74 69 6f 6e  ire any addition
1130: 61 6c 20 6d 65 6d 6f 72 79 2c 20 69 74 20 6f 6e  al memory, it on
1140: 6c 79 20 64 65 6c 61 79 73 20 74 68 65 20 66 72  ly delays the fr
1150: 65 65 69 6e 67 20 6f 66 20 61 6c 72 65 61 64 79  eeing of already
1160: 2d 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72  -allocated memor
1170: 79 20 66 6f 72 20 70 6f 74 65 6e 74 69 61 6c 20  y for potential 
1180: 72 65 2d 75 73 65 2e 20 42 65 63 61 75 73 65 20  re-use. Because 
1190: 56 61 6c 75 65 73 20 63 61 6e 20 66 6f 72 6d 20  Values can form 
11a0: 61 20 73 69 6e 67 6c 79 2d 6c 69 6e 6b 65 64 20  a singly-linked 
11b0: 6c 69 73 74 2c 20 74 68 65 20 72 65 63 79 63 6c  list, the recycl
11c0: 65 72 20 63 61 6e 20 75 73 65 20 74 68 61 74 20  er can use that 
11d0: 74 6f 20 6b 65 65 70 20 74 72 61 63 6b 20 6f 66  to keep track of
11e0: 20 72 65 63 79 63 6c 65 64 20 76 61 6c 75 65 73   recycled values
11f0: 20 77 69 74 68 6f 75 74 20 72 65 71 75 69 72 69   without requiri
1200: 6e 67 20 61 6e 79 20 65 78 74 72 61 20 73 69 67  ng any extra sig
1210: 6e 69 66 69 63 61 6e 74 20 69 6e 66 72 61 73 74  nificant infrast
1220: 72 75 63 74 75 72 65 20 74 6f 20 64 6f 20 73 6f  ructure to do so
1230: 2e 20 54 68 65 20 28 73 6d 61 6c 6c 29 20 74 72  . The (small) tr
1240: 61 63 6b 69 6e 67 20 62 69 74 73 20 68 61 76 65  acking bits have
1250: 20 61 20 73 74 61 74 69 63 20 73 69 7a 65 20 61   a static size a
1260: 6e 64 20 61 72 65 20 61 6c 6c 6f 63 61 74 65 64  nd are allocated
1270: 20 61 73 20 70 61 72 74 20 6f 66 20 74 68 65 20   as part of the 
1280: 63 6f 72 65 20 65 6e 67 69 6e 65 20 73 74 72 75  core engine stru
1290: 63 74 75 72 65 2c 20 61 6e 64 20 74 68 65 20 6c  cture, and the l
12a0: 69 6e 6b 65 64 20 6c 69 73 74 20 63 61 70 61 62  inked list capab
12b0: 69 6c 69 74 69 65 73 20 6f 66 20 74 68 65 20 62  ilities of the b
12c0: 61 73 65 20 56 61 6c 75 65 20 74 79 70 65 20 20  ase Value type  
12d0: 70 72 6f 76 69 64 65 73 20 74 68 65 20 72 65 73  provides the res
12e0: 74 2e 0d 0a 0d 0a 57 68 65 6e 20 63 79 63 6c 65  t.....When cycle
12f0: 73 20 63 6f 6d 65 20 69 6e 20 74 6f 20 70 6c 61  s come in to pla
1300: 79 2c 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c  y, it is possibl
1310: 65 20 74 68 61 74 20 61 20 22 64 65 61 64 20 72  e that a "dead r
1320: 65 66 65 72 65 6e 63 65 22 20 77 69 6c 6c 20 62  eference" will b
1330: 65 20 74 72 61 76 65 72 73 65 64 20 64 75 72 69  e traversed duri
1340: 6e 67 20 63 6c 65 61 6e 75 70 20 6f 66 20 74 68  ng cleanup of th
1350: 6f 73 65 20 63 79 63 6c 65 73 2e 20 63 77 61 6c  ose cycles. cwal
1360: 20 6d 61 6e 61 67 65 73 20 74 68 69 73 20 28 70   manages this (p
1370: 61 72 74 69 61 6c 6c 79 29 20 62 79 20 75 73 69  artially) by usi
1380: 6e 67 20 61 20 22 64 65 66 65 72 72 65 64 20 67  ng a "deferred g
1390: 63 20 71 75 65 75 65 2e 22 20 41 6c 6c 20 63 6f  c queue." All co
13a0: 6e 74 61 69 6e 65 72 20 76 61 6c 75 65 73 20 77  ntainer values w
13b0: 68 69 63 68 20 61 72 65 20 73 65 6e 74 20 74 6f  hich are sent to
13c0: 20 74 68 65 20 72 65 63 79 63 6c 69 6e 67 20 62   the recycling b
13d0: 69 6e 20 28 61 73 20 61 20 73 69 64 65 2d 65 66  in (as a side-ef
13e0: 66 65 63 74 20 6f 66 20 75 6e 72 65 66 27 69 6e  fect of unref'in
13f0: 67 29 20 64 75 72 69 6e 67 20 64 65 73 74 72 75  g) during destru
1400: 63 74 69 6f 6e 20 6f 66 20 61 20 73 63 6f 70 65  ction of a scope
1410: 20 61 72 65 20 74 65 6d 70 6f 72 61 72 69 6c 79   are temporarily
1420: 20 64 69 72 65 63 74 65 64 20 74 6f 20 74 68 65   directed to the
1430: 20 67 63 2d 71 75 65 75 65 2c 20 77 68 69 63 68   gc-queue, which
1440: 20 72 65 71 75 69 72 65 73 20 6e 6f 20 6d 65 6d   requires no mem
1450: 6f 72 79 20 61 6e 64 20 4f 28 31 29 20 74 69 6d  ory and O(1) tim
1460: 65 20 28 6a 75 73 74 20 72 65 2d 6c 69 6e 6b 69  e (just re-linki
1470: 6e 67 20 6f 66 20 6f 6e 65 20 6c 69 6e 6b 65 64  ng of one linked
1480: 20 6c 69 73 74 20 65 6e 74 72 79 29 2e 20 54 68   list entry). Th
1490: 65 20 63 6c 65 61 6e 75 70 20 70 72 6f 63 65 73  e cleanup proces
14a0: 73 20 72 65 63 6f 67 6e 69 7a 65 73 20 69 66 20  s recognizes if 
14b0: 69 74 20 69 73 20 73 74 65 70 70 69 6e 67 20 6f  it is stepping o
14c0: 6e 20 61 20 64 65 61 64 20 72 65 66 65 72 65 6e  n a dead referen
14d0: 63 65 20 61 6e 64 20 73 6b 69 70 73 20 74 68 65  ce and skips the
14e0: 20 65 6e 74 72 79 20 28 61 6e 64 20 65 6d 69 74   entry (and emit
14f0: 73 20 61 20 74 72 61 63 69 6e 67 20 6d 65 73 73  s a tracing mess
1500: 61 67 65 20 69 66 20 74 68 6f 73 65 20 61 72 65  age if those are
1510: 20 61 63 74 69 76 61 74 65 64 29 2e 20 57 68 65   activated). Whe
1520: 6e 20 74 68 65 20 73 63 6f 70 65 20 68 61 73 20  n the scope has 
1530: 66 69 6e 69 73 68 65 64 20 63 6c 65 61 6e 69 6e  finished cleanin
1540: 67 20 75 70 20 69 74 20 22 66 6c 75 73 68 65 73  g up it "flushes
1550: 22 20 74 68 65 20 67 63 20 71 75 65 75 65 2c 20  " the gc queue, 
1560: 77 68 69 63 68 20 63 61 75 73 65 73 20 74 68 6f  which causes tho
1570: 73 65 20 65 6e 74 72 69 65 73 20 74 6f 20 65 69  se entries to ei
1580: 74 68 65 72 20 67 6f 20 69 6e 74 6f 20 74 68 65  ther go into the
1590: 20 72 65 63 79 63 6c 69 6e 67 20 62 69 6e 20 6f   recycling bin o
15a0: 72 20 28 69 66 20 69 74 20 69 73 20 66 75 6c 6c  r (if it is full
15b0: 20 6f 72 20 64 69 73 61 62 6c 65 64 29 20 74 6f   or disabled) to
15c0: 20 62 65 20 66 72 65 65 64 2e 0d 0a 0d 0a 41 20   be freed.....A 
15d0: 66 69 6e 61 6c 20 6c 65 76 65 6c 20 6f 66 20 6d  final level of m
15e0: 65 6d 6f 72 79 20 6d 61 6e 61 67 65 6d 65 6e 74  emory management
15f0: 20 69 73 20 74 68 65 20 22 69 6e 74 65 72 6e 69   is the "interni
1600: 6e 67 22 20 6f 66 20 73 74 72 69 6e 67 73 3a 20  ng" of strings: 
1610: 63 77 61 6c 20 63 61 6e 20 6f 70 74 69 6f 6e 61  cwal can optiona
1620: 6c 6c 79 20 22 69 6e 74 65 72 6e 61 6c 69 7a 65  lly "internalize
1630: 22 20 73 74 72 69 6e 67 73 20 61 75 74 6f 6d 61  " strings automa
1640: 74 69 63 61 6c 6c 79 2c 20 73 75 63 68 20 74 68  tically, such th
1650: 61 74 20 69 66 20 74 77 6f 20 73 74 72 69 6e 67  at if two string
1660: 73 20 77 69 74 68 20 74 68 65 20 73 61 6d 65 20  s with the same 
1670: 62 79 74 65 73 20 61 72 65 20 63 72 65 61 74 65  bytes are create
1680: 64 2c 20 74 68 65 79 20 77 69 6c 6c 20 73 68 61  d, they will sha
1690: 72 65 20 74 68 65 20 73 61 6d 65 20 75 6e 64 65  re the same unde
16a0: 72 6c 79 69 6e 67 20 56 61 6c 75 65 20 68 61 6e  rlying Value han
16b0: 64 6c 65 2c 20 72 65 71 75 69 72 69 6e 67 20 6e  dle, requiring n
16c0: 6f 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 6f 72  o allocation for
16d0: 20 74 68 65 20 32 6e 64 20 61 6e 64 20 73 75 62   the 2nd and sub
16e0: 73 65 71 75 65 6e 74 20 69 6e 73 74 61 6e 63 65  sequent instance
16f0: 73 2e 20 54 68 69 73 20 66 65 61 74 75 72 65 20  s. This feature 
1700: 69 73 20 71 75 69 74 65 20 66 61 73 74 20 28 61  is quite fast (a
1710: 6d 6f 72 74 69 7a 65 64 20 4f 28 31 29 29 20 62  mortized O(1)) b
1720: 75 74 20 75 73 65 73 20 22 73 69 67 6e 69 66 69  ut uses "signifi
1730: 63 61 6e 74 22 20 6d 65 6d 6f 72 79 3a 20 32 6b  cant" memory: 2k
1740: 62 2d 34 6b 62 20 28 64 65 70 65 6e 64 69 6e 67  b-4kb (depending
1750: 20 6f 6e 20 68 6f 77 20 69 27 76 65 20 63 6f 6e   on how i've con
1760: 66 69 67 75 72 65 64 20 69 74 21 29 20 66 6f 72  figured it!) for
1770: 20 65 61 63 68 20 70 61 67 65 20 6f 66 20 69 74   each page of it
1780: 73 20 69 6e 74 65 72 6e 69 6e 67 20 74 61 62 6c  s interning tabl
1790: 65 2c 20 61 6e 64 20 74 68 65 20 6e 75 6d 62 65  e, and the numbe
17a0: 72 20 6f 66 20 70 61 67 65 73 20 65 71 75 61 6c  r of pages equal
17b0: 73 20 74 68 65 20 68 69 67 68 65 73 74 20 6e 75  s the highest nu
17c0: 6d 62 65 72 20 6f 66 20 63 6f 6c 6c 69 73 69 6f  mber of collisio
17d0: 6e 73 20 6f 66 20 61 6e 79 20 73 69 6e 67 6c 65  ns of any single
17e0: 20 68 61 73 68 20 76 61 6c 75 65 20 61 6d 6f 6e   hash value amon
17f0: 67 73 74 20 61 6c 6c 20 75 6e 69 71 75 65 20 73  gst all unique s
1800: 74 72 69 6e 67 73 2e 20 46 6f 72 20 73 6d 61 6c  trings. For smal
1810: 6c 20 75 73 65 73 20 61 20 73 69 6e 67 6c 65 20  l uses a single 
1820: 70 61 67 65 20 6e 6f 72 6d 61 6c 6c 79 20 73 75  page normally su
1830: 66 66 69 63 65 73 2c 20 35 30 30 20 75 6e 69 71  ffices, 500 uniq
1840: 75 65 20 73 74 72 69 6e 67 73 20 63 61 6e 20 63  ue strings can c
1850: 61 75 73 65 20 69 74 20 74 6f 20 63 72 65 61 74  ause it to creat
1860: 65 20 36 2d 39 20 70 61 67 65 73 2c 20 62 75 74  e 6-9 pages, but
1870: 20 74 68 61 74 27 73 20 36 2d 39 20 6d 61 6c 6c   that's 6-9 mall
1880: 6f 63 73 20 76 73 2e 20 35 30 30 20 28 61 73 73  ocs vs. 500 (ass
1890: 75 6d 69 6e 67 20 74 68 6f 73 65 20 73 74 72 69  uming those stri
18a0: 6e 67 73 20 61 72 65 20 72 65 2d 75 73 65 64 20  ngs are re-used 
18b0: 2d 20 69 66 20 6e 6f 74 2c 20 69 6e 74 65 72 6e  - if not, intern
18c0: 69 6e 67 20 69 73 20 61 20 77 61 73 74 65 20 6f  ing is a waste o
18d0: 66 20 6d 65 6d 6f 72 79 29 2e 20 49 6e 74 65 72  f memory). Inter
18e0: 6e 69 6e 67 20 75 73 65 73 20 61 20 73 70 65 63  ning uses a spec
18f0: 69 61 6c 2d 70 75 72 70 6f 73 65 73 20 68 61 73  ial-purposes has
1900: 68 74 61 62 6c 65 2d 6c 69 6b 65 20 73 74 72 75  htable-like stru
1910: 63 74 75 72 65 20 77 68 69 63 68 20 61 6c 6c 6f  cture which allo
1920: 63 61 74 65 73 20 77 68 6f 6c 65 20 74 61 62 6c  cates whole tabl
1930: 65 73 20 69 6e 73 74 65 61 64 20 6f 66 20 69 6e  es instead of in
1940: 64 69 76 69 64 75 61 6c 20 65 6e 74 72 79 20 6f  dividual entry o
1950: 62 6a 65 63 74 73 20 61 6e 64 20 6f 6e 6c 79 20  bjects and only 
1960: 68 6f 6c 64 73 20 76 61 6c 75 65 73 20 28 6e 6f  holds values (no
1970: 74 20 6b 65 79 73 29 2e 20 54 68 69 73 20 63 61  t keys). This ca
1980: 75 73 65 73 20 3c 65 6d 3e 66 61 72 3c 2f 65 6d  uses <em>far</em
1990: 3e 20 66 65 77 65 72 20 6d 61 6c 6c 6f 63 73 20  > fewer mallocs 
19a0: 61 6e 64 20 3c 65 6d 3e 63 61 6e 3c 2f 65 6d 3e  and <em>can</em>
19b0: 2c 20 75 6e 64 65 72 20 69 64 65 61 6c 20 63 69  , under ideal ci
19c0: 72 63 75 6d 73 74 61 6e 63 65 73 20 28 62 75 74  rcumstances (but
19d0: 20 6e 6f 72 6d 61 6c 6c 79 20 64 6f 65 73 20 6e   normally does n
19e0: 6f 74 29 2c 20 75 73 65 20 6c 65 73 73 20 6d 65  ot), use less me
19f0: 6d 6f 72 79 20 74 68 61 6e 20 61 6e 20 65 71 75  mory than an equ
1a00: 69 76 61 6c 65 6e 74 20 63 6f 6e 76 65 6e 74 69  ivalent conventi
1a10: 6f 6e 61 6c 20 68 61 73 68 74 61 62 6c 65 20 77  onal hashtable w
1a20: 69 74 68 20 74 68 65 20 73 61 6d 65 20 6c 6f 61  ith the same loa
1a30: 64 2e 20 49 6e 74 65 72 6e 61 6c 69 7a 69 6e 67  d. Internalizing
1a40: 20 6f 66 20 73 74 72 69 6e 67 73 20 69 73 20 6d   of strings is m
1a50: 61 6e 61 67 65 64 20 73 6f 6c 65 6c 79 20 64 75  anaged solely du
1a60: 72 69 6e 67 20 61 6c 6c 6f 63 61 74 69 6f 6e 20  ring allocation 
1a70: 61 6e 64 20 66 69 6e 61 6c 69 7a 61 74 69 6f 6e  and finalization
1a80: 20 6f 66 20 73 74 72 69 6e 67 20 76 61 6c 75 65   of string value
1a90: 73 2c 20 61 6e 64 20 64 6f 65 73 20 6e 6f 74 20  s, and does not 
1aa0: 3c 65 6d 3e 64 69 72 65 63 74 6c 79 3c 2f 65 6d  <em>directly</em
1ab0: 3e 20 63 68 61 6e 67 65 20 68 6f 77 20 6f 74 68  > change how oth
1ac0: 65 72 20 6c 69 62 72 61 72 79 2d 6c 65 76 65 6c  er library-level
1ad0: 20 63 6f 64 65 20 77 6f 72 6b 73 20 28 62 75 74   code works (but
1ae0: 20 64 6f 65 73 20 63 61 75 73 65 20 75 73 20 74   does cause us t
1af0: 6f 20 64 69 73 61 6c 6c 6f 77 20 73 6f 6d 65 20  o disallow some 
1b00: 6d 69 6e 6f 72 20 69 6e 74 65 72 6e 61 6c 20 6f  minor internal o
1b10: 70 74 69 6d 69 7a 61 74 69 6f 6e 73 20 77 65 20  ptimizations we 
1b20: 6d 69 67 68 74 20 6f 74 68 65 72 77 69 73 65 20  might otherwise 
1b30: 62 65 20 61 62 6c 65 20 74 6f 20 6d 61 6b 65 2c  be able to make,
1b40: 20 61 6e 64 20 69 74 73 20 73 69 64 65 2d 65 66   and its side-ef
1b50: 66 65 63 74 73 20 69 6e 66 6c 75 65 6e 63 65 20  fects influence 
1b60: 61 20 73 69 67 6e 69 66 69 63 61 6e 74 20 69 6e  a significant in
1b70: 74 65 72 6e 61 6c 20 64 65 73 69 67 6e 20 64 65  ternal design de
1b80: 63 69 73 69 6f 6e 20 69 6e 20 74 68 65 20 73 63  cision in the sc
1b90: 6f 70 65 20 63 6c 65 61 6e 75 70 20 63 6f 64 65  ope cleanup code
1ba0: 29 2e 20 52 65 67 61 72 64 6c 65 73 73 20 6f 66  ). Regardless of
1bb0: 20 74 68 65 20 6d 65 6d 6f 72 79 20 65 66 66 65   the memory effe
1bc0: 63 74 73 2c 20 73 74 72 69 6e 67 20 69 6e 74 65  cts, string inte
1bd0: 72 6e 69 6e 67 20 63 61 6e 20 76 61 73 74 6c 79  rning can vastly
1be0: 20 73 70 65 65 64 20 75 70 20 63 65 72 74 61 69   speed up certai
1bf0: 6e 20 74 79 70 65 73 20 6f 66 20 73 74 72 69 6e  n types of strin
1c00: 67 20 75 73 61 67 65 20 28 65 2e 67 2e 20 69 64  g usage (e.g. id
1c10: 65 6e 74 69 66 69 65 72 20 6c 6f 6f 6b 75 70 73  entifier lookups
1c20: 20 69 6e 20 73 63 72 69 70 74 73 29 2e 20 49 6e   in scripts). In
1c30: 20 73 6f 6d 65 20 74 65 73 74 73 20 28 6e 6f 74   some tests (not
1c40: 20 73 70 65 63 69 66 69 63 61 6c 6c 79 20 61 69   specifically ai
1c50: 6d 65 64 20 61 74 20 74 68 69 73 20 70 72 6f 62  med at this prob
1c60: 6c 65 6d 29 20 73 63 72 69 70 74 20 63 6f 64 65  lem) script code
1c70: 20 72 75 6e 73 20 74 77 69 63 65 20 61 73 20 66   runs twice as f
1c80: 61 73 74 20 77 69 74 68 20 73 74 72 69 6e 67 2d  ast with string-
1c90: 69 6e 74 65 72 6e 69 6e 67 20 64 75 65 20 74 6f  interning due to
1ca0: 20 68 6f 77 20 74 68 65 20 73 63 72 69 70 74 69   how the scripti
1cb0: 6e 67 20 6c 61 6e 67 75 61 67 65 20 72 65 73 6f  ng language reso
1cc0: 6c 76 65 73 20 28 72 65 6c 61 74 69 76 65 6c 79  lves (relatively
1cd0: 20 69 6e 65 66 66 69 63 69 65 6e 74 6c 79 29 20   inefficiently) 
1ce0: 69 64 65 6e 74 69 66 69 65 72 20 73 74 72 69 6e  identifier strin
1cf0: 67 73 2e 0d 0a 0d 0a 44 6f 65 73 20 74 68 69 73  gs.....Does this
1d00: 20 61 6c 6c 20 72 65 61 6c 6c 79 20 77 6f 72 6b   all really work
1d10: 3f 0d 0a 0d 0a 3c 68 31 3e 54 68 65 20 50 72 6f  ?....<h1>The Pro
1d20: 6f 66 20 69 73 20 69 6e 20 74 68 65 20 50 75 64  of is in the Pud
1d30: 64 69 6e 67 2e 2e 2e 3c 2f 68 31 3e 0d 0a 0d 0a  ding...</h1>....
1d40: 4e 6f 77 20 61 20 73 68 6f 72 74 20 64 65 6d 6f  Now a short demo
1d50: 6e 73 74 72 61 74 69 6f 6e 20 6f 66 20 74 68 65  nstration of the
1d60: 20 61 62 6f 76 65 2d 6d 65 6e 74 69 6f 6e 65 64   above-mentioned
1d70: 20 6d 6f 76 69 6e 67 20 70 61 72 74 73 2c 20 77   moving parts, w
1d80: 6f 72 6b 69 6e 67 20 69 6e 20 75 6e 69 73 6f 6e  orking in unison
1d90: 2e 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  . The following 
1da0: 6f 75 74 70 75 74 20 77 61 73 20 67 65 6e 65 72  output was gener
1db0: 61 74 65 64 20 62 79 20 5b 74 68 31 69 73 68 5d  ated by [th1ish]
1dc0: 2c 20 61 6e 64 20 73 68 6f 77 73 20 63 77 61 6c  , and shows cwal
1dd0: 2d 69 6e 74 65 72 6e 61 6c 20 61 6c 6c 6f 63 61  -internal alloca
1de0: 74 69 6f 6e 20 6d 65 74 72 69 63 73 20 77 68 65  tion metrics whe
1df0: 6e 20 72 75 6e 20 61 63 72 6f 73 73 20 32 33 20  n run across 23 
1e00: 75 6e 69 74 20 74 65 73 74 20 73 63 72 69 70 74  unit test script
1e10: 20 66 69 6c 65 73 2c 20 74 6f 74 61 6c 69 6e 67   files, totaling
1e20: 20 61 62 6f 75 74 20 33 30 30 30 20 6c 69 6e 65   about 3000 line
1e30: 73 20 6f 66 20 63 6f 64 65 2c 20 69 6e 20 61 20  s of code, in a 
1e40: 73 69 6e 67 6c 65 20 69 6e 74 65 72 70 72 65 74  single interpret
1e50: 65 72 20 73 65 73 73 69 6f 6e 2e 20 41 6e 20 65  er session. An e
1e60: 78 70 6c 61 6e 61 74 69 6f 6e 20 6f 66 20 74 68  xplanation of th
1e70: 65 20 6e 75 6d 62 65 72 73 20 66 6f 6c 6c 6f 77  e numbers follow
1e80: 73 3a 0d 0a 0d 0a 3c 62 6c 6f 63 6b 71 75 6f 74  s:....<blockquot
1e90: 65 3e 3c 6e 6f 77 69 6b 69 3e 3c 70 72 65 3e 0d  e><nowiki><pre>.
1ea0: 0a 56 61 6c 75 65 54 79 70 65 49 64 2f 4e 61 6d  .ValueTypeId/Nam
1eb0: 65 20 20 20 20 20 43 72 65 61 74 69 6f 6e 52 65  e     CreationRe
1ec0: 71 75 65 73 74 73 20 20 20 41 63 74 75 61 6c 6c  quests   Actuall
1ed0: 79 20 61 6c 6c 6f 63 61 74 65 64 20 63 6f 75 6e  y allocated coun
1ee0: 74 20 2a 20 56 61 6c 75 65 2d 74 79 70 65 20 73  t * Value-type s
1ef0: 69 7a 65 6f 66 28 29 20 3d 3d 3e 20 74 6f 74 61  izeof() ==> tota
1f00: 6c 20 62 79 74 65 73 20 66 72 6f 6d 20 61 6c 6c  l bytes from all
1f10: 6f 63 61 74 6f 72 0d 0a 0d 0a 33 20 20 69 6e 74  ocator....3  int
1f20: 65 67 65 72 20 20 20 20 20 20 20 20 20 20 20 32  eger           2
1f30: 31 30 34 34 20 20 20 20 20 20 20 20 20 20 20 20  1044            
1f40: 20 20 39 36 20 20 20 20 20 28 30 30 30 2e 34 36    96     (000.46
1f50: 25 29 20 20 2a 20 34 38 20 3d 3d 3e 20 34 36 30  %)  * 48 ==> 460
1f60: 38 20 20 20 20 20 0d 0a 34 20 20 64 6f 75 62 6c  8     ..4  doubl
1f70: 65 20 20 20 20 20 20 20 20 20 20 20 20 31 30 31  e            101
1f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f90: 31 38 20 20 20 20 20 28 30 31 37 2e 38 32 25 29  18     (017.82%)
1fa0: 20 20 2a 20 34 38 20 3d 3d 3e 20 38 36 34 20 20    * 48 ==> 864  
1fb0: 20 20 20 20 0d 0a 35 20 20 73 74 72 69 6e 67 20      ..5  string 
1fc0: 20 20 20 20 20 20 20 20 20 20 20 33 31 36 34 20             3164 
1fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 34 36                46
1fe0: 38 20 20 20 20 28 30 31 34 2e 37 39 25 29 20 20  8    (014.79%)  
1ff0: 2a 20 34 38 20 3d 3d 3e 20 33 32 30 36 34 20 20  * 48 ==> 32064  
2000: 20 20 49 6e 63 6c 2e 20 73 74 72 69 6e 67 20 62    Incl. string b
2010: 79 74 65 73 0d 0a 36 20 20 61 72 72 61 79 20 20  ytes..6  array  
2020: 20 20 20 20 20 20 20 20 20 20 20 36 30 30 20 20             600  
2030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 32 39                29
2040: 20 20 20 20 20 28 30 30 34 2e 38 33 25 29 20 20       (004.83%)  
2050: 2a 20 38 38 20 3d 3d 3e 20 38 30 33 32 20 20 20  * 88 ==> 8032   
2060: 20 20 49 6e 63 6c 2e 20 70 65 61 6b 20 6c 69 73    Incl. peak lis
2070: 74 20 6d 65 6d 6f 72 79 0d 0a 37 20 20 6f 62 6a  t memory..7  obj
2080: 65 63 74 20 20 20 20 20 20 20 20 20 20 20 20 37  ect            7
2090: 33 32 20 20 20 20 20 20 20 20 20 20 20 20 20 20  32              
20a0: 20 20 33 32 20 20 20 20 20 28 30 30 34 2e 33 37    32     (004.37
20b0: 25 29 20 20 2a 20 36 34 20 3d 3d 3e 20 32 30 34  %)  * 64 ==> 204
20c0: 38 20 20 20 20 20 0d 0a 38 20 20 66 75 6e 63 74  8     ..8  funct
20d0: 69 6f 6e 20 20 20 20 20 20 20 20 20 20 32 33 33  ion          233
20e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
20f0: 31 35 38 20 20 20 20 28 30 36 37 2e 38 31 25 29  158    (067.81%)
2100: 20 20 2a 20 39 36 20 3d 3d 3e 20 31 35 31 36 38    * 96 ==> 15168
2110: 20 20 20 20 0d 0a 39 20 20 65 78 63 65 70 74 69      ..9  excepti
2120: 6f 6e 20 20 20 20 20 20 20 20 20 34 39 20 20 20  on         49   
2130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 35 20                5 
2140: 20 20 20 20 20 28 30 31 30 2e 32 30 25 29 20 20       (010.20%)  
2150: 2a 20 37 32 20 3d 3d 3e 20 33 36 30 20 20 20 20  * 72 ==> 360    
2160: 20 20 0d 0a 31 30 20 6e 61 74 69 76 65 20 20 20    ..10 native   
2170: 20 20 20 20 20 20 20 20 20 32 20 20 20 20 20 20           2      
2180: 20 20 20 20 20 20 20 20 20 20 20 20 32 20 20 20              2   
2190: 20 20 20 28 31 30 30 2e 30 30 25 29 20 20 2a 20     (100.00%)  * 
21a0: 39 36 20 3d 3d 3e 20 31 39 32 20 20 20 20 20 20  96 ==> 192      
21b0: 0d 0a 31 31 20 62 75 66 66 65 72 20 20 20 20 20  ..11 buffer     
21c0: 20 20 20 20 20 20 20 31 31 20 20 20 20 20 20 20         11       
21d0: 20 20 20 20 20 20 20 20 20 20 34 20 20 20 20 20            4     
21e0: 20 28 30 33 36 2e 33 36 25 29 20 20 2a 20 36 34   (036.36%)  * 64
21f0: 20 3d 3d 3e 20 31 38 33 33 39 34 20 20 20 5b 31   ==> 183394   [1
2200: 5d 20 49 6e 63 6c 2e 20 70 65 61 6b 20 62 75 66  ] Incl. peak buf
2210: 66 65 72 65 64 20 6d 65 6d 6f 72 79 20 61 6e 64  fered memory and
2220: 20 6e 6f 6e 2d 56 61 6c 75 65 20 62 75 66 66 65   non-Value buffe
2230: 72 73 0d 0a 31 32 20 68 61 73 68 20 20 20 20 20  rs..12 hash     
2240: 20 20 20 20 20 20 20 20 20 34 20 20 20 20 20 20           4      
2250: 20 20 20 20 20 20 20 20 20 20 20 20 34 20 20 20              4   
2260: 20 20 20 28 31 30 30 2e 30 30 25 29 20 20 2a 20     (100.00%)  * 
2270: 38 38 20 3d 3d 3e 20 31 31 33 36 20 20 20 20 20  88 ==> 1136     
2280: 49 6e 63 6c 2e 20 74 61 62 6c 65 20 6d 65 6d 6f  Incl. table memo
2290: 72 79 0d 0a 31 33 20 63 77 61 6c 5f 73 63 6f 70  ry..13 cwal_scop
22a0: 65 20 20 20 20 20 20 20 20 38 39 30 33 20 20 20  e        8903   
22b0: 20 20 20 20 20 20 20 20 20 20 20 20 31 20 20 20              1   
22c0: 20 20 20 28 30 30 30 2e 30 31 25 29 20 20 2a 20     (000.01%)  * 
22d0: 38 30 20 3d 3d 3e 20 38 30 20 20 20 20 20 20 20  80 ==> 80       
22e0: 5b 32 5d 0d 0a 31 34 20 63 77 61 6c 5f 6b 76 70  [2]..14 cwal_kvp
22f0: 20 20 20 20 20 20 20 20 20 20 33 30 33 31 20 20            3031  
2300: 20 20 20 20 20 20 20 20 20 20 20 20 20 33 30 34               304
2310: 20 20 20 20 28 30 31 30 2e 30 33 25 29 20 20 2a      (010.03%)  *
2320: 20 33 32 20 3d 3d 3e 20 39 37 32 38 20 20 20 20   32 ==> 9728    
2330: 20 0d 0a 31 36 20 78 2d 73 74 72 69 6e 67 20 20   ..16 x-string  
2340: 20 20 20 20 20 20 20 20 33 32 20 20 20 20 20 20          32      
2350: 20 20 20 20 20 20 20 20 20 20 20 33 32 20 20 20             32   
2360: 20 20 28 31 30 30 2e 30 30 25 29 20 20 2a 20 35    (100.00%)  * 5
2370: 36 20 3d 3d 3e 20 31 37 39 32 20 20 20 20 20 4e  6 ==> 1792     N
2380: 6f 74 20 69 6e 63 6c 2e 20 65 78 74 65 72 6e 61  ot incl. externa
2390: 6c 20 73 74 72 69 6e 67 20 62 79 74 65 73 0d 0a  l string bytes..
23a0: 31 37 20 7a 2d 73 74 72 69 6e 67 20 20 20 20 20  17 z-string     
23b0: 20 20 20 20 20 34 20 20 20 20 20 20 20 20 20 20       4          
23c0: 20 20 20 20 20 20 20 20 34 20 20 20 20 20 20 28          4      (
23d0: 31 30 30 2e 30 30 25 29 20 20 2a 20 35 36 20 3d  100.00%)  * 56 =
23e0: 3d 3e 20 32 34 32 20 20 20 20 20 20 49 6e 63 6c  => 242      Incl
23f0: 2e 20 73 74 72 69 6e 67 20 62 79 74 65 73 0d 0a  . string bytes..
2400: 0d 0a 54 6f 74 61 6c 73 3a 20 20 20 20 20 20 20  ..Totals:       
2410: 20 20 20 20 20 20 20 32 39 30 30 38 20 20 20 20         29008    
2420: 20 20 20 20 20 20 20 20 20 20 31 31 35 37 20 20            1157  
2430: 20 28 30 30 33 2e 39 39 25 29 5b 31 5d 20 20 20   (003.99%)[1]   
2440: 20 3d 3d 3e 20 32 35 39 37 30 38 20 20 0d 0a 0d   ==> 259708  ...
2450: 0a 5b 31 5d 20 3d 20 25 20 61 70 70 6c 69 65 73  .[1] = % applies
2460: 20 74 6f 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 63   to allocation c
2470: 6f 75 6e 74 73 2c 20 6e 6f 74 20 73 69 7a 65 73  ounts, not sizes
2480: 2e 20 54 68 65 20 74 6f 74 61 6c 20 63 6f 75 6e  . The total coun
2490: 74 20 64 6f 65 73 20 6e 6f 74 20 61 63 63 6f 75  t does not accou
24a0: 6e 74 20 66 6f 72 20 62 75 66 66 65 72 20 6d 65  nt for buffer me
24b0: 6d 6f 72 79 20 28 72 65 29 61 6c 6c 6f 63 61 74  mory (re)allocat
24c0: 69 6f 6e 73 2c 20 62 75 74 20 74 68 65 20 74 6f  ions, but the to
24d0: 74 61 6c 20 73 69 7a 65 20 64 6f 65 73 2e 0d 0a  tal size does...
24e0: 0d 0a 5b 32 5d 20 3d 20 53 63 6f 70 65 73 20 61  ..[2] = Scopes a
24f0: 72 65 20 61 6c 6d 6f 73 74 20 61 6c 77 61 79 73  re almost always
2500: 20 73 74 61 63 6b 20 61 6c 6c 6f 63 61 74 65 64   stack allocated
2510: 20 61 6e 64 20 73 6b 65 77 20 74 68 65 20 73 74   and skew the st
2520: 61 74 69 73 74 69 63 73 2c 20 73 6f 20 6f 6e 6c  atistics, so onl
2530: 79 20 61 6c 6c 6f 63 61 74 65 64 20 73 63 6f 70  y allocated scop
2540: 65 73 20 61 72 65 20 63 6f 75 6e 74 65 64 20 66  es are counted f
2550: 6f 72 20 74 6f 74 61 6c 73 20 70 75 72 70 6f 73  or totals purpos
2560: 65 73 2e 0d 0a 0d 0a 53 74 72 69 6e 67 20 69 6e  es.....String in
2570: 74 65 72 6e 69 6e 67 20 74 61 62 6c 65 73 3a 20  terning tables: 
2580: 20 34 20 70 61 67 65 28 73 29 20 6f 66 20 73 69   4 page(s) of si
2590: 7a 65 20 33 37 39 20 28 33 30 35 36 20 62 79 74  ze 379 (3056 byt
25a0: 65 73 29 20 3d 3d 3e 20 31 32 32 32 34 20 62 79  es) ==> 12224 by
25b0: 74 65 73 0d 0a 0d 0a 47 65 6e 65 72 61 6c 2d 70  tes....General-p
25c0: 75 72 70 6f 73 65 20 62 75 66 66 65 72 20 63 61  urpose buffer ca
25d0: 70 61 63 69 74 79 3a 20 31 35 31 20 62 79 74 65  pacity: 151 byte
25e0: 73 0d 0a 0d 0a 50 72 6f 70 65 72 74 79 2d 73 6f  s....Property-so
25f0: 72 74 69 6e 67 20 62 75 66 66 65 72 20 63 61 70  rting buffer cap
2600: 61 63 69 74 79 3a 20 34 30 20 62 79 74 65 73 0d  acity: 40 bytes.
2610: 0a 0d 0a 63 77 61 6c 5f 65 6e 67 69 6e 65 20 69  ...cwal_engine i
2620: 6e 73 74 61 6e 63 65 20 61 70 70 65 61 72 73 20  nstance appears 
2630: 74 6f 20 68 61 76 65 20 62 65 65 6e 20 73 74 61  to have been sta
2640: 63 6b 2d 61 6c 6c 6f 63 61 74 65 64 20 28 6e 6f  ck-allocated (no
2650: 74 20 62 79 20 63 77 61 6c 5f 65 6e 67 69 6e 65  t by cwal_engine
2660: 5f 69 6e 69 74 28 29 29 2e 0d 0a 0d 0a 54 6f 74  _init()).....Tot
2670: 61 6c 20 62 79 74 65 73 20 61 6c 6c 6f 63 61 74  al bytes allocat
2680: 65 64 20 66 6f 72 20 6d 65 74 72 69 63 73 2d 74  ed for metrics-t
2690: 72 61 63 6b 65 64 20 72 65 73 6f 75 72 63 65 73  racked resources
26a0: 3a 20 32 37 32 31 32 33 0d 0a 0d 0a 3c 2f 70 72  : 272123....</pr
26b0: 65 3e 3c 2f 6e 6f 77 69 6b 69 3e 3c 2f 62 6c 6f  e></nowiki></blo
26c0: 63 6b 71 75 6f 74 65 3e 0d 0a 0d 0a 54 68 65 20  ckquote>....The 
26d0: 66 69 72 73 74 20 74 77 6f 20 63 6f 6c 75 6d 6e  first two column
26e0: 73 20 74 65 6c 6c 73 20 75 73 20 77 68 61 74 20  s tells us what 
26f0: 56 61 6c 75 65 20 74 79 70 65 20 74 68 65 20 6d  Value type the m
2700: 65 74 72 69 63 73 20 61 72 65 20 66 6f 72 2e 20  etrics are for. 
2710: 54 68 65 20 74 68 69 72 64 20 74 65 6c 6c 73 20  The third tells 
2720: 75 73 20 68 6f 77 20 6d 61 6e 79 20 22 72 65 71  us how many "req
2730: 75 65 73 74 73 22 20 77 65 20 6d 61 64 65 20 74  uests" we made t
2740: 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 76 61 6c  o allocate a val
2750: 75 65 20 6f 66 20 74 68 61 74 20 74 79 70 65 2e  ue of that type.
2760: 20 54 68 65 20 66 6f 75 72 74 68 20 74 65 6c 6c   The fourth tell
2770: 73 20 75 73 20 68 6f 77 20 6d 61 6e 79 20 74 69  s us how many ti
2780: 6d 65 73 20 63 77 61 6c 20 61 63 74 75 61 6c 6c  mes cwal actuall
2790: 79 20 68 61 64 20 74 6f 20 63 61 6c 6c 20 69 6e  y had to call in
27a0: 74 6f 20 74 68 65 20 73 79 73 74 65 6d 20 61 6c  to the system al
27b0: 6c 6f 63 61 74 6f 72 20 74 6f 20 73 65 72 76 65  locator to serve
27c0: 20 74 68 61 74 20 72 65 71 75 65 73 74 2e 20 54   that request. T
27d0: 68 65 20 72 65 6d 61 69 6e 69 6e 67 20 63 6f 6c  he remaining col
27e0: 75 6d 6e 73 20 61 72 65 20 73 74 61 74 73 20 62  umns are stats b
27f0: 61 73 65 64 20 6f 6e 20 74 68 6f 73 65 20 76 61  ased on those va
2800: 6c 75 65 73 2e 0d 0a 0d 0a 53 69 64 65 62 61 72  lues.....Sidebar
2810: 3a 20 3c 74 74 3e 63 77 61 6c 5f 6b 76 70 3c 2f  : <tt>cwal_kvp</
2820: 74 74 3e 20 68 6f 6c 64 73 20 6b 65 79 2f 76 61  tt> holds key/va
2830: 6c 75 65 20 70 61 69 72 73 2e 20 45 61 63 68 20  lue pairs. Each 
2840: 6e 61 6d 65 64 20 76 61 6c 75 65 2c 20 69 6e 63  named value, inc
2850: 6c 75 64 69 6e 67 20 73 63 6f 70 65 2d 6c 65 76  luding scope-lev
2860: 65 6c 20 76 61 72 69 61 62 6c 65 73 20 61 6e 64  el variables and
2870: 20 6e 61 6d 65 64 20 66 75 6e 63 74 69 6f 6e 20   named function 
2880: 70 61 72 61 6d 65 74 65 72 73 2c 20 61 72 65 20  parameters, are 
2890: 73 74 6f 72 65 64 20 61 73 20 61 20 70 61 69 72  stored as a pair
28a0: 20 6f 66 20 56 61 6c 75 65 73 20 69 6e 20 6f 6e   of Values in on
28b0: 65 20 6f 66 20 74 68 65 73 65 20 28 74 68 65 79  e of these (they
28c0: 27 72 65 20 63 61 6c 6c 65 64 20 6b 65 79 2f 76  're called key/v
28d0: 61 6c 75 65 20 70 61 69 72 73 2c 20 62 75 74 20  alue pairs, but 
28e0: 74 68 65 20 6b 65 79 20 69 73 20 6f 66 20 74 68  the key is of th
28f0: 65 20 64 61 74 61 20 74 79 70 65 20 56 61 6c 75  e data type Valu
2900: 65 29 2e 0d 0a 0d 0a 54 68 69 73 20 70 61 72 74  e).....This part
2910: 69 63 75 6c 61 72 20 73 65 74 75 70 20 6f 6e 6c  icular setup onl
2920: 79 20 68 61 64 20 74 6f 20 61 6c 6c 6f 63 61 74  y had to allocat
2930: 65 20 6d 65 6d 6f 72 79 20 66 6f 72 20 34 25 20  e memory for 4% 
2940: 6f 66 20 61 6c 6c 20 56 61 6c 75 65 20 63 72 65  of all Value cre
2950: 61 74 69 6f 6e 20 72 65 71 75 65 73 74 73 2e 20  ation requests. 
2960: 54 68 65 20 72 65 73 74 20 77 61 73 20 73 65 72  The rest was ser
2970: 76 65 64 20 65 69 74 68 65 72 20 62 79 20 74 68  ved either by th
2980: 65 20 72 65 63 79 63 6c 69 6e 67 20 73 75 62 73  e recycling subs
2990: 79 73 74 65 6d 20 6f 72 20 28 69 6e 20 74 68 65  ystem or (in the
29a0: 20 63 61 73 65 20 6f 66 20 73 6f 6d 65 20 6f 66   case of some of
29b0: 20 74 68 65 20 73 74 72 69 6e 67 73 29 20 74 68   the strings) th
29c0: 65 20 73 74 72 69 6e 67 20 69 6e 74 65 72 6e 69  e string interni
29d0: 6e 67 20 73 75 62 73 79 73 74 65 6d 2e 20 4e 6f  ng subsystem. No
29e0: 74 20 61 6c 6c 20 73 63 72 69 70 74 73 20 61 63  t all scripts ac
29f0: 68 69 65 76 65 20 61 20 32 35 3a 31 20 72 61 74  hieve a 25:1 rat
2a00: 69 6f 20 6f 66 20 22 73 61 76 69 6e 67 73 22 20  io of "savings" 
2a10: 69 6e 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 2c 20  in allocations, 
2a20: 62 75 74 20 6c 61 72 67 65 72 20 73 63 72 69 70  but larger scrip
2a30: 74 73 2c 20 69 6e 20 70 61 72 74 69 63 75 6c 61  ts, in particula
2a40: 72 20 74 68 6f 73 65 20 77 68 69 63 68 20 72 75  r those which ru
2a50: 6e 73 20 6c 6f 6f 70 73 2c 20 74 65 6e 64 20 74  ns loops, tend t
2a60: 6f 20 68 61 76 65 20 76 65 72 79 20 68 69 67 68  o have very high
2a70: 20 72 61 74 69 6f 73 2e 20 53 68 6f 72 74 2d 6c   ratios. Short-l
2a80: 69 76 65 64 20 73 63 72 69 70 74 73 20 74 65 6e  ived scripts ten
2a90: 64 20 74 6f 20 73 65 72 76 65 20 6d 6f 73 74 20  d to serve most 
2aa0: 72 65 71 75 65 73 74 73 20 66 72 6f 6d 20 74 68  requests from th
2ab0: 65 20 73 79 73 74 65 6d 20 61 6c 6c 6f 63 61 74  e system allocat
2ac0: 6f 72 2e 0d 0a 0d 0a 53 69 64 65 62 61 72 3a 20  or.....Sidebar: 
2ad0: 74 68 65 73 65 20 6e 75 6d 62 65 72 73 20 64 6f  these numbers do
2ae0: 20 6e 6f 74 20 69 6e 63 6c 75 64 65 20 61 6e 79   not include any
2af0: 20 6f 66 20 74 68 65 20 5b 74 68 31 69 73 68 5d   of the [th1ish]
2b00: 2d 61 6c 6c 6f 63 61 74 65 64 20 6d 65 6d 6f 72  -allocated memor
2b10: 79 2e 20 63 77 61 6c 20 6d 61 6e 61 67 65 73 20  y. cwal manages 
2b20: 74 68 65 20 56 61 6c 75 65 73 20 61 6e 64 20 67  the Values and g
2b30: 65 6e 65 72 69 63 20 62 75 66 66 65 72 73 20 61  eneric buffers a
2b40: 6e 64 20 74 68 31 69 73 68 20 6d 61 6e 61 67 65  nd th1ish manage
2b50: 73 20 74 68 65 20 73 63 72 69 70 74 2d 73 70 65  s the script-spe
2b60: 63 69 66 69 63 20 70 61 72 74 73 20 28 6d 75 63  cific parts (muc
2b70: 68 20 6f 66 20 69 74 20 76 69 61 20 63 77 61 6c  h of it via cwal
2b80: 2c 20 73 6f 20 69 74 27 73 20 69 6e 64 69 72 65  , so it's indire
2b90: 63 74 6c 79 20 69 6e 63 6c 75 64 65 64 20 68 65  ctly included he
2ba0: 72 65 29 2e 20 4d 79 20 22 62 65 73 74 20 67 75  re). My "best gu
2bb0: 65 73 73 22 20 69 73 20 74 68 61 74 20 74 68 65  ess" is that the
2bc0: 20 74 68 31 69 73 68 20 70 61 72 74 20 74 61 6b   th1ish part tak
2bd0: 65 73 20 75 70 20 72 6f 75 67 68 6c 79 20 74 68  es up roughly th
2be0: 65 20 73 61 6d 65 20 61 6d 6f 75 6e 74 20 6f 66  e same amount of
2bf0: 20 6d 65 6d 6f 72 79 2c 20 74 68 6f 75 67 68 20   memory, though 
2c00: 69 74 20 63 75 72 72 65 6e 74 6c 79 20 68 61 73  it currently has
2c10: 20 6e 6f 20 6d 65 74 72 69 63 73 2d 63 6f 6c 6c   no metrics-coll
2c20: 65 63 74 69 6f 6e 20 6d 65 63 68 61 6e 69 73 6d  ection mechanism
2c30: 20 6c 69 6b 65 20 74 68 65 20 63 77 61 6c 20 63   like the cwal c
2c40: 6f 72 65 20 64 6f 65 73 2e 0d 0a 0d 0a 46 6f 72  ore does.....For
2c50: 20 63 6f 6d 70 61 72 69 73 6f 6e 2c 20 64 69 73   comparison, dis
2c60: 61 62 6c 69 6e 67 20 72 65 63 79 63 6c 69 6e 67  abling recycling
2c70: 20 61 6e 64 20 73 74 72 69 6e 67 20 69 6e 74 65   and string inte
2c80: 72 6e 69 6e 67 20 6c 65 61 64 73 20 74 6f 20 3c  rning leads to <
2c90: 65 6d 3e 6d 75 63 68 20 64 69 66 66 65 72 65 6e  em>much differen
2ca0: 74 3c 2f 65 6d 3e 20 6d 65 74 72 69 63 73 3a 0d  t</em> metrics:.
2cb0: 0a 0d 0a 3c 62 6c 6f 63 6b 71 75 6f 74 65 3e 3c  ...<blockquote><
2cc0: 6e 6f 77 69 6b 69 3e 3c 70 72 65 3e 0d 0a 56 61  nowiki><pre>..Va
2cd0: 6c 75 65 54 79 70 65 49 64 2f 4e 61 6d 65 20 20  lueTypeId/Name  
2ce0: 20 20 20 43 72 65 61 74 69 6f 6e 52 65 71 75 65     CreationReque
2cf0: 73 74 73 20 20 20 41 63 74 75 61 6c 6c 79 20 61  sts   Actually a
2d00: 6c 6c 6f 63 61 74 65 64 20 63 6f 75 6e 74 20 2a  llocated count *
2d10: 20 56 61 6c 75 65 2d 74 79 70 65 20 73 69 7a 65   Value-type size
2d20: 6f 66 28 29 20 3d 3d 3e 20 74 6f 74 61 6c 20 62  of() ==> total b
2d30: 79 74 65 73 20 66 72 6f 6d 20 61 6c 6c 6f 63 61  ytes from alloca
2d40: 74 6f 72 0d 0a 0d 0a 33 20 20 69 6e 74 65 67 65  tor....3  intege
2d50: 72 20 20 20 20 20 20 20 20 20 20 20 32 31 30 34  r           2104
2d60: 34 20 20 20 20 20 20 20 20 20 20 20 20 20 20 31  4              1
2d70: 30 36 34 37 20 20 28 30 35 30 2e 35 39 25 29 20  0647  (050.59%) 
2d80: 20 2a 20 34 38 20 3d 3d 3e 20 35 31 31 30 35 36   * 48 ==> 511056
2d90: 20 20 20 0d 0a 34 20 20 64 6f 75 62 6c 65 20 20     ..4  double  
2da0: 20 20 20 20 20 20 20 20 20 20 31 30 31 20 20 20            101   
2db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 38 37 20               87 
2dc0: 20 20 20 20 28 30 38 36 2e 31 34 25 29 20 20 2a      (086.14%)  *
2dd0: 20 34 38 20 3d 3d 3e 20 34 31 37 36 20 20 20 20   48 ==> 4176    
2de0: 20 0d 0a 35 20 20 73 74 72 69 6e 67 20 20 20 20   ..5  string    
2df0: 20 20 20 20 20 20 20 20 35 31 31 35 32 20 20 20          51152   
2e00: 20 20 20 20 20 20 20 20 20 20 20 35 31 31 33 33             51133
2e10: 20 20 28 30 39 39 2e 39 36 25 29 20 20 2a 20 34    (099.96%)  * 4
2e20: 38 20 3d 3d 3e 20 32 37 33 37 32 31 33 20 20 49  8 ==> 2737213  I
2e30: 6e 63 6c 2e 20 73 74 72 69 6e 67 20 62 79 74 65  ncl. string byte
2e40: 73 0d 0a 36 20 20 61 72 72 61 79 20 20 20 20 20  s..6  array     
2e50: 20 20 20 20 20 20 20 20 36 30 30 20 20 20 20 20          600     
2e60: 20 20 20 20 20 20 20 20 20 20 20 36 30 30 20 20             600  
2e70: 20 20 28 31 30 30 2e 30 30 25 29 20 20 2a 20 38    (100.00%)  * 8
2e80: 38 20 3d 3d 3e 20 35 38 32 39 36 20 20 20 20 49  8 ==> 58296    I
2e90: 6e 63 6c 2e 20 70 65 61 6b 20 6c 69 73 74 20 6d  ncl. peak list m
2ea0: 65 6d 6f 72 79 0d 0a 37 20 20 6f 62 6a 65 63 74  emory..7  object
2eb0: 20 20 20 20 20 20 20 20 20 20 20 20 37 33 32 20              732 
2ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 37                 7
2ed0: 33 32 20 20 20 20 28 31 30 30 2e 30 30 25 29 20  32    (100.00%) 
2ee0: 20 2a 20 36 34 20 3d 3d 3e 20 34 36 38 34 38 20   * 64 ==> 46848 
2ef0: 20 20 20 0d 0a 38 20 20 66 75 6e 63 74 69 6f 6e     ..8  function
2f00: 20 20 20 20 20 20 20 20 20 20 32 33 33 20 20 20            233   
2f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 32 33 33               233
2f20: 20 20 20 20 28 31 30 30 2e 30 30 25 29 20 20 2a      (100.00%)  *
2f30: 20 39 36 20 3d 3d 3e 20 32 32 33 36 38 20 20 20   96 ==> 22368   
2f40: 20 0d 0a 39 20 20 65 78 63 65 70 74 69 6f 6e 20   ..9  exception 
2f50: 20 20 20 20 20 20 20 20 34 39 20 20 20 20 20 20          49      
2f60: 20 20 20 20 20 20 20 20 20 20 20 34 39 20 20 20             49   
2f70: 20 20 28 31 30 30 2e 30 30 25 29 20 20 2a 20 37    (100.00%)  * 7
2f80: 32 20 3d 3d 3e 20 33 35 32 38 20 20 20 20 20 0d  2 ==> 3528     .
2f90: 0a 31 30 20 6e 61 74 69 76 65 20 20 20 20 20 20  .10 native      
2fa0: 20 20 20 20 20 20 32 20 20 20 20 20 20 20 20 20        2         
2fb0: 20 20 20 20 20 20 20 20 20 32 20 20 20 20 20 20           2      
2fc0: 28 31 30 30 2e 30 30 25 29 20 20 2a 20 39 36 20  (100.00%)  * 96 
2fd0: 3d 3d 3e 20 31 39 32 20 20 20 20 20 20 0d 0a 31  ==> 192      ..1
2fe0: 31 20 62 75 66 66 65 72 20 20 20 20 20 20 20 20  1 buffer        
2ff0: 20 20 20 20 31 31 20 20 20 20 20 20 20 20 20 20      11          
3000: 20 20 20 20 20 20 20 31 31 20 20 20 20 20 28 31         11     (1
3010: 30 30 2e 30 30 25 29 20 20 2a 20 36 34 20 3d 3d  00.00%)  * 64 ==
3020: 3e 20 31 38 33 38 34 32 20 20 20 5b 31 5d 20 49  > 183842   [1] I
3030: 6e 63 6c 2e 20 70 65 61 6b 20 62 75 66 66 65 72  ncl. peak buffer
3040: 65 64 20 6d 65 6d 6f 72 79 20 61 6e 64 20 6e 6f  ed memory and no
3050: 6e 2d 56 61 6c 75 65 20 62 75 66 66 65 72 73 0d  n-Value buffers.
3060: 0a 31 32 20 68 61 73 68 20 20 20 20 20 20 20 20  .12 hash        
3070: 20 20 20 20 20 20 34 20 20 20 20 20 20 20 20 20        4         
3080: 20 20 20 20 20 20 20 20 20 34 20 20 20 20 20 20           4      
3090: 28 31 30 30 2e 30 30 25 29 20 20 2a 20 38 38 20  (100.00%)  * 88 
30a0: 3d 3d 3e 20 31 31 33 36 20 20 20 20 20 49 6e 63  ==> 1136     Inc
30b0: 6c 2e 20 74 61 62 6c 65 20 6d 65 6d 6f 72 79 0d  l. table memory.
30c0: 0a 31 33 20 63 77 61 6c 5f 73 63 6f 70 65 20 20  .13 cwal_scope  
30d0: 20 20 20 20 20 20 38 39 30 33 20 20 20 20 20 20        8903      
30e0: 20 20 20 20 20 20 20 20 20 31 20 20 20 20 20 20           1      
30f0: 28 30 30 30 2e 30 31 25 29 20 20 2a 20 38 30 20  (000.01%)  * 80 
3100: 3d 3d 3e 20 38 30 20 20 20 20 20 20 20 5b 32 5d  ==> 80       [2]
3110: 0d 0a 31 34 20 63 77 61 6c 5f 6b 76 70 20 20 20  ..14 cwal_kvp   
3120: 20 20 20 20 20 20 20 33 30 33 31 20 20 20 20 20         3031     
3130: 20 20 20 20 20 20 20 20 20 20 33 30 33 31 20 20            3031  
3140: 20 28 31 30 30 2e 30 30 25 29 20 20 2a 20 33 32   (100.00%)  * 32
3150: 20 3d 3d 3e 20 39 36 39 39 32 20 20 20 20 0d 0a   ==> 96992    ..
3160: 31 36 20 78 2d 73 74 72 69 6e 67 20 20 20 20 20  16 x-string     
3170: 20 20 20 20 20 33 32 20 20 20 20 20 20 20 20 20       32         
3180: 20 20 20 20 20 20 20 20 33 32 20 20 20 20 20 28          32     (
3190: 31 30 30 2e 30 30 25 29 20 20 2a 20 35 36 20 3d  100.00%)  * 56 =
31a0: 3d 3e 20 31 37 39 32 20 20 20 20 20 4e 6f 74 20  => 1792     Not 
31b0: 69 6e 63 6c 2e 20 65 78 74 65 72 6e 61 6c 20 73  incl. external s
31c0: 74 72 69 6e 67 20 62 79 74 65 73 0d 0a 31 37 20  tring bytes..17 
31d0: 7a 2d 73 74 72 69 6e 67 20 20 20 20 20 20 20 20  z-string        
31e0: 20 20 34 20 20 20 20 20 20 20 20 20 20 20 20 20    4             
31f0: 20 20 20 20 20 34 20 20 20 20 20 20 28 31 30 30       4      (100
3200: 2e 30 30 25 29 20 20 2a 20 35 36 20 3d 3d 3e 20  .00%)  * 56 ==> 
3210: 32 34 32 20 20 20 20 20 20 49 6e 63 6c 2e 20 73  242      Incl. s
3220: 74 72 69 6e 67 20 62 79 74 65 73 0d 0a 0d 0a 54  tring bytes....T
3230: 6f 74 61 6c 73 3a 20 20 20 20 20 20 20 20 20 20  otals:          
3240: 20 20 20 20 37 36 39 39 36 20 20 20 20 20 20 20      76996       
3250: 20 20 20 20 20 20 20 36 36 35 36 36 20 20 28 30         66566  (0
3260: 38 36 2e 34 35 25 29 5b 31 5d 20 20 20 20 3d 3d  86.45%)[1]    ==
3270: 3e 20 33 36 36 37 37 36 31 20 0d 0a 0d 0a 5b 31  > 3667761 ....[1
3280: 5d 20 3d 20 25 20 61 70 70 6c 69 65 73 20 74 6f  ] = % applies to
3290: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 63 6f 75 6e   allocation coun
32a0: 74 73 2c 20 6e 6f 74 20 73 69 7a 65 73 2e 20 54  ts, not sizes. T
32b0: 68 65 20 74 6f 74 61 6c 20 63 6f 75 6e 74 20 64  he total count d
32c0: 6f 65 73 20 6e 6f 74 20 61 63 63 6f 75 6e 74 20  oes not account 
32d0: 66 6f 72 20 62 75 66 66 65 72 20 6d 65 6d 6f 72  for buffer memor
32e0: 79 20 28 72 65 29 61 6c 6c 6f 63 61 74 69 6f 6e  y (re)allocation
32f0: 73 2c 20 62 75 74 20 74 68 65 20 74 6f 74 61 6c  s, but the total
3300: 20 73 69 7a 65 20 64 6f 65 73 2e 0d 0a 0d 0a 5b   size does.....[
3310: 32 5d 20 3d 20 53 63 6f 70 65 73 20 61 72 65 20  2] = Scopes are 
3320: 61 6c 6d 6f 73 74 20 61 6c 77 61 79 73 20 73 74  almost always st
3330: 61 63 6b 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e  ack allocated an
3340: 64 20 73 6b 65 77 20 74 68 65 20 73 74 61 74 69  d skew the stati
3350: 73 74 69 63 73 2c 20 73 6f 20 6f 6e 6c 79 20 61  stics, so only a
3360: 6c 6c 6f 63 61 74 65 64 20 73 63 6f 70 65 73 20  llocated scopes 
3370: 61 72 65 20 63 6f 75 6e 74 65 64 20 66 6f 72 20  are counted for 
3380: 74 6f 74 61 6c 73 20 70 75 72 70 6f 73 65 73 2e  totals purposes.
3390: 0d 0a 0d 0a 47 65 6e 65 72 61 6c 2d 70 75 72 70  ....General-purp
33a0: 6f 73 65 20 62 75 66 66 65 72 20 63 61 70 61 63  ose buffer capac
33b0: 69 74 79 3a 20 31 35 31 20 62 79 74 65 73 0d 0a  ity: 151 bytes..
33c0: 0d 0a 50 72 6f 70 65 72 74 79 2d 73 6f 72 74 69  ..Property-sorti
33d0: 6e 67 20 62 75 66 66 65 72 20 63 61 70 61 63 69  ng buffer capaci
33e0: 74 79 3a 20 34 30 20 62 79 74 65 73 0d 0a 0d 0a  ty: 40 bytes....
33f0: 63 77 61 6c 5f 65 6e 67 69 6e 65 20 69 6e 73 74  cwal_engine inst
3400: 61 6e 63 65 20 61 70 70 65 61 72 73 20 74 6f 20  ance appears to 
3410: 68 61 76 65 20 62 65 65 6e 20 73 74 61 63 6b 2d  have been stack-
3420: 61 6c 6c 6f 63 61 74 65 64 20 28 6e 6f 74 20 62  allocated (not b
3430: 79 20 63 77 61 6c 5f 65 6e 67 69 6e 65 5f 69 6e  y cwal_engine_in
3440: 69 74 28 29 29 2e 0d 0a 0d 0a 54 6f 74 61 6c 20  it()).....Total 
3450: 62 79 74 65 73 20 61 6c 6c 6f 63 61 74 65 64 20  bytes allocated 
3460: 66 6f 72 20 6d 65 74 72 69 63 73 2d 74 72 61 63  for metrics-trac
3470: 6b 65 64 20 72 65 73 6f 75 72 63 65 73 3a 20 33  ked resources: 3
3480: 36 36 37 39 35 32 0d 0a 3c 2f 70 72 65 3e 3c 2f  667952..</pre></
3490: 6e 6f 77 69 6b 69 3e 3c 2f 62 6c 6f 63 6b 71 75  nowiki></blockqu
34a0: 6f 74 65 3e 0d 0a 0d 0a 54 68 65 20 69 6e 74 65  ote>....The inte
34b0: 67 65 72 73 20 61 72 65 20 76 65 72 79 20 69 6e  gers are very in
34c0: 74 65 72 65 73 74 69 6e 67 20 74 68 65 72 65 3a  teresting there:
34d0: 20 6f 6e 6c 79 20 68 61 6c 66 20 72 65 71 75 69   only half requi
34e0: 72 65 64 20 61 6c 6c 6f 63 61 74 69 6f 6e 2e 20  red allocation. 
34f0: 4f 6e 65 20 6d 69 67 68 74 20 77 65 6c 6c 20 72  One might well r
3500: 65 61 73 6f 6e 61 62 6c 79 20 61 73 6b 2c 20 22  easonably ask, "
3510: 68 6f 77 20 69 73 20 74 68 61 74 20 70 6f 73 73  how is that poss
3520: 69 62 6c 65 20 69 66 20 72 65 63 79 63 6c 69 6e  ible if recyclin
3530: 67 20 69 73 20 64 69 73 61 62 6c 65 64 3f 22 20  g is disabled?" 
3540: 54 68 65 20 74 72 69 63 6b 20 69 73 20 74 68 61  The trick is tha
3550: 74 20 74 68 65 20 69 6e 74 65 67 65 72 20 61 6e  t the integer an
3560: 64 20 64 6f 75 62 6c 65 20 76 61 6c 75 65 73 20  d double values 
3570: 2d 31 2c 20 30 2c 20 61 6e 64 20 31 20 61 72 65  -1, 0, and 1 are
3580: 20 62 75 69 6c 74 2d 69 6e 20 63 6f 6e 73 74 61   built-in consta
3590: 6e 74 73 2c 20 61 6e 64 20 6e 65 76 65 72 20 72  nts, and never r
35a0: 65 71 75 69 72 65 20 61 6c 6c 6f 63 61 74 69 6f  equire allocatio
35b0: 6e 2e 20 54 68 69 73 20 69 73 20 61 6e 20 6f 70  n. This is an op
35c0: 74 69 6d 69 7a 61 74 69 6f 6e 20 77 68 69 63 68  timization which
35d0: 2c 20 69 6e 20 68 69 6e 64 73 69 67 68 74 2c 20  , in hindsight, 
35e0: 70 61 69 64 20 6f 66 66 20 69 6e 20 73 70 61 64  paid off in spad
35f0: 65 73 2e 20 57 65 20 63 61 6e 20 69 6e 66 65 72  es. We can infer
3600: 20 66 72 6f 6d 20 74 68 65 73 65 20 6e 75 6d 62   from these numb
3610: 65 72 73 20 74 68 61 74 20 74 68 6f 73 65 20 74  ers that those t
3620: 68 72 65 65 20 76 61 6c 75 65 73 20 6d 61 6b 65  hree values make
3630: 20 75 70 20 68 61 6c 66 20 6f 66 20 74 68 65 20   up half of the 
3640: 69 6e 74 65 67 65 72 73 20 75 73 65 64 20 62 79  integers used by
3650: 20 74 68 65 20 73 63 72 69 70 74 20 63 6f 64 65   the script code
3660: 2e 20 28 4d 61 79 62 65 20 74 68 61 74 27 73 20  . (Maybe that's 
3670: 62 65 63 61 75 73 65 20 69 20 6f 66 74 65 6e 20  because i often 
3680: 74 79 70 65 20 22 31 22 20 61 73 20 61 20 73 68  type "1" as a sh
3690: 6f 72 74 2d 68 61 6e 64 20 66 6f 72 20 22 74 72  ort-hand for "tr
36a0: 75 65 22 3f 29 0d 0a 0d 0a 53 74 72 69 6e 67 73  ue"?)....Strings
36b0: 20 68 61 76 65 20 61 20 73 69 6d 69 6c 61 72 20   have a similar 
36c0: 73 70 65 63 69 61 6c 20 63 61 73 65 3a 20 6c 65  special case: le
36d0: 6e 67 74 68 2d 7a 65 72 6f 20 73 74 72 69 6e 67  ngth-zero string
36e0: 73 20 61 72 65 20 61 6c 6c 20 74 68 65 20 73 61  s are all the sa
36f0: 6d 65 20 73 74 72 69 6e 67 20 69 6e 73 74 61 6e  me string instan
3700: 63 65 2e 20 53 6f 20 77 65 20 63 61 6e 20 69 6e  ce. So we can in
3710: 66 65 72 20 62 79 20 74 68 65 73 65 20 6e 75 6d  fer by these num
3720: 62 65 72 73 20 74 68 61 74 20 30 2e 30 34 25 20  bers that 0.04% 
3730: 6f 66 20 74 68 65 20 73 74 72 69 6e 67 20 72 65  of the string re
3740: 71 75 65 73 74 73 20 77 65 20 66 6f 72 20 65 6d  quests we for em
3750: 70 74 79 20 73 74 72 69 6e 67 73 2e 0d 0a 0d 0a  pty strings.....
3760: 4c 69 6b 65 77 69 73 65 2c 20 74 68 65 20 62 6f  Likewise, the bo
3770: 6f 6c 65 61 6e 2c 20 6e 75 6c 6c 2c 20 61 6e 64  olean, null, and
3780: 20 75 6e 64 65 66 69 6e 65 64 20 76 61 6c 75 65   undefined value
3790: 73 20 61 72 65 20 61 6c 73 6f 20 62 75 69 6c 74  s are also built
37a0: 2d 69 6e 20 63 6f 6e 73 74 61 6e 74 73 20 77 68  -in constants wh
37b0: 69 63 68 20 28 6c 69 6b 65 20 74 68 65 20 61 62  ich (like the ab
37c0: 6f 76 65 2d 6d 65 6e 74 69 6f 6e 65 64 20 63 61  ove-mentioned ca
37d0: 73 65 73 29 20 64 6f 20 6e 6f 74 20 70 61 72 74  ses) do not part
37e0: 61 6b 65 20 69 6e 20 72 65 66 65 72 65 6e 63 65  ake in reference
37f0: 20 63 6f 75 6e 74 69 6e 67 2c 20 73 63 6f 70 65   counting, scope
3800: 20 6f 77 6e 65 72 73 68 69 70 2c 20 6f 72 20 73   ownership, or s
3810: 65 76 65 72 61 6c 20 6f 74 68 65 72 20 69 6e 74  everal other int
3820: 72 69 63 61 63 69 65 73 20 6f 66 20 74 68 65 20  ricacies of the 
3830: 65 6e 67 69 6e 65 2e 20 54 68 6f 75 67 68 20 74  engine. Though t
3840: 68 65 79 20 61 72 65 20 75 73 65 64 20 62 79 20  hey are used by 
3850: 63 6c 69 65 6e 74 73 20 6a 75 73 74 20 6c 69 6b  clients just lik
3860: 65 20 61 6e 79 20 6f 74 68 65 72 20 76 61 6c 75  e any other valu
3870: 65 73 2c 20 72 65 66 63 6f 75 6e 74 69 6e 67 20  es, refcounting 
3880: 61 6e 64 20 72 65 73 63 6f 70 69 6e 67 20 61 72  and rescoping ar
3890: 65 20 61 63 74 75 61 6c 6c 79 20 6e 6f 2d 6f 70  e actually no-op
38a0: 73 20 66 6f 72 20 61 6c 6c 20 62 75 69 6c 74 2d  s for all built-
38b0: 69 6e 20 63 6f 6e 73 74 61 6e 74 20 76 61 6c 75  in constant valu
38c0: 65 73 2e 20 49 6e 74 65 72 6e 61 6c 6c 79 2c 20  es. Internally, 
38d0: 74 68 65 20 64 65 74 65 72 6d 69 6e 61 74 69 6f  the determinatio
38e0: 6e 20 77 68 65 74 68 65 72 20 61 20 67 69 76 65  n whether a give
38f0: 6e 20 56 61 6c 75 65 20 70 6f 69 6e 74 65 72 20  n Value pointer 
3900: 72 65 66 65 72 73 20 74 6f 20 61 20 62 75 69 6c  refers to a buil
3910: 74 2d 69 6e 20 63 6f 6e 73 74 61 6e 74 20 72 65  t-in constant re
3920: 71 75 69 72 65 73 20 6f 6e 6c 79 20 74 77 6f 20  quires only two 
3930: 70 6f 69 6e 74 65 72 20 61 64 64 72 65 73 73 20  pointer address 
3940: 63 6f 6d 70 61 72 69 73 6f 6e 73 2c 20 73 6f 20  comparisons, so 
3950: 69 74 27 73 20 66 61 73 74 2e 20 57 65 20 64 6f  it's fast. We do
3960: 20 6e 6f 74 20 6b 65 65 70 20 61 20 66 6c 61 67   not keep a flag
3970: 20 66 6f 72 20 74 68 69 73 2c 20 62 75 74 20 68   for this, but h
3980: 6f 77 20 77 65 20 73 74 6f 72 65 20 74 68 65 20  ow we store the 
3990: 62 75 69 6c 74 69 6e 73 20 61 6c 6c 6f 77 73 20  builtins allows 
39a0: 75 73 20 74 6f 20 64 65 74 65 72 6d 69 6e 65 20  us to determine 
39b0: 74 68 65 69 72 20 22 62 75 69 6c 74 2d 69 6e 2d  their "built-in-
39c0: 65 64 6e 65 73 73 22 20 77 69 74 68 6f 75 74 20  edness" without 
39d0: 6f 6e 65 20 76 65 72 79 20 71 75 69 63 6b 6c 79  one very quickly
39e0: 2e 20 53 65 61 72 63 68 20 5b 2f 66 69 6e 66 6f  . Search [/finfo
39f0: 2f 63 77 61 6c 2e 63 7c 63 77 61 6c 2e 63 5d 20  /cwal.c|cwal.c] 
3a00: 66 6f 72 20 3c 74 74 3e 43 57 41 4c 5f 42 55 49  for <tt>CWAL_BUI
3a10: 4c 54 49 4e 5f 56 41 4c 53 5f 3c 2f 74 74 3e 20  LTIN_VALS_</tt> 
3a20: 61 6e 64 20 3c 74 74 3e 56 5f 49 53 5f 42 55 49  and <tt>V_IS_BUI
3a30: 4c 54 49 4e 28 56 29 3c 2f 74 74 3e 20 66 6f 72  LTIN(V)</tt> for
3a40: 20 61 6e 20 65 78 70 6c 61 6e 61 74 69 6f 6e 20   an explanation 
3a50: 6f 66 20 68 6f 77 20 69 74 20 77 6f 72 6b 73 2e  of how it works.
3a60: 0d 0a 0d 0a 54 68 61 74 20 63 6f 6e 63 6c 75 64  ....That conclud
3a70: 65 73 20 6f 75 72 20 69 6e 74 72 6f 64 75 63 74  es our introduct
3a80: 69 6f 6e 20 74 6f 20 63 77 61 6c 27 73 20 6d 65  ion to cwal's me
3a90: 6d 6f 72 79 20 73 79 73 74 65 6d 21 0a 5a 20 32  mory system!.Z 2
3aa0: 36 62 37 34 35 38 62 61 38 31 35 63 66 36 31 30  6b7458ba815cf610
3ab0: 39 61 30 66 64 65 61 30 36 38 63 30 36 38 39 0a  9a0fdea068c0689.