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;
      }
    }
  }
}
示例#3
0
/***************************************************************************
 * @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;
}