diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 24cff4e7ed3..dfc2eb92df5 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -520,8 +520,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, fun setTypeInfoForLocalObject(objectHeader: LLVMValueRef) { val typeInfo = structGep(objectHeader, 0, "typeInfoOrMeta_") - // Set tag OBJECT_TAG_PERMANENT_CONTAINER. - val typeInfoValue = intToPtr(or(ptrToInt(alloca(kTypeInfo), int32Type), Int32(1).llvm), kTypeInfoPtr) + // Set tag OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER. + val typeInfoValue = intToPtr(or(ptrToInt(alloca(kTypeInfo), int32Type), Int32(3).llvm), kTypeInfoPtr) store(typeInfoValue, typeInfo) } diff --git a/runtime/src/main/cpp/Arrays.cpp b/runtime/src/main/cpp/Arrays.cpp index c41030c2b50..faf41f2daab 100644 --- a/runtime/src/main/cpp/Arrays.cpp +++ b/runtime/src/main/cpp/Arrays.cpp @@ -29,7 +29,7 @@ namespace { ALWAYS_INLINE inline void mutabilityCheck(KConstRef thiz) { // TODO: optimize it! - if (thiz->container() != nullptr && thiz->container()->frozen()) { + if (!thiz->local() && thiz->container()->frozen()) { ThrowInvalidMutabilityException(thiz); } } diff --git a/runtime/src/main/cpp/Memory.h b/runtime/src/main/cpp/Memory.h index 7d914f619bf..df9272385e5 100644 --- a/runtime/src/main/cpp/Memory.h +++ b/runtime/src/main/cpp/Memory.h @@ -371,6 +371,12 @@ struct ObjHeader { return (reinterpret_cast(clearPointerBits(typeInfoOrMeta_, OBJECT_TAG_MASK)))->container_; } + inline bool local() const { + unsigned bits = getPointerBits(typeInfoOrMeta_, OBJECT_TAG_MASK); + return (bits & (OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER)) == + (OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER); + } + // Unsafe cast to ArrayHeader. Use carefully! ArrayHeader* array() { return reinterpret_cast(this); } const ArrayHeader* array() const { return reinterpret_cast(this); }