bool doGc(Allocator* allocator, AllocatorObjectsIterator* iterator, bool recursiv) { int before_gc_elements; int before_gc_memory; { const AllocatorInfo& ainf = allocator->getAllocatorInfo(); before_gc_elements = ainf.memTypes[ObjectMem].count; before_gc_memory = ainf.memTypes[ObjectMem].size; } //#if 0 //int before_gc_elements = allocator->getElementCount(UnspecifiedMem); //int before_gc_memory = allocator->getAllocatedCount(UnspecifiedMem); Object* o = 0; int objectcount = 0; while ((o = iterator->getNextObject()) != 0) { //o = iterator->getCurrentElement().mem.obj; o->_setObjectRefFlag(false, ObjectBase::Marked); o->_setObjectRefFlag(false, ObjectBase::Visited); if (o->_isObjectRefFlag(ObjectBase::IsStaticRef) == true || o->_isObjectRefFlag(ObjectBase::IsMemLocked) == true || o->_isObjectRefFlag(ObjectBase::IsStackRef) == true //|| //o->_isObjectRefFlag(ObjectBase::ObjectHasLocalGc) == true ) { markAsExternal(o); } /* if (_lastAddress < o) _lastAddress = o; if (_firstAddress > o) _firstAddress = o; */ ++objectcount; } iterator->reset(); ReferedMap refmap((1 + objectcount) * 3); //HolderMap holdermap(mapsize); FieldReferences fields; // building backward ref while ((o = iterator->getNextObject()) != 0) { o = iterator->getCurrentElement().mem.obj; if (hasColletableFields(o) == false) continue; fields.clear(); o->getCollectableFields(fields); for (int i = 0; i < fields.size(); i++) { if (*fields[i] != Nil) { //DOUT(fields[i]->impl() << " refered by " << o << sys::eofl); refmap.addRefered(fields[i]->impl(), o); refmap.addHolder(fields[i]); //holdermap.add(fields[i]); } } } DOUT("[GC] marking" << sys::eofl); { ReferedMap::iterator it = refmap.begin(); ReferedMap::iterator end = refmap.end(); for (; it != end; ++it) { Object* robj = (*it).first; if (robj->magic() != _MagicObjectSig) continue; if (hasExternalReference(robj, robj, refmap) == true) { //DOUT("MARK: " << (void*)robj); robj->_setObjectRefFlag(true, ObjectBase::Marked); } } } //#endif DOUT("[GC] sweeping" << sys::eofl); RestartSweep: bool wasmodified = true; while (wasmodified == true) { wasmodified = false; ReferedMap::iterator it = refmap.begin(); ReferedMap::iterator end = refmap.end(); for (; it != end; ++it) { Object* obj = (*it).first; if (obj == 0) continue; if (obj->magic() != _MagicObjectSig) continue; //sys::coreout << "o:" << (void*)obj << sys::eofl; try { obj->testIntegrity(); } catch (...) { ACDK_NLOG("acdk.lang.gc", Error, "Object is insane: " + Integer::toHexString((int)(void*)obj)); return false; } if (obj->_isObjectRefFlag(ObjectBase::Marked) == false) { ObjectRefPtrVector& refvec = (*it).second->hold; bool restart = false; for (int i = 0; i < refvec.size(); i++) { RObject* ref = refvec[i]; if (ref == 0 || ref->impl() == 0) continue; if (ref->impl()->magic() != _MagicObjectSig) continue; if (ref->impl() != obj) DOUT(" OOPS " << (void*)ref->impl() << " != " << obj << sys::eofl); if (obj->refCount() == 1) restart = true; DOUT("GC: Free Ref: " << (void*)ref << "; Object: " << (void*)ref->impl() << ", " << ref->impl()->getClazzInfo()->name << sys::eofl); *(ref) = Nil; if (restart == true) { //?? refmap.erase(it); DOUT("[GC] restart" << sys::eofl); goto RestartSweep; } wasmodified = true; } } } } /* int after_gc_elements = _allocator->getElementCount(UnspecifiedMem); int after_gc_memory = _allocator->getAllocatedCount(UnspecifiedMem); */ const AllocatorInfo& ainf = allocator->getAllocatorInfo(); int after_gc_elements = ainf.memTypes[ObjectMem].count; int after_gc_memory = ainf.memTypes[ObjectMem].size; if (after_gc_elements == before_gc_elements) ACDK_NLOG("acdk.lang.gc", SysDebug, "GC released no objects"); else ACDK_NLOGP("acdk.lang.gc", SysDebug, "GC Released objects", LOG_NPV(Elements, before_gc_elements - after_gc_elements) << LOG_NPV(Bytes, before_gc_memory - after_gc_memory)); DOUT("After Sweep" << sys::eofl); //_allocator->dumpStatistics(false); //_allocator->_heap = 0; return after_gc_elements != before_gc_elements; return false; }
void listGcAble(HeapFrame* frame, AllocatorObjectsIterator* iterator, ::acdk::lang::ref::NotifyObjectEventListener* listener, int flags) { Object* o = 0; int objectcount = 0; while ((o = iterator->getNextObject()) != 0) { o->_setObjectRefFlag(false, ObjectBase::Marked); o->_setObjectRefFlag(false, ObjectBase::Visited); if (o->_isObjectRefFlag(ObjectBase::IsStaticRef) == true || o->_isObjectRefFlag(ObjectBase::IsMemLocked) == true || o->_isObjectRefFlag(ObjectBase::IsStackRef) == true //|| //o->_isObjectRefFlag(ObjectBase::ObjectHasLocalGc) == true ) { markAsExternal(o); } ++objectcount; } iterator->reset(); ReferedMap refmap((1 + objectcount) * 3); //HolderMap holdermap(mapsize); FieldReferences fields; // building backward ref while ((o = iterator->getNextObject()) != 0) { o = iterator->getCurrentElement().mem.obj; if (hasColletableFields(o) == false) continue; fields.clear(); o->getCollectableFields(fields); for (int i = 0; i < fields.size(); i++) { if (*fields[i] != Nil) { //DOUT(fields[i]->impl() << " refered by " << o << sys::eofl); refmap.addRefered(fields[i]->impl(), o); refmap.addHolder(fields[i]); //holdermap.add(fields[i]); } } } //DOUT("[GC] marking" << sys::eofl); { ReferedMap::iterator it = refmap.begin(); ReferedMap::iterator end = refmap.end(); for (; it != end; ++it) { Object* robj = (*it).first; if (robj->magic() != _MagicObjectSig) continue; if (hasExternalReference(robj, robj, refmap) == true) { //DOUT("MARK: " << (void*)robj); robj->_setObjectRefFlag(true, ObjectBase::Marked); } } } ReferedMap::iterator it = refmap.begin(); ReferedMap::iterator end = refmap.end(); for (; it != end; ++it) { Object* obj = (*it).first; if (obj == 0) continue; if (obj->magic() != _MagicObjectSig) continue; //sys::coreout << "o:" << (void*)obj << sys::eofl; try { obj->testIntegrity(); } catch (...) { ACDK_NLOG("acdk.lang.gc", Error, "Object is insane: " + Integer::toHexString((int)(void*)obj)); return; } if (obj->_isObjectRefFlag(ObjectBase::Marked) == false) { ObjectRefPtrVector& refvec = (*it).second->hold; bool restart = false; for (int i = 0; i < refvec.size(); i++) { RObject* ref = refvec[i]; if (ref == 0 || ref->impl() == 0) continue; if (ref->impl()->magic() != _MagicObjectSig) continue; //DOUT("GC: Free Ref: " << (void*)ref << "; Object: " << (void*)ref->impl() << ", " << ref->impl()->getClazzInfo()->name << sys::eofl); if (listener->listedAllocated(frame, (*ref).impl(), ObjectMem, 0) == false) return; } } } }
/*************************************************************************** * @brief GSkymap_healpix_io ***************************************************************************/ void TestGSky::test_GSkymap_healpix_io(void) { // Set filenames const std::string file1 = "test_skymap_hpx_1.fits"; // Define Healpix map for comparison GSkymap refmap("GAL", 4, "RING", 1); // Test Healpix map saving test_try("Test Healpix map saving"); try { for (int pix = 0; pix < refmap.npix(); ++pix) refmap(pix) = pix+1; refmap.save(file1, true); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test Healpix map loading test_try("Test Healpix map loading"); try { GSkymap map; map.load(file1); int diff = 0; for (int pix = 0; pix < refmap.npix(); ++pix) { if (map(pix) != refmap(pix)) diff++; } if (diff > 0) { throw exception_error("Loaded file differs from saved file."); } test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test Healpix map instantiation test_try("Test Healpix map instantiation"); try { GSkymap map(file1); int diff = 0; for (int pix = 0; pix < refmap.npix(); ++pix) { if (map(pix) != refmap(pix)) diff++; } if (diff > 0) { throw exception_error("Loaded file differs from saved file."); } test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Exit test return; }