Esempio n. 1
0
void Registry::Delete(Object const &object)
{
#ifdef KAI_DEBUG
	if (IsWatching(object))
		KAI_TRACE() << object.GetHandle();
#endif
	Delete(object.GetHandle());
}
Esempio n. 2
0
Object Registry::GetObject(Handle handle) const
{
#ifdef KAI_DEBUG
	if (IsWatching(handle) && gc_trace_level > 1)
		KAI_TRACE() << handle;
#endif

	if (handle == 0)
		return Object();

	Instances::const_iterator A = instances.find(handle);
	if (A == instances.end())
		return Object();

	return *A->second;
}
Esempio n. 3
0
void Registry::TriColor()
{
	// this is a magic number. the higher it is, the more objects may be deleted in this call
	// the cost has to be paid at some point, so this number really means "how much do I want
	// to spread out cost of GC over time versus memory use".
	//
	// if you have lots of memory, set max_cycles to 1. (or zero!). if not, set it higher
	// until you can fit memory usage into a sequence of frames.
	//
	// see also https://github.com/cschladetsch/Monotonic 
	const int max_cycles = 17;
	if (gc_trace_level >= 1)
	{
		KAI_TRACE_3(instances.size(), grey.size(), white.size());
	}

	int cycle = 0;
	for (; cycle < max_cycles; ++cycle)
	{
#ifdef KAI_DEBUG_REGISTRY
		if (gc_trace_level > 2) 
			TraceTriColor();
#endif

		if (grey.empty())
		{
			ReleaseWhite();
			break;
		}

		ColoredSet::iterator iter = grey.begin();
		Handle handle = *iter;
		grey.erase(iter);
		StorageBase *base = GetStorageBase(handle);
		if (base == 0)
			continue;

		base->MakeReachableGrey();
		base->SetColor(ObjectColor::Black);
	}

	if (gc_trace_level >= 1)
		KAI_TRACE() << "TriColor: " << cycle << " passes";
}
Esempio n. 4
0
void Registry::Delete(Handle handle)
{
#ifdef KAI_USE_TRICOLOR
	// use Object::Delete
	(void)handle;
	throw;
#else

#ifdef KAI_DEBUG
	if (IsObserving(handle))
	{
		KAI_TRACE() << handle;
	}
#endif
	// if unknown handle, do nothing
	Instances::const_iterator instance = instances.find(handle);
	if (instance == instances.end())
		return;		

	// detach from parent
	if (instance->second)
	{
		StorageBase &storage = *instance->second;
		storage.SetColor(ObjectColor::White);
		storage.SetColorRecursive(ObjectColor::White);
		storage.GetClass()->Destroy(storage);
		//Detach(storage);
	}

	// remove from list of retained objects
	auto etained = retained_objects.find(handle);
	if (retained != retained_objects.end())
		retained_objects.erase(retained);

	// mark for pending collection
#ifndef KAI_USE_TRICOLOR
	deathrow.insert(handle);
#endif
#endif
}
Esempio n. 5
0
Object Registry::NewFromClass(const ClassBase *klass)
{
	if (klass == 0)
		KAI_THROW_1(UnknownClass<>, "NULL Class");

	Handle handle = next_handle.NextValue();
	StorageBase *base = 0;
	base = klass->NewStorage(this, handle);

#ifdef KAI_DEBUG_REGISTRY
	if (IsWatchingType(klass->GetTypeNumber()))
		KAI_TRACE() << klass->GetName() << ": " << handle;
#endif

	base->SetColor(ObjectColor::White);
	base->SetMarked(false);

	instances[handle] = base;

	klass->Create(*base);
	return Object(ObjectConstructParams(this, klass, handle));
}
Esempio n. 6
0
void Registry::DestroyObject(Handle handle, bool force)
{
	bool succeeded = false;
	KAI_TRY
	{
		Instances::iterator iter = instances.find(handle);
		if (iter == instances.end())
		{
#ifdef KAI_DEBUG
			if (IsWatching(handle))
			{
				KAI_TRACE() << handle << ": doesn't exist, not deleted";
			}
#endif
			return;
		}

		StorageBase &base = *iter->second;
		assert(base.GetHandle() == handle);
		if (!base.IsManaged() && !force)
		{
#ifdef KAI_DEBUG
			if (IsWatching(handle))
				KAI_TRACE() << handle << ": " << base << " is not managed, not deleted";
#endif
			return;
		}

#ifdef KAI_DEBUG
		bool trace = gc_trace_level > 3;
		trace = trace || IsWatching(base);
		if (trace)
		{
			KAI_TRY
			{
				KAI_TRACE() << handle;
			}
			KAI_CATCH_ALL()
			{
			}
		}
#endif

#ifdef KAI_USE_TRICOLOR
		// when using tri-color GC, objects are always deleted when they are destroyed
		if (!base.GetClass()->Destroy(base) && !force)
		{
			base.SetColor(ObjectColor::Grey);
			return;
		}
#endif
		base.GetClass()->Delete(base);
		instances.erase(iter);

		RetainedObjects::iterator retained = retained_objects.find(handle);
		if (retained != retained_objects.end())
		{
			retained_objects.erase(retained);
		}

		succeeded = true;
	}
	KAI_CATCH(Exception::Base, E)
	{
		KAI_TRACE() << "\n\t" << E.ToString();
	}
	KAI_CATCH(std::exception, E)
	{
		KAI_TRACE() << "std::exception: " << E.what();
	}
	KAI_CATCH_ALL()
	{
	}

	if (!succeeded)
	{
		KAI_TRACE() << "*** AWESOMELY BAD EXCEPTION deleting object ***";
		Instances::iterator iter = instances.find(handle);
		if (iter != instances.end())
		{
			// this leaks and has other *TERRIBLE* consequences but it is the best we can do to keep afloat
			instances.erase(iter);
		}
	}
}
Esempio n. 7
0
 KAI_CATCH(std::exception, E)
 {
     KAI_UNUSED(E);
     KAI_TRACE() << "std::exception: " << E.what();
 }
