#include "config.h"
#include "PropertyMapHashTable.h"
#include "JSCJSValueInlines.h"
#include "JSCellInlines.h"
#include "SlotVisitorInlines.h"
#include "StructureInlines.h"
#include <wtf/CryptographicallyRandomNumber.h>
namespace JSC {
const ClassInfo PropertyTable::s_info = { "PropertyTable", 0, 0, 0, CREATE_METHOD_TABLE(PropertyTable) };
PropertyTable* PropertyTable::create(VM& vm, unsigned initialCapacity)
{
PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, initialCapacity);
table->finishCreation(vm);
return table;
}
PropertyTable* PropertyTable::clone(VM& vm, const PropertyTable& other)
{
PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, other);
table->finishCreation(vm);
return table;
}
PropertyTable* PropertyTable::clone(VM& vm, unsigned initialCapacity, const PropertyTable& other)
{
PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, initialCapacity, other);
table->finishCreation(vm);
return table;
}
PropertyTable::PropertyTable(VM& vm, unsigned initialCapacity)
: JSCell(vm, vm.propertyTableStructure.get())
, m_indexSize(sizeForCapacity(initialCapacity))
, m_indexMask(m_indexSize - 1)
, m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
, m_keyCount(0)
, m_deletedCount(0)
{
ASSERT(isPowerOf2(m_indexSize));
}
PropertyTable::PropertyTable(VM& vm, const PropertyTable& other)
: JSCell(vm, vm.propertyTableStructure.get())
, m_indexSize(other.m_indexSize)
, m_indexMask(other.m_indexMask)
, m_index(static_cast<unsigned*>(fastMalloc(dataSize())))
, m_keyCount(other.m_keyCount)
, m_deletedCount(other.m_deletedCount)
{
ASSERT(isPowerOf2(m_indexSize));
memcpy(m_index, other.m_index, dataSize());
iterator end = this->end();
for (iterator iter = begin(); iter != end; ++iter) {
iter->key->ref();
vm.heap.writeBarrier(this, iter->specificValue.get());
}
Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
if (otherDeletedOffsets)
m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
}
PropertyTable::PropertyTable(VM& vm, unsigned initialCapacity, const PropertyTable& other)
: JSCell(vm, vm.propertyTableStructure.get())
, m_indexSize(sizeForCapacity(initialCapacity))
, m_indexMask(m_indexSize - 1)
, m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
, m_keyCount(0)
, m_deletedCount(0)
{
ASSERT(isPowerOf2(m_indexSize));
ASSERT(initialCapacity >= other.m_keyCount);
const_iterator end = other.end();
for (const_iterator iter = other.begin(); iter != end; ++iter) {
ASSERT(canInsert());
reinsert(*iter);
iter->key->ref();
vm.heap.writeBarrier(this, iter->specificValue.get());
}
Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
if (otherDeletedOffsets)
m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
}
void PropertyTable::destroy(JSCell* cell)
{
static_cast<PropertyTable*>(cell)->PropertyTable::~PropertyTable();
}
PropertyTable::~PropertyTable()
{
iterator end = this->end();
for (iterator iter = begin(); iter != end; ++iter)
iter->key->deref();
fastFree(m_index);
}
void PropertyTable::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
PropertyTable* thisObject = jsCast<PropertyTable*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
JSCell::visitChildren(thisObject, visitor);
PropertyTable::iterator end = thisObject->end();
for (PropertyTable::iterator ptr = thisObject->begin(); ptr != end; ++ptr)
visitor.append(&ptr->specificValue);
}
}