#include "src/heap/base/stack.h"
#include <memory>
#include <ostream>
#include "include/v8config.h"
#include "testing/gtest/include/gtest/gtest.h"
#if V8_OS_LINUX && (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64)
#include <xmmintrin.h>
#endif
namespace cppgc {
namespace internal {
Stack;
StackVisitor;
namespace {
class GCStackTest : public ::testing::Test { … };
}
#if !V8_OS_FUCHSIA
TEST_F(GCStackTest, IsOnStackForStackValue) { … }
#endif
TEST_F(GCStackTest, IsOnStackForHeapValue) { … }
namespace {
class StackScanner final : public StackVisitor { … };
}
TEST_F(GCStackTest, IteratePointersFindsOnStackValue) { … }
TEST_F(GCStackTest, IteratePointersFindsOnStackValuePotentiallyUnaligned) { … }
namespace {
V8_NOINLINE void* RecursivelyPassOnParameterImpl(void* p1, void* p2, void* p3,
void* p4, void* p5, void* p6,
void* p7, void* p8,
Stack* stack,
StackVisitor* visitor) { … }
V8_NOINLINE void* RecursivelyPassOnParameter(size_t num, void* parameter,
Stack* stack,
StackVisitor* visitor) { … }
}
TEST_F(GCStackTest, IteratePointersFindsParameterNesting0) { … }
TEST_F(GCStackTest, IteratePointersFindsParameterNesting1) { … }
TEST_F(GCStackTest, IteratePointersFindsParameterNesting2) { … }
TEST_F(GCStackTest, IteratePointersFindsParameterNesting3) { … }
TEST_F(GCStackTest, IteratePointersFindsParameterNesting4) { … }
TEST_F(GCStackTest, IteratePointersFindsParameterNesting5) { … }
TEST_F(GCStackTest, IteratePointersFindsParameterNesting6) { … }
TEST_F(GCStackTest, IteratePointersFindsParameterNesting7) { … }
#if !defined(_MSC_VER) || defined(__clang__)
TEST_F(GCStackTest, IteratePointersFindsParameterNesting8) { … }
#endif
namespace {
extern "C" V8_NOINLINE
#if defined(__clang__)
__attribute__((used))
#if !defined(V8_OS_WIN)
__attribute__((visibility("hidden")))
#endif
#ifdef __has_attribute
#if __has_attribute(force_align_arg_pointer)
__attribute__((force_align_arg_pointer))
#endif
#endif
#endif
void
IteratePointersNoMangling(Stack* stack, StackVisitor* visitor) { … }
}
#ifdef __clang__
#ifdef V8_TARGET_ARCH_X64
#ifdef V8_OS_WIN
#define FOR_ALL_CALLEE_SAVED_REGS …
#else
#define FOR_ALL_CALLEE_SAVED_REGS …
#endif
#endif
#endif
#ifdef FOR_ALL_CALLEE_SAVED_REGS
TEST_F(GCStackTest, IteratePointersFindsCalleeSavedRegisters) { … }
#endif
#if defined(__clang__) && defined(V8_TARGET_ARCH_X64) && defined(V8_OS_WIN)
#define FOR_ALL_XMM_CALLEE_SAVED_REGS …
TEST_F(GCStackTest, IteratePointersFindsCalleeSavedXMMRegisters) {
auto scanner = std::make_unique<StackScanner>();
#define CLEAR_REGISTER …
FOR_ALL_XMM_CALLEE_SAVED_REGS(CLEAR_REGISTER)
#undef CLEAR_REGISTER
auto* local_stack = GetStack();
auto* local_scanner = scanner.get();
#define KEEP_ALIVE_FROM_CALLEE_SAVED …
#define MOVE_TO_REG_AND_CALL …
FOR_ALL_XMM_CALLEE_SAVED_REGS(KEEP_ALIVE_FROM_CALLEE_SAVED)
#undef MOVE_TO_REG_AND_CALL
#define MOVE_TO_REG_AND_CALL …
FOR_ALL_XMM_CALLEE_SAVED_REGS(KEEP_ALIVE_FROM_CALLEE_SAVED)
#undef MOVE_TO_REG_AND_CALL
#undef KEEP_ALIVE_FROM_CALLEE_SAVED
#undef FOR_ALL_XMM_CALLEE_SAVED_REGS
}
#endif
#if V8_OS_LINUX && (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64)
class CheckStackAlignmentVisitor final : public StackVisitor { … };
TEST_F(GCStackTest, StackAlignment) { … }
#endif
}
}