hlibsass-0.1.5.0: libsass/src/memory_manager.cpp
#include "ast.hpp"
#include "memory_manager.hpp"
namespace Sass {
Memory_Manager::Memory_Manager(size_t size)
: nodes(std::vector<Memory_Object*>())
{
size_t init = size;
if (init < 8) init = 8;
// reserve some space
nodes.reserve(init);
}
Memory_Manager::~Memory_Manager()
{
// release memory for all controlled nodes
// avoid calling erase for every single node
for (size_t i = 0, S = nodes.size(); i < S; ++i) {
deallocate(nodes[i]);
}
// just in case
nodes.clear();
}
Memory_Object* Memory_Manager::add(Memory_Object* np)
{
// object has been initialized
// it can be "deleted" from now on
np->refcount = 1;
return np;
}
bool Memory_Manager::has(Memory_Object* np)
{
// check if the pointer is controlled under our pool
return find(nodes.begin(), nodes.end(), np) != nodes.end();
}
Memory_Object* Memory_Manager::allocate(size_t size)
{
// allocate requested memory
void* heap = malloc(size);
// init internal refcount status to zero
(static_cast<Memory_Object*>(heap))->refcount = 0;
// add the memory under our management
nodes.push_back(static_cast<Memory_Object*>(heap));
// cast object to its initial type
return static_cast<Memory_Object*>(heap);
}
void Memory_Manager::deallocate(Memory_Object* np)
{
// only call destructor if initialized
if (np->refcount) np->~Memory_Object();
// always free the memory
free(np);
}
void Memory_Manager::remove(Memory_Object* np)
{
// remove node from pool (no longer active)
nodes.erase(find(nodes.begin(), nodes.end(), np));
// you are now in control of the memory
}
void Memory_Manager::destroy(Memory_Object* np)
{
// remove from pool
remove(np);
// release memory
deallocate(np);
}
}