[K/N] Specialize marking call for objects ^KT-54163

Merge-request: KT-MR-7232
Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
Alexander Shabalin
2022-10-04 09:51:08 +00:00
committed by Space Team
parent 377082ee43
commit 98251f42f2
19 changed files with 280 additions and 112 deletions
@@ -561,4 +561,9 @@ bool FinalizersThreadIsRunning() noexcept;
} // namespace kotlin
RUNTIME_NOTHROW ALWAYS_INLINE extern "C" void Kotlin_processObjectInMark(void* state, ObjHeader* object);
RUNTIME_NOTHROW ALWAYS_INLINE extern "C" void Kotlin_processArrayInMark(void* state, ObjHeader* object);
RUNTIME_NOTHROW ALWAYS_INLINE extern "C" void Kotlin_processFieldInMark(void* state, ObjHeader* field);
RUNTIME_NOTHROW ALWAYS_INLINE extern "C" void Kotlin_processEmptyObjectInMark(void* state, ObjHeader* object);
#endif // RUNTIME_MEMORY_H
@@ -661,10 +661,12 @@ static const TypeInfo* createTypeInfo(
if ((superType->flags_ & TF_IMMUTABLE) != 0) {
result->flags_ |= TF_IMMUTABLE;
}
result->processObjectInMark = superType->processObjectInMark;
} else {
result->instanceSize_ = fieldsInfo->instanceSize_;
result->objOffsets_ = fieldsInfo->objOffsets_;
result->objOffsetsCount_ = fieldsInfo->objOffsetsCount_;
result->processObjectInMark = fieldsInfo->processObjectInMark;
}
result->classId_ = superType->classId_;
@@ -28,8 +28,10 @@ private:
int32_t instanceSize_ = 0;
std_support::vector<int32_t> objOffsets_;
int32_t objOffsetsCount_ = 0;
int32_t flags_ = 0;
const TypeInfo* superType_ = nullptr;
void (*processObjectInMark_)(void*, ObjHeader*) = nullptr;
};
public:
@@ -57,7 +59,16 @@ public:
template <typename Payload>
class ArrayBuilder : public Builder {
public:
ArrayBuilder() noexcept { instanceSize_ = -static_cast<int32_t>(sizeof(Payload)); }
ArrayBuilder() noexcept {
instanceSize_ = -static_cast<int32_t>(sizeof(Payload));
if constexpr (std::is_same_v<Payload, ObjHeader*>) {
// Following RTTIGenerator.kt
objOffsetsCount_ = 1;
processObjectInMark_ = Kotlin_processArrayInMark;
} else {
processObjectInMark_ = Kotlin_processEmptyObjectInMark;
}
}
ArrayBuilder&& addFlag(Konan_TypeFlags flag) noexcept {
flags_ |= flag;
@@ -75,12 +86,8 @@ public:
typeInfo_.instanceSize_ = builder.instanceSize_;
objOffsets_ = std::move(builder.objOffsets_);
typeInfo_.objOffsets_ = objOffsets_.data();
if (&typeInfo_ == theArrayTypeInfo) {
// Following RTTIGenerator.kt
typeInfo_.objOffsetsCount_ = 1;
} else {
typeInfo_.objOffsetsCount_ = objOffsets_.size();
}
typeInfo_.objOffsetsCount_ = builder.objOffsetsCount_;
typeInfo_.processObjectInMark = builder.processObjectInMark_;
typeInfo_.flags_ = builder.flags_;
typeInfo_.superType_ = builder.superType_;
}
@@ -174,6 +181,8 @@ TypeInfoHolder::ObjectBuilder<Payload>::ObjectBuilder() noexcept {
auto& actualField = payload.*field;
objOffsets_.push_back(reinterpret_cast<uintptr_t>(&actualField) - reinterpret_cast<uintptr_t>(object.header()));
}
objOffsetsCount_ = objOffsets_.size();
processObjectInMark_ = Kotlin_processObjectInMark;
}
namespace internal {
@@ -132,16 +132,16 @@ struct TypeInfo {
// Null-terminated array.
const AssociatedObjectTableRecord* associatedObjects;
// Invoked on an object during mark phase.
// TODO: Consider providing a generic traverse method instead.
void (*processObjectInMark)(void* state, ObjHeader* object);
// vtable starts just after declared contents of the TypeInfo:
// void* const vtable_[];
#ifdef __cplusplus
inline VTableElement const* vtable() const {
return reinterpret_cast<VTableElement const*>(this + 1);
}
inline VTableElement const* vtable() const { return reinterpret_cast<VTableElement const*>(this + 1); }
inline VTableElement* vtable() {
return reinterpret_cast<VTableElement*>(this + 1);
}
inline VTableElement* vtable() { return reinterpret_cast<VTableElement*>(this + 1); }
inline bool IsArray() const { return instanceSize_ < 0; }