1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdint.h>
18
19 #include "common_runtime_test.h"
20 #include "mirror/art_method-inl.h"
21 #include "quick/quick_method_frame_info.h"
22
23 namespace art {
24
25 class ArchTest : public CommonRuntimeTest {
26 protected:
CheckFrameSize(InstructionSet isa,Runtime::CalleeSaveType type,uint32_t save_size)27 static void CheckFrameSize(InstructionSet isa, Runtime::CalleeSaveType type, uint32_t save_size)
28 NO_THREAD_SAFETY_ANALYSIS {
29 Runtime* r = Runtime::Current();
30
31 Thread* t = Thread::Current();
32 t->TransitionFromSuspendedToRunnable(); // So we can create callee-save methods.
33
34 r->SetInstructionSet(isa);
35 mirror::ArtMethod* save_method = r->CreateCalleeSaveMethod(type);
36 r->SetCalleeSaveMethod(save_method, type);
37 QuickMethodFrameInfo frame_info = save_method->GetQuickFrameInfo();
38 EXPECT_EQ(frame_info.FrameSizeInBytes(), save_size) << "Expected and real size differs for "
39 << type << " core spills=" << std::hex << frame_info.CoreSpillMask() << " fp spills="
40 << frame_info.FpSpillMask() << std::dec;
41
42 t->TransitionFromRunnableToSuspended(ThreadState::kNative); // So we can shut down.
43 }
44 };
45
46
TEST_F(ArchTest,ARM)47 TEST_F(ArchTest, ARM) {
48 #include "arch/arm/asm_support_arm.h"
49 #undef ART_RUNTIME_ARCH_ARM_ASM_SUPPORT_ARM_H_
50
51
52 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
53 CheckFrameSize(InstructionSet::kArm, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE);
54 #else
55 LOG(WARNING) << "No frame size for SaveAll";
56 #endif
57 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
58 CheckFrameSize(InstructionSet::kArm, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE);
59 #else
60 LOG(WARNING) << "No frame size for RefsOnly";
61 #endif
62 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
63 CheckFrameSize(InstructionSet::kArm, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE);
64 #else
65 LOG(WARNING) << "No frame size for RefsAndArgs";
66 #endif
67
68
69 #ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
70 #undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
71 #endif
72 #ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
73 #undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
74 #endif
75 #ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
76 #undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
77 #endif
78 #ifdef THREAD_SELF_OFFSET
79 #undef THREAD_SELF_OFFSET
80 #endif
81 #ifdef THREAD_CARD_TABLE_OFFSET
82 #undef THREAD_CARD_TABLE_OFFSET
83 #endif
84 #ifdef THREAD_EXCEPTION_OFFSET
85 #undef THREAD_EXCEPTION_OFFSET
86 #endif
87 #ifdef THREAD_ID_OFFSET
88 #undef THREAD_ID_OFFSET
89 #endif
90 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
91 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
92 #endif
93 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
94 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
95 #endif
96 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
97 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
98 #endif
99 #ifdef HEAP_REFERENCE_SIZE
100 #undef HEAP_REFERENCE_SIZE
101 #endif
102 }
103
104
TEST_F(ArchTest,ARM64)105 TEST_F(ArchTest, ARM64) {
106 #include "arch/arm64/asm_support_arm64.h"
107 #undef ART_RUNTIME_ARCH_ARM64_ASM_SUPPORT_ARM64_H_
108
109
110 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
111 CheckFrameSize(InstructionSet::kArm64, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE);
112 #else
113 LOG(WARNING) << "No frame size for SaveAll";
114 #endif
115 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
116 CheckFrameSize(InstructionSet::kArm64, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE);
117 #else
118 LOG(WARNING) << "No frame size for RefsOnly";
119 #endif
120 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
121 CheckFrameSize(InstructionSet::kArm64, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE);
122 #else
123 LOG(WARNING) << "No frame size for RefsAndArgs";
124 #endif
125
126
127 #ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
128 #undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
129 #endif
130 #ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
131 #undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
132 #endif
133 #ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
134 #undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
135 #endif
136 #ifdef THREAD_SELF_OFFSET
137 #undef THREAD_SELF_OFFSET
138 #endif
139 #ifdef THREAD_CARD_TABLE_OFFSET
140 #undef THREAD_CARD_TABLE_OFFSET
141 #endif
142 #ifdef THREAD_EXCEPTION_OFFSET
143 #undef THREAD_EXCEPTION_OFFSET
144 #endif
145 #ifdef THREAD_ID_OFFSET
146 #undef THREAD_ID_OFFSET
147 #endif
148 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
149 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
150 #endif
151 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
152 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
153 #endif
154 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
155 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
156 #endif
157 #ifdef HEAP_REFERENCE_SIZE
158 #undef HEAP_REFERENCE_SIZE
159 #endif
160 }
161
162
TEST_F(ArchTest,MIPS)163 TEST_F(ArchTest, MIPS) {
164 #include "arch/mips/asm_support_mips.h"
165 #undef ART_RUNTIME_ARCH_MIPS_ASM_SUPPORT_MIPS_H_
166
167
168 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
169 CheckFrameSize(InstructionSet::kMips, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE);
170 #else
171 LOG(WARNING) << "No frame size for SaveAll";
172 #endif
173 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
174 CheckFrameSize(InstructionSet::kMips, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE);
175 #else
176 LOG(WARNING) << "No frame size for RefsOnly";
177 #endif
178 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
179 CheckFrameSize(InstructionSet::kMips, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE);
180 #else
181 LOG(WARNING) << "No frame size for RefsAndArgs";
182 #endif
183
184
185 #ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
186 #undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
187 #endif
188 #ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
189 #undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
190 #endif
191 #ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
192 #undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
193 #endif
194 #ifdef THREAD_SELF_OFFSET
195 #undef THREAD_SELF_OFFSET
196 #endif
197 #ifdef THREAD_CARD_TABLE_OFFSET
198 #undef THREAD_CARD_TABLE_OFFSET
199 #endif
200 #ifdef THREAD_EXCEPTION_OFFSET
201 #undef THREAD_EXCEPTION_OFFSET
202 #endif
203 #ifdef THREAD_ID_OFFSET
204 #undef THREAD_ID_OFFSET
205 #endif
206 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
207 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
208 #endif
209 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
210 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
211 #endif
212 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
213 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
214 #endif
215 #ifdef HEAP_REFERENCE_SIZE
216 #undef HEAP_REFERENCE_SIZE
217 #endif
218 }
219
220
TEST_F(ArchTest,X86)221 TEST_F(ArchTest, X86) {
222 #include "arch/x86/asm_support_x86.h"
223 #undef ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_H_
224
225
226 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
227 CheckFrameSize(InstructionSet::kX86, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE);
228 #else
229 LOG(WARNING) << "No frame size for SaveAll";
230 #endif
231 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
232 CheckFrameSize(InstructionSet::kX86, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE);
233 #else
234 LOG(WARNING) << "No frame size for RefsOnly";
235 #endif
236 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
237 CheckFrameSize(InstructionSet::kX86, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE);
238 #else
239 LOG(WARNING) << "No frame size for RefsAndArgs";
240 #endif
241
242
243 #ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
244 #undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
245 #endif
246 #ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
247 #undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
248 #endif
249 #ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
250 #undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
251 #endif
252 #ifdef THREAD_SELF_OFFSET
253 #undef THREAD_SELF_OFFSET
254 #endif
255 #ifdef THREAD_CARD_TABLE_OFFSET
256 #undef THREAD_CARD_TABLE_OFFSET
257 #endif
258 #ifdef THREAD_EXCEPTION_OFFSET
259 #undef THREAD_EXCEPTION_OFFSET
260 #endif
261 #ifdef THREAD_ID_OFFSET
262 #undef THREAD_ID_OFFSET
263 #endif
264 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
265 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
266 #endif
267 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
268 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
269 #endif
270 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
271 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
272 #endif
273 #ifdef HEAP_REFERENCE_SIZE
274 #undef HEAP_REFERENCE_SIZE
275 #endif
276 }
277
278
TEST_F(ArchTest,X86_64)279 TEST_F(ArchTest, X86_64) {
280 #include "arch/x86_64/asm_support_x86_64.h"
281 #undef ART_RUNTIME_ARCH_X86_64_ASM_SUPPORT_X86_64_H_
282
283
284 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
285 CheckFrameSize(InstructionSet::kX86_64, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE);
286 #else
287 LOG(WARNING) << "No frame size for SaveAll";
288 #endif
289 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
290 CheckFrameSize(InstructionSet::kX86_64, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE);
291 #else
292 LOG(WARNING) << "No frame size for RefsOnly";
293 #endif
294 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
295 CheckFrameSize(InstructionSet::kX86_64, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE);
296 #else
297 LOG(WARNING) << "No frame size for RefsAndArgs";
298 #endif
299
300
301 #ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
302 #undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
303 #endif
304 #ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
305 #undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
306 #endif
307 #ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
308 #undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
309 #endif
310 #ifdef THREAD_SELF_OFFSET
311 #undef THREAD_SELF_OFFSET
312 #endif
313 #ifdef THREAD_CARD_TABLE_OFFSET
314 #undef THREAD_CARD_TABLE_OFFSET
315 #endif
316 #ifdef THREAD_EXCEPTION_OFFSET
317 #undef THREAD_EXCEPTION_OFFSET
318 #endif
319 #ifdef THREAD_ID_OFFSET
320 #undef THREAD_ID_OFFSET
321 #endif
322 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
323 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
324 #endif
325 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
326 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
327 #endif
328 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
329 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
330 #endif
331 #ifdef HEAP_REFERENCE_SIZE
332 #undef HEAP_REFERENCE_SIZE
333 #endif
334 }
335
336
337 // The following tests are all for the running architecture. So we get away
338 // with just including it and not undefining it every time.
339
340 #if defined(__arm__)
341 #include "arch/arm/asm_support_arm.h"
342 #elif defined(__aarch64__)
343 #include "arch/arm64/asm_support_arm64.h"
344 #elif defined(__mips__)
345 #include "arch/mips/asm_support_mips.h"
346 #elif defined(__i386__)
347 #include "arch/x86/asm_support_x86.h"
348 #elif defined(__x86_64__)
349 #include "arch/x86_64/asm_support_x86_64.h"
350 #else
351 // This happens for the host test.
352 #ifdef __LP64__
353 #include "arch/x86_64/asm_support_x86_64.h"
354 #else
355 #include "arch/x86/asm_support_x86.h"
356 #endif
357 #endif
358
359
TEST_F(ArchTest,ThreadOffsets)360 TEST_F(ArchTest, ThreadOffsets) {
361 // Ugly hack, change when possible.
362 #ifdef __LP64__
363 #define POINTER_SIZE 8
364 #else
365 #define POINTER_SIZE 4
366 #endif
367
368 #if defined(THREAD_SELF_OFFSET)
369 ThreadOffset<POINTER_SIZE> self_offset = Thread::SelfOffset<POINTER_SIZE>();
370 EXPECT_EQ(self_offset.Int32Value(), THREAD_SELF_OFFSET);
371 #else
372 LOG(INFO) << "No Thread Self Offset found.";
373 #endif
374
375 #if defined(THREAD_CARD_TABLE_OFFSET)
376 ThreadOffset<POINTER_SIZE> card_offset = Thread::CardTableOffset<POINTER_SIZE>();
377 EXPECT_EQ(card_offset.Int32Value(), THREAD_CARD_TABLE_OFFSET);
378 #else
379 LOG(INFO) << "No Thread Card Table Offset found.";
380 #endif
381
382 #if defined(THREAD_EXCEPTION_OFFSET)
383 ThreadOffset<POINTER_SIZE> exc_offset = Thread::ExceptionOffset<POINTER_SIZE>();
384 EXPECT_EQ(exc_offset.Int32Value(), THREAD_EXCEPTION_OFFSET);
385 #else
386 LOG(INFO) << "No Thread Exception Offset found.";
387 #endif
388
389 #if defined(THREAD_ID_OFFSET)
390 ThreadOffset<POINTER_SIZE> id_offset = Thread::ThinLockIdOffset<POINTER_SIZE>();
391 EXPECT_EQ(id_offset.Int32Value(), THREAD_ID_OFFSET);
392 #else
393 LOG(INFO) << "No Thread ID Offset found.";
394 #endif
395 }
396
397
TEST_F(ArchTest,CalleeSaveMethodOffsets)398 TEST_F(ArchTest, CalleeSaveMethodOffsets) {
399 #if defined(RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET)
400 EXPECT_EQ(Runtime::GetCalleeSaveMethodOffset(Runtime::kSaveAll),
401 static_cast<size_t>(RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET));
402 #else
403 LOG(INFO) << "No Runtime Save-all Offset found.";
404 #endif
405
406 #if defined(RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET)
407 EXPECT_EQ(Runtime::GetCalleeSaveMethodOffset(Runtime::kRefsOnly),
408 static_cast<size_t>(RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET));
409 #else
410 LOG(INFO) << "No Runtime Refs-only Offset found.";
411 #endif
412
413 #if defined(RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET)
414 EXPECT_EQ(Runtime::GetCalleeSaveMethodOffset(Runtime::kRefsAndArgs),
415 static_cast<size_t>(RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET));
416 #else
417 LOG(INFO) << "No Runtime Refs-and-Args Offset found.";
418 #endif
419 }
420
421
TEST_F(ArchTest,HeapReferenceSize)422 TEST_F(ArchTest, HeapReferenceSize) {
423 #if defined(HEAP_REFERENCE_SIZE)
424 EXPECT_EQ(sizeof(mirror::HeapReference<mirror::Object>),
425 static_cast<size_t>(HEAP_REFERENCE_SIZE));
426 #else
427 LOG(INFO) << "No expected HeapReference Size found.";
428 #endif
429 }
430
TEST_F(ArchTest,StackReferenceSize)431 TEST_F(ArchTest, StackReferenceSize) {
432 #if defined(STACK_REFERENCE_SIZE)
433 EXPECT_EQ(sizeof(StackReference<mirror::Object>),
434 static_cast<size_t>(STACK_REFERENCE_SIZE));
435 #else
436 LOG(INFO) << "No expected StackReference Size #define found.";
437 #endif
438 }
439
440 } // namespace art
441