xref: /third_party/vixl/test/test-code-buffer.cc (revision b8021494)
1// Copyright 2016, VIXL authors
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7//   * Redistributions of source code must retain the above copyright notice,
8//     this list of conditions and the following disclaimer.
9//   * Redistributions in binary form must reproduce the above copyright notice,
10//     this list of conditions and the following disclaimer in the documentation
11//     and/or other materials provided with the distribution.
12//   * Neither the name of ARM Limited nor the names of its contributors may be
13//     used to endorse or promote products derived from this software without
14//     specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27
28#include "code-buffer-vixl.h"
29#include "test-runner.h"
30
31namespace vixl {
32
33#define TEST(name) TEST_(CODE_BUFFER_##name)
34
35TEST(align_grow) {
36  CodeBuffer code_buffer(2);
37  VIXL_CHECK(code_buffer.GetCapacity() == 2);
38  VIXL_CHECK(code_buffer.GetRemainingBytes() == 2);
39
40  code_buffer.Emit16(0);
41  VIXL_CHECK(code_buffer.GetCapacity() == 2);
42  VIXL_CHECK(code_buffer.GetRemainingBytes() == 0);
43
44  // Check that the buffer can automatically grow when aligning the cursor.
45  VIXL_CHECK(IsAligned<2>(code_buffer.GetCursorOffset()));
46  code_buffer.Align();
47  VIXL_CHECK(IsWordAligned(code_buffer.GetCursorOffset()));
48  VIXL_CHECK(code_buffer.GetCapacity() > 2);
49
50  code_buffer.SetClean();
51}
52
53static void TestDefaultsHelper(const CodeBuffer& buffer) {
54  VIXL_CHECK(buffer.GetCapacity() == CodeBuffer::kDefaultCapacity);
55  VIXL_CHECK(buffer.HasSpaceFor(CodeBuffer::kDefaultCapacity));
56  VIXL_CHECK(!buffer.HasSpaceFor(CodeBuffer::kDefaultCapacity + 1));
57  VIXL_CHECK(buffer.GetCursorOffset() == 0);
58  VIXL_CHECK(buffer.GetOffsetFrom(0) == 0);
59  VIXL_CHECK(buffer.IsManaged());
60  VIXL_CHECK(!buffer.IsDirty());
61  VIXL_CHECK(buffer.GetRemainingBytes() == CodeBuffer::kDefaultCapacity);
62  VIXL_CHECK(buffer.GetSizeInBytes() == 0);
63  VIXL_CHECK(buffer.GetEndAddress<uintptr_t>() ==
64             buffer.GetStartAddress<uintptr_t>());
65}
66
67TEST(defaults) {
68  CodeBuffer buffer;
69  TestDefaultsHelper(buffer);
70}
71
72TEST(reset) {
73  CodeBuffer buffer;
74  // Update the buffer by writing to it.
75  buffer.Emit("placeholder data");
76  VIXL_CHECK(buffer.IsDirty());
77  VIXL_CHECK(buffer.GetSizeInBytes() > 0);
78  // Calling Reset() should reset it back to its default state. (It does not
79  // shrink the capacity, but it should not have grown here.)
80  VIXL_ASSERT(buffer.GetCapacity() == CodeBuffer::kDefaultCapacity);
81  buffer.Reset();
82  TestDefaultsHelper(buffer);
83}
84
85TEST(ensure_space) {
86  const size_t initial_capacity = 1234;
87  CodeBuffer buffer(initial_capacity);
88
89  // Requesting less space than we already have should have no effect.
90  for (size_t space = 0; space < initial_capacity; space++) {
91    buffer.EnsureSpaceFor(space);
92    VIXL_CHECK(buffer.GetCapacity() == initial_capacity);
93  }
94
95  // Requesting more memory grows the buffer by an unspecified amount.
96  buffer.EnsureSpaceFor(initial_capacity + 1);
97  VIXL_CHECK(buffer.GetCapacity() > initial_capacity);
98}
99
100TEST(emit) {
101  CodeBuffer buffer;
102  VIXL_ASSERT(buffer.GetSizeInBytes() == 0);
103
104  uint64_t base_value = 0x0100001000100101;
105  const char* test_string = "test string";
106  size_t expected_size = 0;
107
108  // Simple emissions. This should not align or pad in any way.
109  buffer.EmitData(&base_value, 7);
110  expected_size += 7;
111
112  buffer.EmitString(test_string);
113  expected_size += strlen(test_string) + 1;  // EmitString() emits the '\0'.
114
115  buffer.Emit64(static_cast<uint64_t>(base_value * 1));
116  buffer.Emit(static_cast<uint64_t>(base_value * 2));
117  expected_size += 16;
118
119  buffer.Emit32(static_cast<uint32_t>(base_value * 3));
120  buffer.Emit(static_cast<uint32_t>(base_value * 4));
121  expected_size += 8;
122
123  buffer.Emit16(static_cast<uint16_t>(base_value * 5));
124  buffer.Emit(static_cast<uint16_t>(base_value * 6));
125  expected_size += 4;
126
127  buffer.Emit8(static_cast<uint8_t>(base_value * 7));
128  buffer.Emit(static_cast<uint8_t>(base_value * 8));
129  expected_size += 2;
130
131  VIXL_CHECK(buffer.GetSizeInBytes() == expected_size);
132
133  buffer.SetClean();
134
135  // clang-format off
136  uint8_t expected[] = {
137    // EmitData
138    0x01, 0x01, 0x10, 0x00, 0x10, 0x00, 0x00,
139    // EmitString
140    't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g', '\0',
141    // Emit64
142    0x01, 0x01, 0x10, 0x00, 0x10, 0x00, 0x00, 0x01,
143    // Emit<uint64_t>
144    0x02, 0x02, 0x20, 0x00, 0x20, 0x00, 0x00, 0x02,
145    // Emit32
146    0x03, 0x03, 0x30, 0x00,
147    // Emit<uint32_t>
148    0x04, 0x04, 0x40, 0x00,
149    // Emit16
150    0x05, 0x05,
151    // Emit<uint16_t>
152    0x06, 0x06,
153    // Emit8
154    0x07,
155    // Emit<uint8_t>
156    0x08
157  };
158  // clang-format on
159
160  VIXL_ASSERT(expected_size == sizeof(expected));
161  VIXL_CHECK(memcmp(buffer.GetStartAddress<const void*>(),
162                    expected,
163                    expected_size) == 0);
164}
165
166}  // namespace vixl
167