View Single Post
Old 10-19-2015, 05:48 AM   #76
derek.john.evans
Human being with feelings
 
derek.john.evans's Avatar
 
Join Date: Feb 2011
Location: Adelaide, South Australia
Posts: 217
Default

EDIT: Ive written an improved heap manager which is available from here:
https://stash.reaper.fm/v/25527/Heman...%20Manager.zip

Here is my older memory manager code. Managed memory starts from block 4. Largest memory block allowed is 1 Gig. I'm now using the Heman code available above.

TIP: Ignore the heap functions, and just use the standard malloc(), calloc(), realloc() & free() functions.

Code:
@init

// Helper function to ensure a valid memory size value.
function size_t(x) global()
(
  max(floor(x), 0);
);

// Sets the starting offset for heap memory. Also resets heap link list.
function heap.min(min) global()
(
  // Heap min is hardcoded to block 4.
  this.min = this.max = max(size_t(min), 4 << 16);
  this.min[] = 0;
);

function heap.max(max) global()
(
  this.max = max(this.min, size_t(max));
);

heap.min(0);

// Returns the max heap used. Includes memory that was freed.
function heap.size() global()
(
  this.max - this.min;
);

// Checks the heap block is valid. Not 100% perfect, but the best we can achieve.
function heap.check(block) global()
(
  block >= this.min && (block[] <= -1 || block[] >= 1);
);

// Returns true if heap block is free.
function heap.isfree(block) global()
(
  this.heap.check(block) && block[] < 0;
);

// Merges free blocks into one free block.
function heap.merge(block) global() local(ptr, size)
(
  this.heap.isfree(block) ? (
    size = 0; ptr = block;
    while (this.heap.isfree(ptr)) ( size += ptr[]; ptr += abs(ptr[]); );
    block[] = size;
  );
);

/*
Checks if block is avaliable to store a given size. Also handles merging
of freed blocks after given block.
*/
function heap.avail(block, size) global()
(
  !this.heap.check(block) ? block[] = -0x80000000; // 1 gig should be more than enough.
  this.heap.merge(block);
  size <= -block[];
);

// Allocates a block of memory. Does not clear the new memory.
function malloc(size) global(heap*) local(block)
(
  size = size_t(size) + 1;
  size >= 1 && size < 0x80000000 ? (
    block = heap.min;
    while (!heap.avail(block, size)) ( block += abs(block[]); );
    size != -block[] ? block[size] = block[] + size;
    block[] = size;
    heap.max(max(heap.max, block + size));
    block + 1;
  ) : 0;
);

// Same as malloc, but clears the memory to zero. (This is a non-standard helper)
function calloc(size) global()
(
  size = size_t(size);
  memset(malloc(size), 0, size);
);

// Same as malloc, but clears the memory to zero. 
function calloc(count, size) global()
(
  calloc(size_t(count) * size_t(size));
);

// Returns TRUE if memory location is valid.
function mcheck(memory) global(heap*)
(
  heap.check(memory - 1);
);

// Returns the size of given memory location.
function _msize(memory) global()
(
  mcheck(memory) && memory[-1] > 0 ? memory[-1] - 1 : 0;
);

// Same as _msize(). Mac name alias.
function malloc_size(memory) global()
(
  _msize(memory);
);

// Frees a memory block.
function free(memory) global()
(
  mcheck(memory) ? memory[-1] = -abs(memory[-1]);
  0;
);

// Realloc a memory block, with option to clear new memory.
function realloc(memory, size, clear) global() local(newmem)
(
  size = size_t(size);
  size == _msize(memory) ? (
    memory;
  ) : (
    newmem = clear ? calloc(size) : malloc(size);
    memcpy(newmem, memory, min(size, _msize(memory)));
    free(memory);
    newmem;
  );
);

// Traditional realloc. New memory is not cleared.
function realloc(m, n) global()
(
  realloc(m, n, 0);
);
Just a little info about JS memory. JS memory is allocated in pages of (1 << 16) items. ie: 65536 doubles, which is 512kb of memory. The above memory manager starts on page 4, which gives 2 meg for normal memory usage.

Sing out if you find a bug. I have done a lot of testing, but, more testing is always good.
__________________
http://wascal.net/music/

Last edited by derek.john.evans; 11-05-2015 at 10:58 AM.
derek.john.evans is offline   Reply With Quote