SharedVariant::~SharedVariant() { switch (m_type) { case KindOfObject: if (getIsObj()) { delete m_data.obj; break; } // otherwise fall through case KindOfString: m_data.str->destruct(); break; case KindOfArray: { if (getSerializedArray()) { m_data.str->destruct(); break; } if (isPacked()) { delete m_data.packed; } else { ImmutableArray::Destroy(m_data.array); } } break; default: break; } }
int32_t SharedVariant::getSpaceUsage() const { int32_t size = sizeof(SharedVariant); if (!IS_REFCOUNTED_TYPE(m_type)) return size; switch (m_type) { case KindOfObject: if (getIsObj()) { return size + m_data.obj->getSpaceUsage(); } // fall through case KindOfString: size += sizeof(StringData) + m_data.str->size(); break; default: assert(is(KindOfArray)); if (getSerializedArray()) { size += sizeof(StringData) + m_data.str->size(); } else if (isPacked()) { auto size = m_data.packed->size(); size += sizeof(ImmutablePackedArray) + size * sizeof(SharedVariant*); for (size_t i = 0, n = m_data.packed->size(); i < n; i++) { size += m_data.packed->vals()[i]->getSpaceUsage(); } } else { auto array = m_data.array; size += array->getStructSize(); for (size_t i = 0, n = array->size(); i < n; i++) { size += array->getKeyIndex(i)->getSpaceUsage(); size += array->getValIndex(i)->getSpaceUsage(); } } break; } return size; }
SharedVariant::~SharedVariant() { switch (m_type) { case KindOfObject: if (getIsObj()) { delete m_data.obj; break; } // otherwise fall through case KindOfString: m_data.str->destruct(); break; case KindOfArray: { if (getSerializedArray()) { m_data.str->destruct(); break; } if (getIsVector()) { delete m_data.vec; } else { delete m_data.map; } } break; default: break; } }
int32 SharedVariant::getSpaceUsage() { int32 size = sizeof(SharedVariant); if (!IS_REFCOUNTED_TYPE(m_type)) return size; switch (m_type) { case KindOfObject: if (getIsObj()) { return size + m_data.obj->getSpaceUsage(); } // fall through case KindOfString: size += sizeof(StringData) + m_data.str->size(); break; default: ASSERT(is(KindOfArray)); if (getSerializedArray()) { size += sizeof(StringData) + m_data.str->size(); } else if (getIsVector()) { size += sizeof(VectorData) + sizeof(SharedVariant*) * m_data.vec->size; for (size_t i = 0; i < m_data.vec->size; i++) { size += m_data.vec->vals[i]->getSpaceUsage(); } } else { ImmutableMap *map = m_data.map; size += map->getStructSize(); for (int i = 0; i < map->size(); i++) { size += map->getKeyIndex(i)->getSpaceUsage(); size += map->getValIndex(i)->getSpaceUsage(); } } break; } return size; }
void SharedVariant::getStats(SharedVariantStats *stats) const { stats->initStats(); stats->variantCount = 1; switch (m_type) { case KindOfUninit: case KindOfNull: case KindOfBoolean: case KindOfInt64: case KindOfDouble: case KindOfStaticString: stats->dataSize = sizeof(m_data.dbl); stats->dataTotalSize = sizeof(SharedVariant); break; case KindOfObject: if (getIsObj()) { SharedVariantStats childStats; m_data.obj->getSizeStats(&childStats); stats->addChildStats(&childStats); break; } // fall through case KindOfString: stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(SharedVariant) + sizeof(StringData) + stats->dataSize; break; default: assert(is(KindOfArray)); if (getSerializedArray()) { stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(SharedVariant) + sizeof(StringData) + stats->dataSize; break; } if (isPacked()) { stats->dataTotalSize = sizeof(SharedVariant) + sizeof(ImmutablePackedArray); auto size = m_data.packed->size(); stats->dataTotalSize += sizeof(SharedVariant*) * size; for (size_t i = 0; i < size; i++) { SharedVariant *v = m_data.packed->vals()[i]; SharedVariantStats childStats; v->getStats(&childStats); stats->addChildStats(&childStats); } } else { auto array = m_data.array; stats->dataTotalSize = sizeof(SharedVariant) + array->getStructSize(); for (size_t i = 0, n = array->size(); i < n; i++) { SharedVariantStats childStats; array->getKeyIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); array->getValIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); } } break; } }
void SharedVariant::getStats(SharedVariantStats *stats) const { stats->initStats(); stats->variantCount = 1; switch (m_type) { case KindOfUninit: case KindOfNull: case KindOfBoolean: case KindOfInt64: case KindOfDouble: case KindOfStaticString: stats->dataSize = sizeof(m_data.dbl); stats->dataTotalSize = sizeof(SharedVariant); break; case KindOfObject: if (getIsObj()) { SharedVariantStats childStats; m_data.obj->getSizeStats(&childStats); stats->addChildStats(&childStats); break; } // fall through case KindOfString: stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(SharedVariant) + sizeof(StringData) + stats->dataSize; break; default: assert(is(KindOfArray)); if (getSerializedArray()) { stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(SharedVariant) + sizeof(StringData) + stats->dataSize; break; } if (getIsVector()) { stats->dataTotalSize = sizeof(SharedVariant) + sizeof(VectorData); stats->dataTotalSize += sizeof(SharedVariant*) * m_data.vec->m_size; for (size_t i = 0; i < m_data.vec->m_size; i++) { SharedVariant *v = m_data.vec->vals()[i]; SharedVariantStats childStats; v->getStats(&childStats); stats->addChildStats(&childStats); } } else { ImmutableMap *map = m_data.map; stats->dataTotalSize = sizeof(SharedVariant) + map->getStructSize(); for (int i = 0; i < map->size(); i++) { SharedVariantStats childStats; map->getKeyIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); map->getValIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); } } break; } }
HOT_FUNC Variant SharedVariant::toLocal() { switch (m_type) { case KindOfBoolean: { return (bool)m_data.num; } case KindOfInt64: { return m_data.num; } case KindOfDouble: { return m_data.dbl; } case KindOfStaticString: { return m_data.str; } case KindOfString: { return NEW(StringData)(this); } case KindOfArray: { if (getSerializedArray()) { return apc_unserialize(String(m_data.str->data(), m_data.str->size(), AttachLiteral)); } return NEW(SharedMap)(this); } case KindOfUninit: case KindOfNull: { return null_variant; } default: { assert(m_type == KindOfObject); if (getIsObj()) { return m_data.obj->getObject(); } return apc_unserialize(String(m_data.str->data(), m_data.str->size(), AttachLiteral)); } } }
int32 ThreadSharedVariant::getSpaceUsage() { int32 size = sizeof(ThreadSharedVariant); if (m_type <= KindOfDouble) return size; switch (m_type) { case KindOfObject: if (getIsObj()) { return size + m_data.obj->getSpaceUsage(); } // fall through case KindOfString: if (m_data.str->isStatic()) { break; } size += sizeof(StringData) + m_data.str->size(); break; default: ASSERT(is(KindOfArray)); if (getSerializedArray()) { size += sizeof(StringData) + m_data.str->size(); } else if (getIsVector()) { size += sizeof(VectorData) + sizeof(ThreadSharedVariant*) * m_data.vec->size; for (size_t i = 0; i < m_data.vec->size; i++) { size += m_data.vec->vals[i]->getSpaceUsage(); } } else if (RuntimeOption::ApcUseGnuMap) { // Not accurate size += sizeof(MapData); } else { ImmutableMap *map = m_data.map; size += map->getStructSize(); for (int i = 0; i < map->size(); i++) { size += map->getKeyIndex(i)->getSpaceUsage(); size += map->getValIndex(i)->getSpaceUsage(); } } break; } return size; }
ThreadSharedVariant::~ThreadSharedVariant() { switch (m_type) { case KindOfObject: if (getIsObj()) { delete m_data.obj; break; } // otherwise fall through case KindOfString: if (getOwner()) { m_data.str->destruct(); } break; case KindOfArray: { if (getSerializedArray()) { if (getOwner()) { m_data.str->destruct(); } break; } ASSERT(getOwner()); if (getIsVector()) { delete m_data.vec; } else if (RuntimeOption::ApcUseGnuMap) { delete m_data.gnuMap; } else { delete m_data.map; } } break; default: break; } }
void ThreadSharedVariant::getStats(SharedVariantStats *stats) { stats->initStats(); stats->variantCount = 1; switch (m_type) { case KindOfNull: case KindOfBoolean: case KindOfInt64: case KindOfDouble: stats->dataSize = sizeof(m_data.dbl); stats->dataTotalSize = sizeof(ThreadSharedVariant); break; case KindOfObject: if (getIsObj()) { SharedVariantStats childStats; m_data.obj->getSizeStats(&childStats); stats->addChildStats(&childStats); break; } // fall through case KindOfString: if (m_data.str->isStatic()) { stats->dataSize = 0; stats->dataTotalSize = sizeof(ThreadSharedVariant); break; } stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(ThreadSharedVariant) + sizeof(StringData) + stats->dataSize; break; default: ASSERT(is(KindOfArray)); if (getSerializedArray()) { stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(ThreadSharedVariant) + sizeof(StringData) + stats->dataSize; break; } if (getIsVector()) { stats->dataTotalSize = sizeof(ThreadSharedVariant) + sizeof(VectorData); stats->dataTotalSize += sizeof(ThreadSharedVariant*) * m_data.vec->size; for (size_t i = 0; i < m_data.vec->size; i++) { ThreadSharedVariant *v = m_data.vec->vals[i]; SharedVariantStats childStats; v->getStats(&childStats); stats->addChildStats(&childStats); } } else if (RuntimeOption::ApcUseGnuMap) { // There is no way to calculate this accurately, and this should be only // used if ImmutableMap is seriously broken, when profiling is less // important. Just not do basic thing here: stats->dataTotalSize = sizeof(MapData); } else { ImmutableMap *map = m_data.map; stats->dataTotalSize = sizeof(ThreadSharedVariant) + map->getStructSize(); for (int i = 0; i < map->size(); i++) { SharedVariantStats childStats; map->getKeyIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); map->getValIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); } } break; } }