コード例 #1
0
ファイル: Registry.cpp プロジェクト: kalineh/KAI
void MarkObject(StorageBase &Q, bool M)
{
	if (M == Q.IsMarked())
		return;

	Q.SetMarked(M);
	Q.GetClass()->SetMarked(Q, M);
}
コード例 #2
0
ファイル: Registry.cpp プロジェクト: kalineh/KAI
void MarkObjectAndChildren(StorageBase &Q, bool M)
{
	MarkObject(Q, M);
	Dictionary::const_iterator A = Q.GetDictionary().begin(), B = Q.GetDictionary().end();
	for (; A != B; ++A)
	{
		Object &child = const_cast<Object &>(A->second);
		if (child.GetHandle() == Q.GetHandle())	// HACK to sorta/kinda avoid cycles :/
			continue;

		MarkObjectAndChildren(child, M);
	}
}
コード例 #3
0
ファイル: StorageBase.cpp プロジェクト: cschladetsch/KAI
void StorageBase::RemovedFromContainer(Object const &container)
{
    ObjectColor::Color color = ObjectColor::White;
    StorageBase *parent = GetRegistry()->GetStorageBase(GetParentHandle());
    bool parent_is_black = parent && parent->IsBlack();
    if (parent_is_black)
        color = ObjectColor::Grey;
    
    bool removed = false;
    auto iter = containers.begin(), end = containers.end();
    for (; iter != end; )
    {
        StorageBase *base = GetRegistry()->GetStorageBase(*iter);
        if (!base)
        {
            iter = containers.erase(iter);
            continue;
        }

        if (!removed && *iter == container.GetHandle())
        {
            iter = containers.erase(iter);
            removed = true;
            if (parent_is_black)
            {
                // if removed from container and parent is black early out
                break;
            }
            else
            {
                // we need to check for other black parents to enforce the TriColor invariant
                continue;
            }
        }

        if (base->IsBlack())
        {
            color = ObjectColor::Grey;
            parent_is_black = true;
            // if any parent container is black, and we have already removed from the
            // given container, we can early out
            if (removed)
                break;
        }

        ++iter;
    }

    SetColorRecursive(color);
}
コード例 #4
0
ファイル: StorageBase.cpp プロジェクト: cschladetsch/KAI
void StorageBase::MakeReachableGrey()
{
    Dictionary::const_iterator child = dictionary.begin(), end = dictionary.end();
    for (; child != end; ++child)
    {
        StorageBase *sub = GetRegistry()->GetStorageBase(child->second.GetHandle());
        if (!sub)
            continue;

        if (sub->IsWhite())
            sub->SetColor(ObjectColor::Grey);
    }

    GetClass()->MakeReachableGrey(*this);
}
コード例 #5
0
ファイル: StorageBase.cpp プロジェクト: cschladetsch/KAI
void StorageBase::DetachFromContainers()
{
    if (containers.empty())
        return;

    Containers tmp = containers;
    Containers::const_iterator iter = tmp.begin(), end = tmp.end();
    for (; iter != end; ++iter)
    {
        StorageBase *cont = GetRegistry()->GetStorageBase(*iter);
        if (!cont)
            continue;

        cont->GetClass()->DetachFromContainer(*cont, *this);
    }
}
コード例 #6
0
ファイル: StorageBase.cpp プロジェクト: cschladetsch/KAI
void StorageBase::Remove(const Label &label)
{
    Dictionary::iterator iter = dictionary.find(label);
    if (iter == dictionary.end())
        return;

    SetDirty();
    StorageBase *child = iter->second.GetBasePtr();
    dictionary.erase(iter);

    if (child)
    {
        child->SetParentHandle(Handle());
        child->RemovedFromContainer(*this);
    }
}
コード例 #7
0
ファイル: Registry.cpp プロジェクト: kalineh/KAI
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";
}
コード例 #8
0
ファイル: StorageBase.cpp プロジェクト: cschladetsch/KAI
void StorageBase::Delete()
{
    // avoid double deletion
    if (IsMarked())
        return;

    SetManaged(true);

    // remove from all containers
    DetachFromContainers();

    // remove from parent
    StorageBase *parent = GetParentBasePtr();
    if (parent != 0)
        parent->Remove(GetLabel());

    // set this and all referent objects to be white, and mark it for deletion.
    SetColorRecursive(ObjectColor::White);
    SetMarked(true);
}
コード例 #9
0
ファイル: StorageBase.cpp プロジェクト: cschladetsch/KAI
bool StorageBase::SetColor(ObjectColor::Color color)
{
    auto reg = GetRegistry();
    if (!reg->SetColor(*this, color))
        return false;

    this->color = color;
    if (color == ObjectColor::White)
    {
        Containers::const_iterator container = containers.begin(), end = containers.end();
        for (; container != end; ++container)
        {
            StorageBase *cont = GetRegistry()->GetStorageBase(*container);
            if (cont && cont->IsBlack())
                cont->SetColor(ObjectColor::Grey);
        }
    }

    return true;
}
コード例 #10
0
ファイル: Registry.cpp プロジェクト: kalineh/KAI
void Registry::MarkAll(StorageBase &root, bool marked)
{
	MarkObject(root, marked);
	const Dictionary &dict = root.GetDictionary();
	Dictionary::const_iterator C = dict.begin(), D = dict.end();
	for (; C != D; ++C)
	{
		Object const &child = C->second;
		StorageBase *base = GetStorageBase(child.GetHandle());
		if (base == 0)
			continue;

		if (base->IsManaged())
			MarkObject(*base, marked);

		if (base->GetSwitches() & IObject::NoRecurse)
			continue;

		MarkAll(*base, marked);
	}
}
コード例 #11
0
ファイル: Registry.cpp プロジェクト: kalineh/KAI
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));
}
コード例 #12
0
ファイル: Tree.cpp プロジェクト: kalineh/KAI
Pathname GetFullname(const StorageBase &Q)
{
	nstd::list<String> parentage;
	Label const &label = Q.GetLabel();
	if (!label.ToString().empty())
		parentage.push_back(label.ToString());

	Object parent = Q.GetParent();
	for (; parent.Valid(); parent = parent.GetParent())
		parentage.push_front(GetStorageBase(parent).GetLabel().ToString());

	StringStream path;
	if (!parentage.empty())
		;//path << "[anon]";
	else
		path.Append('/');

	foreach (String const &name, parentage)
	{
		path.Append(name);
		path.Append('/');
	}
コード例 #13
0
ファイル: Registry.cpp プロジェクト: kalineh/KAI
void Registry::Sweep()
{
	if (instances.empty())
		return;

	Instances::iterator A = instances.begin(), B = instances.end();
	// the handle of the next object created
	Handle last = next_handle.GetValue();
	for (; A != B; ++A)
	{
		StorageBase *base = A->second;
		// do not consider objects that were created during this loop!
		if (last < base->GetHandle())
			continue;

		if (!base->IsManaged())
			continue;

		if (!base->IsMarked())
			Delete(A->first);
		else 
			base->SetMarked(false);
	}
}
コード例 #14
0
ファイル: StorageBase.cpp プロジェクト: cschladetsch/KAI
// avoid loops by passing history of objects traversed via handles argument
void StorageBase::SetColorRecursive(ObjectColor::Color color, HandleSet& handles)
{
    Handle handle = GetHandle();
    if (handles.find(handle) != handles.end())
        return;

    handles.insert(handle);

    if (!SetColor(color))
        return;

    GetClass()->SetReferencedObjectsColor(*this, color, handles);
    if (dictionary.empty())
        return;

    for (Dictionary::value_type const &child : dictionary)
    {
        StorageBase *sub = GetRegistry()->GetStorageBase(child.second.GetHandle());
        if (!sub)
            continue;

        sub->SetColorRecursive(color, handles);
    }
}