Files
avmplus/core/Domain.cpp
T
dmcallis 65a0592776 Initial source code drop
Source code drop for the Actionscript virtual machine in the Adobe
Flash Player for December 2013
2013-12-02 16:04:04 -08:00

97 lines
3.7 KiB
C++

/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "avmplus.h"
namespace avmplus
{
Domain::Domain(AvmCore* core, Domain* base, uint32_t baseCount)
: m_loadedTraits(MultinameTraitsHashtable::create(core->GetGC()))
, m_cachedTraits(MultinameTraitsHashtable::create(core->GetGC()))
, m_loadedScripts(MultinameMethodInfoHashtable::create(core->GetGC()))
, m_cachedScripts(MultinameMethodInfoHashtable::create(core->GetGC()))
, m_parameterizedTypes(WeakKeyHashtable::create(core->GetGC()))
, m_baseCount(baseCount)
{
WB(core->GetGC(), this, &m_bases[0], this);
for (uint32_t i = 1; i < baseCount; ++i)
{
WB(core->GetGC(), this, &this->m_bases[i], base->m_bases[i-1]);
}
}
Domain* Domain::newDomain(AvmCore* core, Domain* base)
{
uint32_t baseCount = (base ? base->m_baseCount : 0) + 1;
// Note that we deliberately overallocate by one here (the proper
// amount is baseCount-1) so that we always have one, zeroed-out
// entry at the end. This allows us to always use "m_bases[1]"
// to get our immediate base, even if our base is NULL, thus
// avoiding a check in the implementation of base().
uint32_t extra = baseCount * sizeof(Domain*);
return new (core->GetGC(), MMgc::kExact, extra) Domain(core, base, baseCount);
}
ClassClosure* Domain::getParameterizedType(ClassClosure* type)
{
ClassClosure* result = NULL;
AvmAssert(type != NULL);
if (type)
{
Atom value = m_parameterizedTypes->get(type->atom());
if (AvmCore::isGenericObject(value))
{
MMgc::GCWeakRef* wr = (MMgc::GCWeakRef*)AvmCore::atomToGenericObject(value);
if (wr)
{
result = (ClassClosure*)wr->get();
}
}
}
return result;
}
bool Domain::isParameterizedTypePresent(ClassClosure* type)
{
bool result = false;
if (type)
{
Atom value = m_parameterizedTypes->get(type->atom());
if (AvmCore::isGenericObject(value))
{
MMgc::GCWeakRef* wr = (MMgc::GCWeakRef*)AvmCore::atomToGenericObject(value);
if (wr)
{
result = !(wr->isNull());
}
}
}
return result;
}
void Domain::addParameterizedType(ClassClosure* type, ClassClosure* parameterizedType)
{
AvmAssert(type && parameterizedType);
if (type && parameterizedType)
{
AvmAssert(!isParameterizedTypePresent(type));
// Note that what we really need here is fixing the problems with our weak tables.
// If there exists a cycle in the weak table ('value' indirectly pointing to the weak 'key'),
// the weak key will not get collected even if there are no references to
// it from elsewhere and hence the table entry will not be deleted, which
// will in turn lead to value not getting collected.
//
// As a short term fix, we'll just use WeakKeyHashtable with explicit GCWeakRef usage
// for the value.
MMgc::GCWeakRef* wr = parameterizedType ? parameterizedType->GetWeakRef() : NULL;
m_parameterizedTypes->add(type->atom(), AvmCore::genericObjectToAtom(wr));
}
}
}