Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
assembler_test.cc
Go to the documentation of this file.
1// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
7#include "vm/globals.h"
8#include "vm/hash.h"
9#include "vm/os.h"
10#include "vm/random.h"
11#include "vm/simulator.h"
12#include "vm/unit_test.h"
13#include "vm/virtual_memory.h"
14
15namespace dart {
16
17namespace compiler {
18ASSEMBLER_TEST_EXTERN(StoreIntoObject);
19} // namespace compiler
20
21ASSEMBLER_TEST_RUN(StoreIntoObject, test) {
22#define TEST_CODE(value, growable_array, thread) \
23 test->Invoke<void, ObjectPtr, ObjectPtr, Thread*>(value, growable_array, \
24 thread)
25
26 const Array& old_array = Array::Handle(Array::New(3, Heap::kOld));
27 const Array& new_array = Array::Handle(Array::New(3, Heap::kNew));
32 Smi& smi = Smi::Handle();
33 Thread* thread = Thread::Current();
34
35 EXPECT(old_array.ptr() == grow_old_array.data());
36 EXPECT(!thread->StoreBufferContains(grow_old_array.ptr()));
37 EXPECT(old_array.ptr() == grow_new_array.data());
38 EXPECT(!thread->StoreBufferContains(grow_new_array.ptr()));
39
40 // Store Smis into the old object.
41 for (int i = -128; i < 128; i++) {
42 smi = Smi::New(i);
43 TEST_CODE(smi.ptr(), grow_old_array.ptr(), thread);
44 EXPECT(static_cast<CompressedObjectPtr>(smi.ptr()) ==
45 static_cast<CompressedObjectPtr>(grow_old_array.data()));
46 EXPECT(!thread->StoreBufferContains(grow_old_array.ptr()));
47 }
48
49 // Store an old object into the old object.
50 TEST_CODE(old_array.ptr(), grow_old_array.ptr(), thread);
51 EXPECT(old_array.ptr() == grow_old_array.data());
52 EXPECT(!thread->StoreBufferContains(grow_old_array.ptr()));
53
54 // Store a new object into the old object.
55 TEST_CODE(new_array.ptr(), grow_old_array.ptr(), thread);
56 EXPECT(new_array.ptr() == grow_old_array.data());
57 EXPECT(thread->StoreBufferContains(grow_old_array.ptr()));
58
59 // Store a new object into the new object.
60 TEST_CODE(new_array.ptr(), grow_new_array.ptr(), thread);
61 EXPECT(new_array.ptr() == grow_new_array.data());
62 EXPECT(!thread->StoreBufferContains(grow_new_array.ptr()));
63
64 // Store an old object into the new object.
65 TEST_CODE(old_array.ptr(), grow_new_array.ptr(), thread);
66 EXPECT(old_array.ptr() == grow_new_array.data());
67 EXPECT(!thread->StoreBufferContains(grow_new_array.ptr()));
68}
69
70namespace compiler {
71#define __ assembler->
72
73ASSEMBLER_TEST_GENERATE(InstantiateTypeArgumentsHashKeys, assembler) {
74#if defined(TARGET_ARCH_IA32)
75 const Register kArg1Reg = EAX;
76 const Register kArg2Reg = ECX;
77 __ movl(kArg1Reg, Address(ESP, 2 * target::kWordSize));
78 __ movl(kArg2Reg, Address(ESP, 1 * target::kWordSize));
79#else
82#endif
86 __ Ret();
87}
88
89#undef __
90} // namespace compiler
91
92ASSEMBLER_TEST_RUN(InstantiateTypeArgumentsHashKeys, test) {
93 typedef uint32_t (*HashKeysCode)(uword hash, uword other) DART_UNUSED;
94
95 auto hash_test = [&](const Expect& expect, uword hash1, uword hash2) {
96 const uint32_t expected = FinalizeHash(CombineHashes(hash1, hash2));
97 const uint32_t got = EXECUTE_TEST_CODE_UWORD_UWORD_UINT32(
98 HashKeysCode, test->entry(), hash1, hash2);
99 if (got == expected) return;
100 TextBuffer buffer(128);
101 buffer.Printf("For hash1 = %" Pu " and hash2 = %" Pu
102 ": expected result %u, got result %u",
103 hash1, hash2, expected, got);
104 expect.Fail("%s", buffer.buffer());
105 };
106
107#define HASH_TEST(hash1, hash2) \
108 hash_test(Expect(__FILE__, __LINE__), hash1, hash2)
109
110 const intptr_t kNumRandomTests = 500;
111 Random random;
112
113 // First, fixed and random 32 bit tests for all architectures.
114 HASH_TEST(1, 1);
115 HASH_TEST(10, 20);
116 HASH_TEST(20, 10);
119
120 for (intptr_t i = 0; i < kNumRandomTests; i++) {
121 const uword hash1 = random.NextUInt32();
122 const uword hash2 = random.NextUInt32();
123 HASH_TEST(hash1, hash2);
124 }
125
126#if defined(TARGET_ARCH_IS_64_BIT)
127 // Now 64-bit tests on 64-bit architectures.
130
131 for (intptr_t i = 0; i < kNumRandomTests; i++) {
132 const uword hash1 = random.NextUInt64();
133 const uword hash2 = random.NextUInt64();
134 HASH_TEST(hash1, hash2);
135 }
136#endif
137#undef HASH_TEST
138}
139
140#define __ assembler->
141
142#if defined(TARGET_ARCH_IA32)
143const Register kArg1Reg = EAX;
144const Register kArg2Reg = ECX;
145#else
148#endif
149
150#define LOAD_FROM_BOX_TEST(SIZE, TYPE, VALUE, SAME_REGISTER) \
151 ASSEMBLER_TEST_GENERATE(Load##SIZE##FromBoxOrSmi##VALUE##SAME_REGISTER, \
152 assembler) { \
153 const bool same_register = SAME_REGISTER; \
154 \
155 const Register src = kArg1Reg; \
156 const Register dst = same_register ? src : kArg2Reg; \
157 const TYPE value = VALUE; \
158 \
159 EnterTestFrame(assembler); \
160 \
161 __ LoadObject(src, Integer::ZoneHandle(Integer::New(value, Heap::kOld))); \
162 __ Load##SIZE##FromBoxOrSmi(dst, src); \
163 __ MoveRegister(CallingConventions::kReturnReg, dst); \
164 \
165 LeaveTestFrame(assembler); \
166 \
167 __ Ret(); \
168 } \
169 \
170 ASSEMBLER_TEST_RUN(Load##SIZE##FromBoxOrSmi##VALUE##SAME_REGISTER, test) { \
171 const int64_t res = test->InvokeWithCodeAndThread<int64_t>(); \
172 EXPECT_EQ(static_cast<TYPE>(VALUE), static_cast<TYPE>(res)); \
173 }
174
175LOAD_FROM_BOX_TEST(Word, intptr_t, 0, true)
176LOAD_FROM_BOX_TEST(Word, intptr_t, 0, false)
177LOAD_FROM_BOX_TEST(Word, intptr_t, 1, true)
178LOAD_FROM_BOX_TEST(Word, intptr_t, 1, false)
179#if defined(TARGET_ARCH_IS_32_BIT)
180LOAD_FROM_BOX_TEST(Word, intptr_t, 0x7FFFFFFF, true)
181LOAD_FROM_BOX_TEST(Word, intptr_t, 0x7FFFFFFF, false)
182LOAD_FROM_BOX_TEST(Word, intptr_t, 0x80000000, true)
183LOAD_FROM_BOX_TEST(Word, intptr_t, 0x80000000, false)
184LOAD_FROM_BOX_TEST(Word, intptr_t, 0xFFFFFFFF, true)
185LOAD_FROM_BOX_TEST(Word, intptr_t, 0xFFFFFFFF, false)
186#else
187LOAD_FROM_BOX_TEST(Word, intptr_t, 0x7FFFFFFFFFFFFFFF, true)
188LOAD_FROM_BOX_TEST(Word, intptr_t, 0x7FFFFFFFFFFFFFFF, false)
189LOAD_FROM_BOX_TEST(Word, intptr_t, 0x8000000000000000, true)
190LOAD_FROM_BOX_TEST(Word, intptr_t, 0x8000000000000000, false)
191LOAD_FROM_BOX_TEST(Word, intptr_t, 0xFFFFFFFFFFFFFFFF, true)
192LOAD_FROM_BOX_TEST(Word, intptr_t, 0xFFFFFFFFFFFFFFFF, false)
193#endif
194
195LOAD_FROM_BOX_TEST(Int32, int32_t, 0, true)
196LOAD_FROM_BOX_TEST(Int32, int32_t, 0, false)
197LOAD_FROM_BOX_TEST(Int32, int32_t, 1, true)
198LOAD_FROM_BOX_TEST(Int32, int32_t, 1, false)
199LOAD_FROM_BOX_TEST(Int32, int32_t, 0x7FFFFFFF, true)
200LOAD_FROM_BOX_TEST(Int32, int32_t, 0x7FFFFFFF, false)
201LOAD_FROM_BOX_TEST(Int32, int32_t, 0x80000000, true)
202LOAD_FROM_BOX_TEST(Int32, int32_t, 0x80000000, false)
203LOAD_FROM_BOX_TEST(Int32, int32_t, 0xFFFFFFFF, true)
204LOAD_FROM_BOX_TEST(Int32, int32_t, 0xFFFFFFFF, false)
205
206#if !defined(TARGET_ARCH_IS_32_BIT)
207LOAD_FROM_BOX_TEST(Int64, int64_t, 0, true)
208LOAD_FROM_BOX_TEST(Int64, int64_t, 0, false)
209LOAD_FROM_BOX_TEST(Int64, int64_t, 1, true)
210LOAD_FROM_BOX_TEST(Int64, int64_t, 1, false)
211LOAD_FROM_BOX_TEST(Int64, int64_t, 0x7FFFFFFFFFFFFFFF, true)
212LOAD_FROM_BOX_TEST(Int64, int64_t, 0x7FFFFFFFFFFFFFFF, false)
213LOAD_FROM_BOX_TEST(Int64, int64_t, 0x8000000000000000, true)
214LOAD_FROM_BOX_TEST(Int64, int64_t, 0x8000000000000000, false)
215LOAD_FROM_BOX_TEST(Int64, int64_t, 0xFFFFFFFFFFFFFFFF, true)
216LOAD_FROM_BOX_TEST(Int64, int64_t, 0xFFFFFFFFFFFFFFFF, false)
217#endif
218
219#if defined(TARGET_ARCH_ARM)
220ISOLATE_UNIT_TEST_CASE(Assembler_Regress54621) {
221 auto zone = thread->zone();
222 const classid_t cid = kTypedDataInt32ArrayCid;
223 const intptr_t index_scale = 1;
224 const intptr_t kMaxAllowedOffsetForExternal = (2 << 11) - 1;
225 auto& smi = Smi::Handle(zone, Smi::New(kMaxAllowedOffsetForExternal));
226 bool needs_base;
228 smi, /*is_load=*/true,
229 /*is_external=*/true, cid, index_scale, &needs_base));
230 EXPECT(!needs_base);
232 smi, /*is_load=*/true,
233 /*is_external=*/false, cid, index_scale, &needs_base));
234 EXPECT(needs_base);
235 // Double-checking we're on a boundary of what's allowed.
236 smi = Smi::New(kMaxAllowedOffsetForExternal + 1);
238 smi, /*is_load=*/true,
239 /*is_external=*/false, cid, index_scale));
241 smi, /*is_load=*/true,
242 /*is_external=*/true, cid, index_scale));
243}
244#endif
245
246} // namespace dart
static uint32_t hash(const SkShaderBase::GradientInfo &v)
#define EXPECT(type, expectedAlignment, expectedSize)
#define __
#define LOAD_FROM_BOX_TEST(SIZE, TYPE, VALUE, SAME_REGISTER)
#define HASH_TEST(hash1, hash2)
#define TEST_CODE(value, growable_array, thread)
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10933
static const Register ArgumentRegisters[]
static constexpr Register kReturnReg
void Fail(const char *format,...) const PRINTF_ATTRIBUTE(2
Definition assert.cc:58
static GrowableObjectArrayPtr New(Heap::Space space=Heap::kNew)
Definition object.h:11118
ArrayPtr data() const
Definition object.h:11056
@ kNew
Definition heap.h:38
@ kOld
Definition heap.h:39
ObjectPtr ptr() const
Definition object.h:332
static Object & Handle()
Definition object.h:407
uint64_t NextUInt64()
Definition random.h:26
uint32_t NextUInt32()
Definition random.cc:73
static SmiPtr New(intptr_t value)
Definition object.h:9985
static Thread * Current()
Definition thread.h:361
static bool AddressCanHoldConstantIndex(const Object &constant, bool is_load, bool is_external, intptr_t cid, intptr_t index_scale, bool *needs_base=nullptr)
static const uint8_t buffer[]
uint32_t CombineHashes(uint32_t hash, uint32_t other_hash)
Definition hash.h:12
int32_t classid_t
Definition globals.h:524
constexpr uint64_t kMaxUint64
Definition globals.h:487
constexpr uint32_t kMaxUint32
Definition globals.h:484
uintptr_t uword
Definition globals.h:501
const Register kArg2Reg
const intptr_t cid
uint32_t FinalizeHash(uint32_t hash, intptr_t hashbits=kBitsPerInt32)
Definition hash.h:20
const Register kArg1Reg
constexpr uint16_t kMaxUint16
Definition globals.h:481
#define Pu
Definition globals.h:409
#define DART_UNUSED
Definition globals.h:269
#define ASSEMBLER_TEST_GENERATE(name, assembler)
Definition unit_test.h:89
#define ISOLATE_UNIT_TEST_CASE(name)
Definition unit_test.h:64
#define ASSEMBLER_TEST_EXTERN(name)
Definition unit_test.h:94
#define ASSEMBLER_TEST_RUN(name, test)
Definition unit_test.h:127