Commit c4cb14c7 authored by Anton Bikineev's avatar Anton Bikineev Committed by V8 LUCI CQ

cppgc: Try to fix test IteratePointersFindsCalleeSavedRegisters, vol.2

The previous attempt has broken the tsan bot. The only reliable way to
make sure that registers are not clobbered is by doing direct call from
inline assembly, which is what this CL does.

Change-Id: I6adbd5e735949a7cc4cc7fc686ee8c428863ffb9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2859947
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74313}
parent 05fc4737
...@@ -308,6 +308,16 @@ TEST_F(GCStackTest, IteratePointersFindsParameterNesting8) { ...@@ -308,6 +308,16 @@ TEST_F(GCStackTest, IteratePointersFindsParameterNesting8) {
#ifdef FOR_ALL_CALLEE_SAVED_REGS #ifdef FOR_ALL_CALLEE_SAVED_REGS
namespace {
#if !defined(V8_OS_WIN)
__attribute__((visibility("hidden")))
#endif
extern "C" void
IteratePointersNoMangling(Stack* stack, StackVisitor* visitor) {
stack->IteratePointers(visitor);
}
} // namespace
TEST_F(GCStackTest, IteratePointersFindsCalleeSavedRegisters) { TEST_F(GCStackTest, IteratePointersFindsCalleeSavedRegisters) {
auto scanner = std::make_unique<StackScanner>(); auto scanner = std::make_unique<StackScanner>();
...@@ -324,22 +334,35 @@ TEST_F(GCStackTest, IteratePointersFindsCalleeSavedRegisters) { ...@@ -324,22 +334,35 @@ TEST_F(GCStackTest, IteratePointersFindsCalleeSavedRegisters) {
auto* local_stack = GetStack(); auto* local_stack = GetStack();
auto* local_scanner = scanner.get(); auto* local_scanner = scanner.get();
#define MOVE_TO_REG_AND_CALL_IMPL(needle_reg, arg1, arg2) \
asm volatile("mov %0, %%" needle_reg "\n mov %1, %%" arg1 \
"\n mov %2, %%" arg2 \
"\n call %P3" \
"\n mov $0, %%" needle_reg \
: \
: "r"(local_scanner->needle()), "r"(local_stack), \
"r"(local_scanner), "i"(IteratePointersNoMangling) \
: "memory", needle_reg, arg1, arg2, "cc");
#ifdef V8_OS_WIN
#define MOVE_TO_REG_AND_CALL(reg) MOVE_TO_REG_AND_CALL_IMPL(reg, "rcx", "rdx")
#else // !V8_OS_WIN
#define MOVE_TO_REG_AND_CALL(reg) MOVE_TO_REG_AND_CALL_IMPL(reg, "rdi", "rsi")
#endif // V8_OS_WIN
// Moves |local_scanner->needle()| into a callee-saved register, leaving the // Moves |local_scanner->needle()| into a callee-saved register, leaving the
// callee-saved register as the only register referencing the needle. // callee-saved register as the only register referencing the needle.
// (Ignoring implementation-dependent dirty registers/stack.) // (Ignoring implementation-dependent dirty registers/stack.)
#define KEEP_ALIVE_FROM_CALLEE_SAVED(reg) \ #define KEEP_ALIVE_FROM_CALLEE_SAVED(reg) \
local_scanner->Reset(); \ local_scanner->Reset(); \
/* This moves the temporary into the calee-saved register. */ \ [local_stack, local_scanner]() V8_NOINLINE { MOVE_TO_REG_AND_CALL(reg) }(); \
asm("mov %0, %%" reg : : "r"(local_scanner->needle()) : reg); \ EXPECT_TRUE(local_scanner->found()) \
/* Register is unprotected from here till the actual invocation. */ \ << "pointer in callee-saved register not found. register: " << reg \
local_stack->IteratePointers(local_scanner); \ << std::endl;
EXPECT_TRUE(local_scanner->found()) \
<< "pointer in callee-saved register not found. register: " << reg \
<< std::endl; \
/* Clear out the register again */ \
asm("mov $0, %%" reg : : : reg);
FOR_ALL_CALLEE_SAVED_REGS(KEEP_ALIVE_FROM_CALLEE_SAVED) FOR_ALL_CALLEE_SAVED_REGS(KEEP_ALIVE_FROM_CALLEE_SAVED)
#undef MOVE_TO_REG_AND_CALL
#undef MOVE_TO_REG_AND_CALL_IMPL
#undef KEEP_ALIVE_FROM_CALLEE_SAVED #undef KEEP_ALIVE_FROM_CALLEE_SAVED
#undef FOR_ALL_CALLEE_SAVED_REGS #undef FOR_ALL_CALLEE_SAVED_REGS
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment