#include "../sass.hpp" #include #include #include "SharedPtr.hpp" #include "../ast_fwd_decl.hpp" #ifdef DEBUG_SHARED_PTR #include "../debugger.hpp" #endif namespace Sass { #ifdef DEBUG_SHARED_PTR void SharedObj::dumpMemLeaks() { if (!all.empty()) { std::cerr << "###################################\n"; std::cerr << "# REPORTING MISSING DEALLOCATIONS #\n"; std::cerr << "###################################\n"; for (SharedObj* var : all) { if (AST_Node_Ptr ast = dynamic_cast(var)) { debug_ast(ast); } else { std::cerr << "LEAKED " << var << "\n"; } } } } std::vector SharedObj::all; #endif bool SharedObj::taint = false; SharedObj::SharedObj() : detached(false) #ifdef DEBUG_SHARED_PTR , dbg(false) #endif { refcounter = 0; #ifdef DEBUG_SHARED_PTR if (taint) all.push_back(this); #endif }; SharedObj::~SharedObj() { #ifdef DEBUG_SHARED_PTR if (dbg) std::cerr << "Destruct " << this << "\n"; if(!all.empty()) { // check needed for MSVC (no clue why?) all.erase(std::remove(all.begin(), all.end(), this), all.end()); } #endif }; void SharedPtr::decRefCount() { if (node) { -- node->refcounter; #ifdef DEBUG_SHARED_PTR if (node->dbg) std::cerr << "- " << node << " X " << node->refcounter << " (" << this << ") " << "\n"; #endif if (node->refcounter == 0) { #ifdef DEBUG_SHARED_PTR // AST_Node_Ptr ast = dynamic_cast(node); if (node->dbg) std::cerr << "DELETE NODE " << node << "\n"; #endif if (!node->detached) { delete(node); } } } } void SharedPtr::incRefCount() { if (node) { ++ node->refcounter; node->detached = false; #ifdef DEBUG_SHARED_PTR if (node->dbg) { std::cerr << "+ " << node << " X " << node->refcounter << " (" << this << ") " << "\n"; } #endif } } SharedPtr::~SharedPtr() { decRefCount(); } // the create constructor SharedPtr::SharedPtr(SharedObj* ptr) : node(ptr) { incRefCount(); } // copy assignment operator SharedPtr& SharedPtr::operator=(const SharedPtr& rhs) { void* cur_ptr = (void*) node; void* rhs_ptr = (void*) rhs.node; if (cur_ptr == rhs_ptr) { return *this; } decRefCount(); node = rhs.node; incRefCount(); return *this; } // the copy constructor SharedPtr::SharedPtr(const SharedPtr& obj) : node(obj.node) { incRefCount(); } }