1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/memory/aligned_memory.h"
6#include "base/memory/scoped_ptr.h"
7#include "testing/gtest/include/gtest/gtest.h"
8
9#define EXPECT_ALIGNED(ptr, align) \
10    EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(ptr) & (align - 1))
11
12namespace {
13
14using base::AlignedMemory;
15
16TEST(AlignedMemoryTest, StaticAlignment) {
17  static AlignedMemory<8, 8> raw8;
18  static AlignedMemory<8, 16> raw16;
19  static AlignedMemory<8, 256> raw256;
20  static AlignedMemory<8, 4096> raw4096;
21
22  EXPECT_EQ(8u, ALIGNOF(raw8));
23  EXPECT_EQ(16u, ALIGNOF(raw16));
24  EXPECT_EQ(256u, ALIGNOF(raw256));
25  EXPECT_EQ(4096u, ALIGNOF(raw4096));
26
27  EXPECT_ALIGNED(raw8.void_data(), 8);
28  EXPECT_ALIGNED(raw16.void_data(), 16);
29  EXPECT_ALIGNED(raw256.void_data(), 256);
30  EXPECT_ALIGNED(raw4096.void_data(), 4096);
31}
32
33TEST(AlignedMemoryTest, StackAlignment) {
34  AlignedMemory<8, 8> raw8;
35  AlignedMemory<8, 16> raw16;
36  AlignedMemory<8, 128> raw128;
37
38  EXPECT_EQ(8u, ALIGNOF(raw8));
39  EXPECT_EQ(16u, ALIGNOF(raw16));
40  EXPECT_EQ(128u, ALIGNOF(raw128));
41
42  EXPECT_ALIGNED(raw8.void_data(), 8);
43  EXPECT_ALIGNED(raw16.void_data(), 16);
44
45  // TODO(ios): __attribute__((aligned(X))) with X >= 128 does not works on
46  // the stack when building for arm64 on iOS, http://crbug.com/349003
47#if !(defined(OS_IOS) && defined(ARCH_CPU_ARM64))
48  EXPECT_ALIGNED(raw128.void_data(), 128);
49
50  // NaCl x86-64 compiler emits non-validating instructions for >128
51  // bytes alignment.
52  // http://www.chromium.org/nativeclient/design-documents/nacl-sfi-model-on-x86-64-systems
53  // TODO(hamaji): Ideally, NaCl compiler for x86-64 should workaround
54  // this limitation and this #if should be removed.
55  // https://code.google.com/p/nativeclient/issues/detail?id=3463
56#if !(defined(OS_NACL) && defined(ARCH_CPU_X86_64))
57  AlignedMemory<8, 256> raw256;
58  EXPECT_EQ(256u, ALIGNOF(raw256));
59  EXPECT_ALIGNED(raw256.void_data(), 256);
60
61  // TODO(ios): This test hits an armv7 bug in clang. crbug.com/138066
62#if !(defined(OS_IOS) && defined(ARCH_CPU_ARM_FAMILY))
63  AlignedMemory<8, 4096> raw4096;
64  EXPECT_EQ(4096u, ALIGNOF(raw4096));
65  EXPECT_ALIGNED(raw4096.void_data(), 4096);
66#endif  // !(defined(OS_IOS) && defined(ARCH_CPU_ARM_FAMILY))
67#endif  // !(defined(OS_NACL) && defined(ARCH_CPU_X86_64))
68#endif  // !(defined(OS_IOS) && defined(ARCH_CPU_ARM64))
69}
70
71TEST(AlignedMemoryTest, DynamicAllocation) {
72  void* p = base::AlignedAlloc(8, 8);
73  EXPECT_TRUE(p);
74  EXPECT_ALIGNED(p, 8);
75  base::AlignedFree(p);
76
77  p = base::AlignedAlloc(8, 16);
78  EXPECT_TRUE(p);
79  EXPECT_ALIGNED(p, 16);
80  base::AlignedFree(p);
81
82  p = base::AlignedAlloc(8, 256);
83  EXPECT_TRUE(p);
84  EXPECT_ALIGNED(p, 256);
85  base::AlignedFree(p);
86
87  p = base::AlignedAlloc(8, 4096);
88  EXPECT_TRUE(p);
89  EXPECT_ALIGNED(p, 4096);
90  base::AlignedFree(p);
91}
92
93TEST(AlignedMemoryTest, ScopedDynamicAllocation) {
94  scoped_ptr<float, base::AlignedFreeDeleter> p(
95      static_cast<float*>(base::AlignedAlloc(8, 8)));
96  EXPECT_TRUE(p.get());
97  EXPECT_ALIGNED(p.get(), 8);
98}
99
100}  // namespace
101