[K/N] Optimize finalizing of simple extra objects
There is no need to delay ExtraObject deletion when it doesn't have associated object. We can just remove it while iterating on them.
This commit is contained in:
@@ -71,9 +71,16 @@ void SweepExtraObjects(typename Traits::ExtraObjectsFactory& objectFactory) noex
|
|||||||
auto &extraObject = *it;
|
auto &extraObject = *it;
|
||||||
if (!Traits::IsMarkedByExtraObject(extraObject)) {
|
if (!Traits::IsMarkedByExtraObject(extraObject)) {
|
||||||
extraObject.ClearWeakReferenceCounter();
|
extraObject.ClearWeakReferenceCounter();
|
||||||
extraObject.DetachAssociatedObject();
|
if (extraObject.HasAssociatedObject()) {
|
||||||
|
extraObject.DetachAssociatedObject();
|
||||||
|
++it;
|
||||||
|
} else {
|
||||||
|
extraObject.Uninstall();
|
||||||
|
objectFactory.EraseAndAdvance(it);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public:
|
|||||||
auto& extraObjectData = mm::ExtraObjectData::GetOrInstall(GetObjHeader());
|
auto& extraObjectData = mm::ExtraObjectData::GetOrInstall(GetObjHeader());
|
||||||
auto *setCounter = extraObjectData.GetOrSetWeakReferenceCounter(GetObjHeader(), counter.GetObjHeader());
|
auto *setCounter = extraObjectData.GetOrSetWeakReferenceCounter(GetObjHeader(), counter.GetObjHeader());
|
||||||
EXPECT_EQ(setCounter, counter.GetObjHeader());
|
EXPECT_EQ(setCounter, counter.GetObjHeader());
|
||||||
|
EXPECT_EQ(extraObjectData.GetBaseObject(), GetObjHeader());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -340,6 +341,7 @@ TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleCharArrayWithExtraData) {
|
|||||||
TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleObjectWithWeakCounter) {
|
TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleObjectWithWeakCounter) {
|
||||||
Object weakCounter;
|
Object weakCounter;
|
||||||
Object object;
|
Object object;
|
||||||
|
weakCounter->field1 = object.header();
|
||||||
object.InstallWeakCounter(weakCounter);
|
object.InstallWeakCounter(weakCounter);
|
||||||
|
|
||||||
auto stats = Mark({object});
|
auto stats = Mark({object});
|
||||||
@@ -352,6 +354,7 @@ TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleObjectWithWeakCounter) {
|
|||||||
TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleObjectArrayWithWeakCounter) {
|
TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleObjectArrayWithWeakCounter) {
|
||||||
Object weakCounter;
|
Object weakCounter;
|
||||||
ObjectArray array;
|
ObjectArray array;
|
||||||
|
weakCounter->field1 = array.header();
|
||||||
array.InstallWeakCounter(weakCounter);
|
array.InstallWeakCounter(weakCounter);
|
||||||
|
|
||||||
auto stats = Mark({array});
|
auto stats = Mark({array});
|
||||||
@@ -364,6 +367,7 @@ TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleObjectArrayWithWeakCounter) {
|
|||||||
TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleCharArrayWithWeakCounter) {
|
TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleCharArrayWithWeakCounter) {
|
||||||
Object weakCounter;
|
Object weakCounter;
|
||||||
CharArray array;
|
CharArray array;
|
||||||
|
weakCounter->field1 = array.header();
|
||||||
array.InstallWeakCounter(weakCounter);
|
array.InstallWeakCounter(weakCounter);
|
||||||
|
|
||||||
auto stats = Mark({array});
|
auto stats = Mark({array});
|
||||||
@@ -377,6 +381,7 @@ TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleObjectWithInvalidFieldsWithWeakCount
|
|||||||
Object weakCounter;
|
Object weakCounter;
|
||||||
Object object;
|
Object object;
|
||||||
object->field1 = kInitializingSingleton;
|
object->field1 = kInitializingSingleton;
|
||||||
|
weakCounter->field1 = object.header();
|
||||||
object.InstallWeakCounter(weakCounter);
|
object.InstallWeakCounter(weakCounter);
|
||||||
|
|
||||||
auto stats = Mark({object});
|
auto stats = Mark({object});
|
||||||
@@ -390,6 +395,7 @@ TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleObjectArrayWithInvalidFieldsWithWeak
|
|||||||
Object weakCounter;
|
Object weakCounter;
|
||||||
ObjectArray array;
|
ObjectArray array;
|
||||||
array.elements()[0] = kInitializingSingleton;
|
array.elements()[0] = kInitializingSingleton;
|
||||||
|
weakCounter->field1 = array.header();
|
||||||
array.InstallWeakCounter(weakCounter);
|
array.InstallWeakCounter(weakCounter);
|
||||||
|
|
||||||
auto stats = Mark({array});
|
auto stats = Mark({array});
|
||||||
@@ -405,6 +411,7 @@ TEST_F(MarkAndSweepUtilsMarkTest, MarkSingleCharArrayWithSomeDataWithWeakCounter
|
|||||||
array.elements()[0] = 'a';
|
array.elements()[0] = 'a';
|
||||||
array.elements()[1] = 'b';
|
array.elements()[1] = 'b';
|
||||||
array.elements()[2] = 'c';
|
array.elements()[2] = 'c';
|
||||||
|
weakCounter->field1 = array.header();
|
||||||
array.InstallWeakCounter(weakCounter);
|
array.InstallWeakCounter(weakCounter);
|
||||||
|
|
||||||
auto stats = Mark({array});
|
auto stats = Mark({array});
|
||||||
|
|||||||
@@ -177,8 +177,7 @@ public:
|
|||||||
~MarkAndSweepUtilsSweepTest() override {
|
~MarkAndSweepUtilsSweepTest() override {
|
||||||
auto deallocExtraObject = [this](ObjHeader* obj) {
|
auto deallocExtraObject = [this](ObjHeader* obj) {
|
||||||
auto *extraObject = mm::ExtraObjectData::Get(obj);
|
auto *extraObject = mm::ExtraObjectData::Get(obj);
|
||||||
EXPECT_NE(extraObject, nullptr);
|
extraObject->Uninstall();
|
||||||
obj->typeInfoOrMeta_ = const_cast<TypeInfo*>(obj->type_info());
|
|
||||||
extraObjectFactory_.DestroyExtraObjectData(extraObjectFactoryThreadQueue_, *extraObject);
|
extraObjectFactory_.DestroyExtraObjectData(extraObjectFactoryThreadQueue_, *extraObject);
|
||||||
extraObjectFactoryThreadQueue_.Publish();
|
extraObjectFactoryThreadQueue_.Publish();
|
||||||
};
|
};
|
||||||
@@ -223,6 +222,14 @@ public:
|
|||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KStdVector<mm::ExtraObjectData*> AliveExtraObjects() {
|
||||||
|
KStdVector<mm::ExtraObjectData*> objects;
|
||||||
|
for (auto &node : extraObjectFactory_.LockForIter()) {
|
||||||
|
objects.push_back(&node);
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
Object& AllocateObject(const TypeInfo* typeInfo = typeHolder.typeInfo()) {
|
Object& AllocateObject(const TypeInfo* typeInfo = typeHolder.typeInfo()) {
|
||||||
auto* object = objectFactoryThreadQueue_.CreateObject(typeInfo);
|
auto* object = objectFactoryThreadQueue_.CreateObject(typeInfo);
|
||||||
objectFactoryThreadQueue_.Publish();
|
objectFactoryThreadQueue_.Publish();
|
||||||
@@ -357,9 +364,9 @@ TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleObjectWithExtraData) {
|
|||||||
|
|
||||||
auto finalizers = Sweep();
|
auto finalizers = Sweep();
|
||||||
|
|
||||||
EXPECT_THAT(finalizers, testing::UnorderedElementsAre(object.header()));
|
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(object.state(), GC::ObjectData::State::kUnmarked);
|
EXPECT_THAT(AliveExtraObjects(), testing::UnorderedElementsAre());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleObjectArrayWithExtraData) {
|
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleObjectArrayWithExtraData) {
|
||||||
@@ -369,9 +376,9 @@ TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleObjectArrayWithExtraData) {
|
|||||||
|
|
||||||
auto finalizers = Sweep();
|
auto finalizers = Sweep();
|
||||||
|
|
||||||
EXPECT_THAT(finalizers, testing::UnorderedElementsAre(array.header()));
|
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(array.state(), GC::ObjectData::State::kUnmarked);
|
EXPECT_THAT(AliveExtraObjects(), testing::UnorderedElementsAre());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleCharArrayWithExtraData) {
|
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleCharArrayWithExtraData) {
|
||||||
@@ -381,14 +388,14 @@ TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleCharArrayWithExtraData) {
|
|||||||
|
|
||||||
auto finalizers = Sweep();
|
auto finalizers = Sweep();
|
||||||
|
|
||||||
EXPECT_THAT(finalizers, testing::UnorderedElementsAre(array.header()));
|
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(array.state(), GC::ObjectData::State::kUnmarked);
|
EXPECT_THAT(AliveExtraObjects(), testing::UnorderedElementsAre());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleMarkedObjectWithExtraData) {
|
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleMarkedObjectWithExtraData) {
|
||||||
auto& object = AllocateObject();
|
auto& object = AllocateObject();
|
||||||
InstallExtraData(object.header());
|
auto& extra = InstallExtraData(object.header());
|
||||||
object.Mark();
|
object.Mark();
|
||||||
ASSERT_THAT(Alive(), testing::UnorderedElementsAre(object.header()));
|
ASSERT_THAT(Alive(), testing::UnorderedElementsAre(object.header()));
|
||||||
|
|
||||||
@@ -396,12 +403,12 @@ TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleMarkedObjectWithExtraData) {
|
|||||||
|
|
||||||
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(Alive(), testing::UnorderedElementsAre(object.header()));
|
EXPECT_THAT(Alive(), testing::UnorderedElementsAre(object.header()));
|
||||||
EXPECT_THAT(object.state(), GC::ObjectData::State::kMarkReset);
|
EXPECT_THAT(AliveExtraObjects(), testing::UnorderedElementsAre(&extra));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleMarkedObjectArrayWithExtraData) {
|
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleMarkedObjectArrayWithExtraData) {
|
||||||
auto& array = AllocateObjectArray();
|
auto& array = AllocateObjectArray();
|
||||||
InstallExtraData(array.header());
|
auto& extra = InstallExtraData(array.header());
|
||||||
array.Mark();
|
array.Mark();
|
||||||
ASSERT_THAT(Alive(), testing::UnorderedElementsAre(array.header()));
|
ASSERT_THAT(Alive(), testing::UnorderedElementsAre(array.header()));
|
||||||
|
|
||||||
@@ -409,12 +416,12 @@ TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleMarkedObjectArrayWithExtraData) {
|
|||||||
|
|
||||||
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(Alive(), testing::UnorderedElementsAre(array.header()));
|
EXPECT_THAT(Alive(), testing::UnorderedElementsAre(array.header()));
|
||||||
EXPECT_THAT(array.state(), GC::ObjectData::State::kMarkReset);
|
EXPECT_THAT(AliveExtraObjects(), testing::UnorderedElementsAre(&extra));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleMarkedCharArrayWithExtraData) {
|
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleMarkedCharArrayWithExtraData) {
|
||||||
auto& array = AllocateCharArray();
|
auto& array = AllocateCharArray();
|
||||||
InstallExtraData(array.header());
|
auto& extra = InstallExtraData(array.header());
|
||||||
array.Mark();
|
array.Mark();
|
||||||
ASSERT_THAT(Alive(), testing::UnorderedElementsAre(array.header()));
|
ASSERT_THAT(Alive(), testing::UnorderedElementsAre(array.header()));
|
||||||
|
|
||||||
@@ -422,7 +429,7 @@ TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleMarkedCharArrayWithExtraData) {
|
|||||||
|
|
||||||
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(Alive(), testing::UnorderedElementsAre(array.header()));
|
EXPECT_THAT(Alive(), testing::UnorderedElementsAre(array.header()));
|
||||||
EXPECT_THAT(array.state(), GC::ObjectData::State::kMarkReset);
|
EXPECT_THAT(AliveExtraObjects(), testing::UnorderedElementsAre(&extra));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleObjectWithFinalizerHook) {
|
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleObjectWithFinalizerHook) {
|
||||||
@@ -457,10 +464,8 @@ TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleObjectWithWeakCounter) {
|
|||||||
|
|
||||||
auto finalizers = Sweep();
|
auto finalizers = Sweep();
|
||||||
|
|
||||||
EXPECT_THAT(finalizers, testing::UnorderedElementsAre(object.header()));
|
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(object.state(), GC::ObjectData::State::kUnmarked);
|
|
||||||
EXPECT_FALSE(object.HasWeakCounter());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleObjectArrayWithWeakCounter) {
|
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleObjectArrayWithWeakCounter) {
|
||||||
@@ -470,10 +475,8 @@ TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleObjectArrayWithWeakCounter) {
|
|||||||
|
|
||||||
auto finalizers = Sweep();
|
auto finalizers = Sweep();
|
||||||
|
|
||||||
EXPECT_THAT(finalizers, testing::UnorderedElementsAre(array.header()));
|
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(array.state(), GC::ObjectData::State::kUnmarked);
|
|
||||||
EXPECT_FALSE(array.HasWeakCounter());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleCharArrayWithWeakCounter) {
|
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleCharArrayWithWeakCounter) {
|
||||||
@@ -483,10 +486,8 @@ TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleCharArrayWithWeakCounter) {
|
|||||||
|
|
||||||
auto finalizers = Sweep();
|
auto finalizers = Sweep();
|
||||||
|
|
||||||
EXPECT_THAT(finalizers, testing::UnorderedElementsAre(array.header()));
|
EXPECT_THAT(finalizers, testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
EXPECT_THAT(Alive(), testing::UnorderedElementsAre());
|
||||||
EXPECT_THAT(array.state(), GC::ObjectData::State::kUnmarked);
|
|
||||||
EXPECT_FALSE(array.HasWeakCounter());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleMarkedObjectWithWeakCounter) {
|
TEST_F(MarkAndSweepUtilsSweepTest, SweepSingleMarkedObjectWithWeakCounter) {
|
||||||
|
|||||||
@@ -160,6 +160,11 @@ public:
|
|||||||
deletionQueue_ = std::move(remainingDeletions);
|
deletionQueue_ = std::move(remainingDeletions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// requires LockForIter
|
||||||
|
void EraseAndAdvance(Iterator &it) {
|
||||||
|
it.position_ = queue_.erase(it.position_);
|
||||||
|
}
|
||||||
|
|
||||||
void ClearForTests() noexcept {
|
void ClearForTests() noexcept {
|
||||||
queue_.clear();
|
queue_.clear();
|
||||||
deletionQueue_.clear();
|
deletionQueue_.clear();
|
||||||
|
|||||||
@@ -56,20 +56,15 @@ mm::ExtraObjectData& mm::ExtraObjectData::Install(ObjHeader* object) noexcept {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
void mm::ExtraObjectData::Uninstall() noexcept {
|
||||||
void mm::ExtraObjectData::Uninstall(ObjHeader* object) noexcept {
|
auto *object = GetBaseObject();
|
||||||
RuntimeAssert(object->has_meta_object(), "Object must have a meta object set");
|
*const_cast<const TypeInfo**>(&object->typeInfoOrMeta_) = typeInfo_;
|
||||||
|
RuntimeAssert(!object->has_meta_object(), "Object has metaobject after removing metaobject");
|
||||||
|
|
||||||
auto& data = ExtraObjectData::FromMetaObjHeader(object->meta_object());
|
|
||||||
|
|
||||||
*const_cast<const TypeInfo**>(&object->typeInfoOrMeta_) = data.typeInfo_;
|
|
||||||
|
|
||||||
auto *threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
|
|
||||||
#ifdef KONAN_OBJC_INTEROP
|
#ifdef KONAN_OBJC_INTEROP
|
||||||
Kotlin_ObjCExport_releaseAssociatedObject(data.associatedObject_);
|
Kotlin_ObjCExport_releaseAssociatedObject(associatedObject_);
|
||||||
data.associatedObject_ = nullptr;
|
associatedObject_ = nullptr;
|
||||||
#endif
|
#endif
|
||||||
mm::ExtraObjectDataFactory::Instance().DestroyExtraObjectData(threadData, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mm::ExtraObjectData::DetachAssociatedObject() noexcept {
|
void mm::ExtraObjectData::DetachAssociatedObject() noexcept {
|
||||||
@@ -78,6 +73,15 @@ void mm::ExtraObjectData::DetachAssociatedObject() noexcept {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mm::ExtraObjectData::HasAssociatedObject() noexcept {
|
||||||
|
#ifdef KONAN_OBJC_INTEROP
|
||||||
|
return associatedObject_ != nullptr;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void mm::ExtraObjectData::ClearWeakReferenceCounter() noexcept {
|
void mm::ExtraObjectData::ClearWeakReferenceCounter() noexcept {
|
||||||
if (!HasWeakReferenceCounter()) return;
|
if (!HasWeakReferenceCounter()) return;
|
||||||
|
|
||||||
|
|||||||
@@ -41,11 +41,12 @@ public:
|
|||||||
static ExtraObjectData& GetOrInstall(ObjHeader* object) noexcept { return FromMetaObjHeader(object->meta_object()); }
|
static ExtraObjectData& GetOrInstall(ObjHeader* object) noexcept { return FromMetaObjHeader(object->meta_object()); }
|
||||||
|
|
||||||
static ExtraObjectData& Install(ObjHeader* object) noexcept;
|
static ExtraObjectData& Install(ObjHeader* object) noexcept;
|
||||||
static void Uninstall(ObjHeader* object) noexcept;
|
void Uninstall() noexcept;
|
||||||
|
|
||||||
#ifdef KONAN_OBJC_INTEROP
|
#ifdef KONAN_OBJC_INTEROP
|
||||||
void** GetAssociatedObjectLocation() noexcept { return &associatedObject_; }
|
void** GetAssociatedObjectLocation() noexcept { return &associatedObject_; }
|
||||||
#endif
|
#endif
|
||||||
|
bool HasAssociatedObject() noexcept;
|
||||||
void DetachAssociatedObject() noexcept;
|
void DetachAssociatedObject() noexcept;
|
||||||
|
|
||||||
std::atomic<Flags>& flags() noexcept { return flags_; }
|
std::atomic<Flags>& flags() noexcept { return flags_; }
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ public:
|
|||||||
|
|
||||||
size_t GetSizeUnsafe() noexcept { return extraObjects_.GetSizeUnsafe(); }
|
size_t GetSizeUnsafe() noexcept { return extraObjects_.GetSizeUnsafe(); }
|
||||||
|
|
||||||
|
// requires LockForIter
|
||||||
|
void EraseAndAdvance(Iterator &it) { extraObjects_.EraseAndAdvance(it); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Queue extraObjects_;
|
Queue extraObjects_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ TEST_F(ExtraObjectDataTest, Install) {
|
|||||||
EXPECT_FALSE(extraData.HasWeakReferenceCounter());
|
EXPECT_FALSE(extraData.HasWeakReferenceCounter());
|
||||||
EXPECT_THAT(extraData.GetBaseObject(), object.header());
|
EXPECT_THAT(extraData.GetBaseObject(), object.header());
|
||||||
|
|
||||||
mm::ExtraObjectData::Uninstall(object.header());
|
extraData.Uninstall();
|
||||||
|
mm::GlobalData::Instance().threadRegistry().CurrentThreadData()->ClearForTests();
|
||||||
|
|
||||||
EXPECT_FALSE(object.header()->has_meta_object());
|
EXPECT_FALSE(object.header()->has_meta_object());
|
||||||
EXPECT_THAT(object.header()->type_info(), typeInfo);
|
EXPECT_THAT(object.header()->type_info(), typeInfo);
|
||||||
|
|||||||
@@ -82,7 +82,11 @@ MetaObjHeader* ObjHeader::createMetaObject(ObjHeader* object) {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
void ObjHeader::destroyMetaObject(ObjHeader* object) {
|
void ObjHeader::destroyMetaObject(ObjHeader* object) {
|
||||||
mm::ExtraObjectData::Uninstall(object);
|
RuntimeAssert(object->has_meta_object(), "Object must have a meta object set");
|
||||||
|
auto &extraObject = *mm::ExtraObjectData::Get(object);
|
||||||
|
extraObject.Uninstall();
|
||||||
|
auto *threadData = mm::ThreadRegistry::Instance().CurrentThreadData();
|
||||||
|
mm::ExtraObjectDataFactory::Instance().DestroyExtraObjectData(threadData, extraObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool isPermanentOrFrozen(const ObjHeader* obj) {
|
ALWAYS_INLINE bool isPermanentOrFrozen(const ObjHeader* obj) {
|
||||||
|
|||||||
Reference in New Issue
Block a user