blob: d4ca70bbd3213f1804ef374f4d4a7f3e7f98e64c [file] [log] [blame]
\ *****************************************************************************
\ * Copyright (c) 2011 IBM Corporation
\ * All rights reserved.
\ * This program and the accompanying materials
\ * are made available under the terms of the BSD License
\ * which accompanies this distribution, and is available at
\ * http://www.opensource.org/licenses/bsd-license.php
\ *
\ * Contributors:
\ * IBM Corporation - initial implementation
\ ****************************************************************************/
\ * Dynamic memory allocation/de-allocation debug functions
\ *****************************************************************************
\ Uncomment the following code for debugging bad write accesses beyond
\ the end of the allocated block:
\ Store magic value past the end of the block during alloc-mem and
\ check for this magic value when free-mem has been called.
#if 1
: alloc-mem ( len -- addr )
dup /n + alloc-mem ( len addr )
2dup + 3141592653589793 swap ! nip
;
: free-mem ( addr len -- )
2dup + @ 3141592653589793 <> IF
cr ." Detected memory corrupt during free-mem of "
swap . . cr EXIT
THEN
/n + free-mem
;
#endif
\ Never ever assume that allocated memory is pre-initialized with 0 ...
: alloc-mem ( len -- addr )
dup alloc-mem swap 2dup ff fill drop
;
\ Make sure that memory block do not contain "valid" data after free-mem:
: free-mem ( addr len -- )
2dup ff fill free-mem
;
\ The following definitions are used for debugging the parameters of free-mem:
\ Store block address and size of allocated blocks
\ in an array, then check for right values on free-mem.
1000 CONSTANT max-malloced-blocks
CREATE malloced-blocks max-malloced-blocks 2 * cells allot
malloced-blocks max-malloced-blocks 2 * cells erase
: alloc-mem ( len -- addr )
dup alloc-mem dup 0= IF
cr ." alloc-mem returned 0 for size " swap . cr EXIT
THEN ( len addr )
malloced-blocks max-malloced-blocks 0 DO ( len addr m-blocks-ptr )
dup @ 0= IF ( len addr m-blocks-ptr )
\ Found a free entry: store addr and len
over >r dup >r !
r> cell+ !
r> UNLOOP EXIT
THEN
cell+ cell+ ( len addr next-m-blocks-ptr )
LOOP
." Please increase max-malloced-blocks." cr ( len addr next-m-blocks-ptr )
drop nip
;
: free-mem ( addr len -- )
malloced-blocks max-malloced-blocks 0 DO ( addr len m-blocks-ptr )
dup @ ?dup IF
( addr len m-blocks-ptr s-addr )
3 pick = IF
( addr len m-blocks-ptr )
dup cell+ @ ( addr len m-blocks-ptr s-len )
2 pick = IF ( addr len m-blocks-ptr )
\ All right, addr and len matched,
\ clear entry and call original free-mem.
dup cell+ 0 swap !
0 swap !
free-mem
ELSE
>r swap cr
." free-mem called for block " . ." with wrong size=" . cr
." ( correct size should be: " r> cell+ @ . ." )" cr
THEN
UNLOOP EXIT
THEN ( addr len m-blocks-ptr )
THEN
cell+ cell+ ( addr len next-m-blocks-ptr )
LOOP
drop swap cr
." free-mem called for block " .
." ( size=" .
." ) which has never been allocated before!" cr
;
\ Enable these for verbose debug messages:
#if 0
: alloc-mem
cr ." alloc-mem with len=" dup .
alloc-mem
." returned addr=" dup . cr
;
: free-mem
cr ." free mem addr=" over . ." len=" dup . cr
free-mem
;
#endif