Bump $VERSION to 0.77_50
[p5sagit/Devel-Size.git] / lib / Devel / Size.pm
index 43b4098..61ad183 100644 (file)
@@ -1,30 +1,31 @@
 package Devel::Size;
 
 use strict;
-use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $warn);
+use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS $warn $dangle);
 
+require 5.005;
 require Exporter;
-require DynaLoader;
+require XSLoader;
 
-@ISA = qw(Exporter DynaLoader);
+@ISA = qw(Exporter);
 
-# This allows declaration      use Devel::Size ':all';
-%EXPORT_TAGS = ( 'all' => [ qw(
-       size total_size
-) ] );
+@EXPORT_OK = qw(size total_size);
 
-@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+# This allows declaration   use Devel::Size ':all';
+%EXPORT_TAGS = ( 'all' => \@EXPORT_OK );
 
-@EXPORT = qw( );
-$VERSION = '0.67';
+$VERSION = '0.77_50';
 
-bootstrap Devel::Size $VERSION;
+XSLoader::load( __PACKAGE__);
 
 $warn = 1;
+$dangle = 0; ## Set true to enable warnings about dangling pointers
 
 1;
 __END__
 
+=pod
+
 =head1 NAME
 
 Devel::Size - Perl extension for finding the memory usage of Perl variables
@@ -39,16 +40,18 @@ Devel::Size - Perl extension for finding the memory usage of Perl variables
   my $other_size = size(\@foo);
 
   my $foo = {a => [1, 2, 3],
-         b => {a => [1, 3, 4]}
+      b => {a => [1, 3, 4]}
          };
-  my  $total_size = total_size($foo);
+  my $total_size = total_size($foo);
 
 =head1 DESCRIPTION
 
-This module figures out the real sizes of Perl variables in bytes.  
+This module figures out the real size of Perl variables in bytes, as
+accurately as possible.
+
 Call functions with a reference to the variable you want the size
 of.  If the variable is a plain scalar it returns the size of
-the scalar.  If the variable is a hash or an array, use a reference
+this scalar.  If the variable is a hash or an array, use a reference
 when calling.
 
 =head1 FUNCTIONS
@@ -84,14 +87,15 @@ the constant values we'll talk about, not their existence)
 
 =head2 The C library
 
-It's important firtst to understand how your OS and libraries handle
+It's important first to understand how your OS and libraries handle
 memory. When the perl interpreter needs some memory, it asks the C
 runtime library for it, using the C<malloc()> call. C<malloc> has one
 parameter, the size of the memory allocation you want, and returns a
 pointer to that memory. C<malloc> also makes sure that the pointer it
 returns to you is properly aligned. When you're done with the memory
 you hand it back to the library with the C<free()> call. C<free> has
-one parameter, the pointer that C<malloc> returned. There are a couple of interesting ramifications to this.
+one parameter, the pointer that C<malloc> returned.
+There are a couple of interesting ramifications to this.
 
 Because malloc has to return an aligned pointer, it will round up the
 memory allocation to make sure that the memory it returns is aligned
@@ -178,18 +182,22 @@ bytes. If the key is 7 characters then the allocation is 24 bytes on
 a 32 bit system. If you're on a 64 bit system the numbers get even
 larger.
 
-This does mean that hashes eat up a I<lot> of memory, both in memory
-Devel::Size can track (the memory actually in the structures and
-strings) and that it can't (the malloc alignment and length overhead).
-
 =head1 DANGERS
 
-Devel::Size, because of the way it works, can consume a
-considerable amount of memory as it runs. It will use five
-pointers, two integers, and two bytes worth of storage, plus
-potential alignment and bucket overhead, per thing it looks at. This
-memory is released at the end, but it may fragment your free pool,
-and will definitely expand your process' memory footprint.
+Since version 0.72, Devel::Size uses a new pointer tracking mechanism
+that consumes far less memory than was previously the case. It does this
+by using a bit vector where 1 bit represents each 4- or 8-byte aligned pointer
+(32- or 64-bit platform dependant) that could exist. Further, it segments
+that bit vector and only allocates each chunk when an address is seen within
+that chunk. Since version 0.73, chunks are allocated in blocks of 2**16 bits
+(ie 8K), accessed via a 256-way tree. The tree is 2 levels deep on a 32 bit
+system, 6 levels deep on a 64 bit system. This avoids having make any
+assumptions about address layout on 64 bit systems or trade offs about sizes
+to allocate. It assumes that the addresses of allocated pointers are reasonably
+contiguous, so that relevant parts of the tree stay in the CPU cache.
+
+Besides saving a lot of memory, this change means that Devel::Size
+runs significantly faster than previous versions.
 
 =head1 Messages: texts originating from this module.
 
@@ -197,28 +205,56 @@ and will definitely expand your process' memory footprint.
 
 =over 4
 
-=item  "Devel::Size: Unknown variable type"
+=item   "Devel::Size: Unknown variable type"
 
-The thing (or something contained within it) that you gave to 
+The thing (or something contained within it) that you gave to
 total_size() was unrecognisable as a Perl entity.
 
 =back
 
 =head2 warnings
 
-These messages warn you that for some types, the sizes calculated may not include 
-everything that could be associated with those types. The differences are usually 
+These messages warn you that for some types, the sizes calculated may not include
+everything that could be associated with those types. The differences are usually
 insignificant for most uses of this module.
 
 These may be disabled by setting
 
-       $Devel::Size::warn = 0
+    $Devel::Size::warn = 0
 
 =over 4
 
-=item  "Devel::Size: Calculated sizes for CVs are incomplete"
+=item   "Devel::Size: Calculated sizes for CVs are incomplete"
 
-=item  "Devel::Size: Calculated sizes for FMs are incomplete"
+=item   "Devel::Size: Calculated sizes for FMs are incomplete"
+
+=item   "Devel::Size: Calculated sizes for compiled regexes are incompatible, and probably always will be"
+
+=back
+
+=head2 New warnings since 0.72
+
+Devel::Size has always been vulnerable to trapping when traversing Perl's
+internal data structures, if it encounters uninitialised (dangling) pointers.
+
+MSVC provides exception handling able to deal with this possibility, and when
+built with MSVC Devel::Size will now attempt to ignore (or log) them and
+continue. These messages are mainly of interest to Devel::Size and core
+developers, and so are disabled by default.
+
+They may be enabled by setting
+
+    $Devel::Size::dangle = 0
+
+=over 4
+
+=item       "Devel::Size: Can't determine class of operator OPx_XXXX, assuming BASEOP\n"
+
+=item       "Devel::Size: Encountered bad magic at: 0xXXXXXXXX"
+
+=item       "Devel::Size: Encountered dangling pointer in opcode at: 0xXXXXXXXX"
+
+=item       "Devel::Size: Encountered invalid pointer: 0xXXXXXXXX"
 
 =back
 
@@ -237,14 +273,18 @@ Dan Sugalski dan@sidhe.org
 
 Small portion taken from the B module as shipped with perl 5.6.2.
 
-Maintained now by Tels <http://bloodgate.com>
+Previously maintained by Tels <http://bloodgate.com>
+
+New pointer tracking & exception handling for 0.72 by BrowserUK
+
+Currently maintained by Nicholas Clark
 
 =head1 COPYRIGHT
 
-Copyright (C) 2005 Dan Sugalski, Copyright (C) 2007 Tels
+Copyright (C) 2005 Dan Sugalski, Copyright (C) 2007-2008 Tels
 
 This module is free software; you can redistribute it and/or modify it
-under the same terms as Perl itself.
+under the same terms as Perl v5.8.8.
 
 =head1 SEE ALSO