buffer: add dispose to Buffer instance api

Users now have the ability to manually dispose a Buffer when it's no
longer needed. This will transform the instance into a zero-length
Buffer. If the instance was a slice then the memory is not actually
released, but the pointer to the parent allocation is removed.
buffer: keep __refs count on slices

To prevent a double memory corruption the parent has a __refs counter
that keeps track of how many children are pointing to it.

WIP even if the parent is deleted then the __refs still needs to stick
around. and if __refs == 1 on dispose(), and being called on the slice,
then need to both dispose the slice and the parent. but the parent can't
be disposed until all children are also disposed.