Esempio n. 8
0
void Registry::DestroyObject(Handle handle, bool force)
{
    bool succeeded = false;
    KAI_TRY
    {
        Instances::iterator iter = instances.find(handle);
        if (iter == instances.end())
        {
#ifdef KAI_DEBUG_REGISTRY
            if (IsWatching(handle))
            {
                KAI_TRACE() << handle << ": doesn't exist, not deleted";
            }
#endif
            return;
        }

        StorageBase &base = *iter->second;
        assert(base.GetHandle() == handle);
        if (!base.IsManaged() && !force)
        {
#ifdef KAI_DEBUG_REGISTRY
            if (IsWatching(handle))
                KAI_TRACE() << handle << ": " << base << " is not managed, not deleted";
#endif
            return;
        }

#ifdef KAI_DEBUG_REGISTRY
        bool trace = gc_trace_level > 3;
        trace = trace || IsWatching(base);
        if (trace)
        {
            KAI_TRY
            {
                KAI_TRACE() << handle;
            }
            KAI_CATCH_ALL()
            {
            }
        }
#endif

#ifdef KAI_USE_TRICOLOR
        // when using tri-color GC, objects are always deleted when they are destroyed
        if (!base.GetClass()->Destroy(base) && !force)
        {
            base.SetColor(ObjectColor::Grey);
            return;
        }
#endif
        base.GetClass()->Delete(base);
        instances.erase(iter);

        RetainedObjects::iterator retained = retained_objects.find(handle);
        if (retained != retained_objects.end())
        {
            retained_objects.erase(retained);
        }

        succeeded = true;
    }
    KAI_CATCH(Exception::Base, E)
    {
        KAI_UNUSED(E);
        KAI_TRACE() << "\n\t" << E.ToString();
    }