Support sanitizers in runtime tests (#4622)

This commit is contained in:
Alexander Shabalin
2021-01-20 19:42:09 +03:00
committed by Nikolay Krasko
parent 3ee8d98726
commit 6cc60ad6a2
10 changed files with 256 additions and 66 deletions
+19 -16
View File
@@ -5,6 +5,8 @@
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.testing.native.*
import org.jetbrains.kotlin.bitcode.CompileToBitcode
import org.jetbrains.kotlin.bitcode.CompileToBitcodeExtension
import org.jetbrains.kotlin.konan.target.*
plugins {
id("compile-to-bitcode")
@@ -42,6 +44,7 @@ bitcode {
"${target}ExperimentalMemoryManager"
)
includeRuntime()
// TODO: Should depend on the sanitizer.
linkerArgs.add(project.file("../common/build/bitcode/main/$target/hash.bc").path)
}
@@ -107,9 +110,11 @@ bitcode {
}
targetList.forEach { targetName ->
createTestTask(
val allTests = mutableListOf<Task>()
allTests.addAll(createTestTasks(
project,
"StdAlloc",
targetName,
"${targetName}StdAllocRuntimeTests",
listOf(
"${targetName}Runtime",
@@ -120,11 +125,11 @@ targetList.forEach { targetName ->
)
) {
includeRuntime()
}
})
createTestTask(
allTests.addAll(createTestTasks(
project,
"Mimalloc",
targetName,
"${targetName}MimallocRuntimeTests",
listOf(
"${targetName}Runtime",
@@ -136,11 +141,11 @@ targetList.forEach { targetName ->
)
) {
includeRuntime()
}
})
createTestTask(
allTests.addAll(createTestTasks(
project,
"ExperimentalMMMimalloc",
targetName,
"${targetName}ExperimentalMMMimallocRuntimeTests",
listOf(
"${targetName}Runtime",
@@ -151,11 +156,11 @@ targetList.forEach { targetName ->
)
) {
includeRuntime()
}
})
createTestTask(
allTests.addAll(createTestTasks(
project,
"ExperimentalMMStdAlloc",
targetName,
"${targetName}ExperimentalMMStdAllocRuntimeTests",
listOf(
"${targetName}Runtime",
@@ -165,13 +170,11 @@ targetList.forEach { targetName ->
)
) {
includeRuntime()
}
})
// TODO: This "all tests" tasks should be provided by `CompileToBitcodeExtension`
tasks.register("${targetName}RuntimeTests") {
dependsOn("${targetName}StdAllocRuntimeTests")
dependsOn("${targetName}MimallocRuntimeTests")
dependsOn("${targetName}ExperimentalMMStdAllocRuntimeTests")
dependsOn("${targetName}ExperimentalMMMimallocRuntimeTests")
dependsOn(allTests)
}
}
@@ -112,7 +112,9 @@ TEST_F(KonanAllocatorAwareTest, PlacementAllocated) {
TEST_F(KonanAllocatorAwareTest, PlacementConstructedArray) {
constexpr size_t kCount = 5;
std::array<uint8_t, sizeof(A) * kCount> buffer;
// TODO: Consider removing support for placement new[] altogether, since there's no
// portable way to know needed storage size ahead of time.
alignas(A) std::array<uint8_t, sizeof(A) * kCount + sizeof(size_t)> buffer;
A* as = new (buffer.data()) A[kCount];
std::vector<int> actual;
@@ -8,6 +8,9 @@ namespace kotlin {
#if KONAN_WINDOWS
// TODO: Figure out why creating many threads on windows is so slow.
constexpr int kDefaultThreadCount = 10;
#elif __has_feature(thread_sanitizer)
// TSAN has a huge overhead.
constexpr int kDefaultThreadCount = 10;
#else
constexpr int kDefaultThreadCount = 100;
#endif
@@ -14,9 +14,27 @@
using namespace kotlin;
namespace {
template <typename T>
ALWAYS_INLINE T UnsafeRead(T* location) noexcept {
#if __has_feature(thread_sanitizer)
// Make TSAN think that this load is fine.
return __atomic_load_n(location, __ATOMIC_ACQUIRE);
#else
return *location;
#endif
}
} // namespace
// static
mm::ExtraObjectData& mm::ExtraObjectData::Install(ObjHeader* object) noexcept {
TypeInfo* typeInfo = object->typeInfoOrMeta_;
// TODO: Consider extracting initialization scheme with speculative load.
// `object->typeInfoOrMeta_` is assigned at most once. If we read some old value (i.e. not a meta object),
// we will fail at CAS below. If we read the new value, we will immediately return it.
TypeInfo* typeInfo = UnsafeRead(&object->typeInfoOrMeta_);
if (auto* metaObject = ObjHeader::AsMetaObject(typeInfo)) {
return mm::ExtraObjectData::FromMetaObjHeader(metaObject);
}