blob: efbfcac38cbe66cf5e7cfb6e3c2ba5c00f505f23 [file]
/*
* Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
#include "FinalizerHooks.hpp"
#include "Cleaner.h"
#include "Memory.h"
#include "Types.h"
using namespace kotlin;
namespace {
void (*g_hookOverrideForTesting)(ObjHeader*) = nullptr;
// Not inlining this call as it affects deallocation performance for
// all types.
NO_INLINE void RunFinalizerHooksImpl(ObjHeader* object, const TypeInfo* type) noexcept {
if (g_hookOverrideForTesting != nullptr) {
g_hookOverrideForTesting(object);
}
// TODO: Consider some global registration.
if (type == theCleanerImplTypeInfo) {
DisposeCleaner(object);
} else if (type == theRegularWeakReferenceImplTypeInfo) {
DisposeRegularWeakReferenceImpl(object);
}
}
} // namespace
PERFORMANCE_INLINE bool kotlin::HasFinalizers(ObjHeader* object) noexcept {
return object->has_meta_object() || HasFinalizersDataInObject(object);
}
PERFORMANCE_INLINE bool kotlin::HasFinalizersDataInObject(ObjHeader* object) noexcept {
return (object->type_info()->flags_ & TF_HAS_FINALIZER) != 0;
}
PERFORMANCE_INLINE void kotlin::RunFinalizers(ObjHeader* object) noexcept {
auto* type = object->type_info();
if ((type->flags_ & TF_HAS_FINALIZER) != 0) {
// This is a cold path.
RunFinalizerHooksImpl(object, type);
}
if (object->has_meta_object()) {
ObjHeader::destroyMetaObject(object);
}
}
void kotlin::SetFinalizerHookForTesting(void (*hook)(ObjHeader*)) noexcept {
g_hookOverrideForTesting = hook;
}