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 <cstdio>
18 
19 #include "art_field-inl.h"
20 #include "art_method-inl.h"
21 #include "base/callee_save_type.h"
22 #include "base/pointer_size.h"
23 #include "class_linker-inl.h"
24 #include "class_root-inl.h"
25 #include "common_runtime_test.h"
26 #include "entrypoints/quick/quick_entrypoints_enum.h"
27 #include "imt_conflict_table.h"
28 #include "jni/jni_internal.h"
29 #include "linear_alloc-inl.h"
30 #include "mirror/class-alloc-inl.h"
31 #include "mirror/string-inl.h"
32 #include "mirror/object_array-alloc-inl.h"
33 #include "scoped_thread_state_change-inl.h"
34 
35 namespace art HIDDEN {
36 
37 
38 class StubTest : public CommonRuntimeTest {
39  protected:
40   // We need callee-save methods set up in the Runtime for exceptions.
SetUp()41   void SetUp() override {
42     // Do the normal setup.
43     CommonRuntimeTest::SetUp();
44 
45     {
46       // Create callee-save methods
47       ScopedObjectAccess soa(Thread::Current());
48       runtime_->SetInstructionSet(kRuntimeISA);
49       for (uint32_t i = 0; i < static_cast<uint32_t>(CalleeSaveType::kLastCalleeSaveType); ++i) {
50         CalleeSaveType type = CalleeSaveType(i);
51         if (!runtime_->HasCalleeSaveMethod(type)) {
52           runtime_->SetCalleeSaveMethod(runtime_->CreateCalleeSaveMethod(), type);
53         }
54       }
55     }
56   }
57 
SetUpRuntimeOptions(RuntimeOptions * options)58   void SetUpRuntimeOptions(RuntimeOptions *options) override {
59     // Use a smaller heap
60     for (std::pair<std::string, const void*>& pair : *options) {
61       if (pair.first.find("-Xmx") == 0) {
62         pair.first = "-Xmx4M";  // Smallest we can go.
63       }
64     }
65     options->push_back(std::make_pair("-Xint", nullptr));
66   }
67 
68   // Helper function needed since TEST_F makes a new class.
GetTlsPtr(Thread * self)69   Thread::tls_ptr_sized_values* GetTlsPtr(Thread* self) {
70     return &self->tlsPtr_;
71   }
72 
73  public:
Invoke3(size_t arg0,size_t arg1,size_t arg2,uintptr_t code,Thread * self)74   size_t Invoke3(size_t arg0, size_t arg1, size_t arg2, uintptr_t code, Thread* self) {
75     return Invoke3WithReferrer(arg0, arg1, arg2, code, self, nullptr);
76   }
77 
78   // TODO: Set up a frame according to referrer's specs.
Invoke3WithReferrer(size_t arg0,size_t arg1,size_t arg2,uintptr_t code,Thread * self,ArtMethod * referrer)79   size_t Invoke3WithReferrer(size_t arg0, size_t arg1, size_t arg2, uintptr_t code, Thread* self,
80                              ArtMethod* referrer) {
81     return Invoke3WithReferrerAndHidden(arg0, arg1, arg2, code, self, referrer, 0);
82   }
83 
84   // TODO: Set up a frame according to referrer's specs.
Invoke3WithReferrerAndHidden(size_t arg0,size_t arg1,size_t arg2,uintptr_t code,Thread * self,ArtMethod * referrer,size_t hidden)85   size_t Invoke3WithReferrerAndHidden(size_t arg0, size_t arg1, size_t arg2, uintptr_t code,
86                                       Thread* self, ArtMethod* referrer, size_t hidden) {
87     // Push a transition back into managed code onto the linked list in thread.
88     ManagedStack fragment;
89     self->PushManagedStackFragment(&fragment);
90 
91     size_t result;
92     size_t fpr_result = 0;
93 #if defined(__i386__)
94     // TODO: Set the thread?
95 #define PUSH(reg) "push " # reg "\n\t .cfi_adjust_cfa_offset 4\n\t"
96 #define POP(reg) "pop " # reg "\n\t .cfi_adjust_cfa_offset -4\n\t"
97     __asm__ __volatile__(
98         "movd %[hidden], %%xmm7\n\t"  // This is a memory op, so do this early. If it is off of
99                                       // esp, then we won't be able to access it after spilling.
100 
101         // Spill 6 registers.
102         PUSH(%%ebx)
103         PUSH(%%ecx)
104         PUSH(%%edx)
105         PUSH(%%esi)
106         PUSH(%%edi)
107         PUSH(%%ebp)
108 
109         // Store the inputs to the stack, but keep the referrer up top, less work.
110         PUSH(%[referrer])           // Align stack.
111         PUSH(%[referrer])           // Store referrer
112 
113         PUSH(%[arg0])
114         PUSH(%[arg1])
115         PUSH(%[arg2])
116         PUSH(%[code])
117         // Now read them back into the required registers.
118         POP(%%edi)
119         POP(%%edx)
120         POP(%%ecx)
121         POP(%%eax)
122         // Call is prepared now.
123 
124         "call *%%edi\n\t"           // Call the stub
125         "addl $8, %%esp\n\t"        // Pop referrer and padding.
126         ".cfi_adjust_cfa_offset -8\n\t"
127 
128         // Restore 6 registers.
129         POP(%%ebp)
130         POP(%%edi)
131         POP(%%esi)
132         POP(%%edx)
133         POP(%%ecx)
134         POP(%%ebx)
135 
136         : "=a" (result)
137           // Use the result from eax
138         : [arg0] "r"(arg0), [arg1] "r"(arg1), [arg2] "r"(arg2), [code] "r"(code),
139           [referrer]"r"(referrer), [hidden]"m"(hidden)
140           // This places code into edi, arg0 into eax, arg1 into ecx, and arg2 into edx
141         : "memory", "xmm7");  // clobber.
142 #undef PUSH
143 #undef POP
144 #elif defined(__arm__)
145     __asm__ __volatile__(
146         "push {r1-r12, lr}\n\t"     // Save state, 13*4B = 52B
147         ".cfi_adjust_cfa_offset 52\n\t"
148         "push {r9}\n\t"
149         ".cfi_adjust_cfa_offset 4\n\t"
150         "mov r9, %[referrer]\n\n"
151         "str r9, [sp, #-8]!\n\t"   // Push referrer, +8B padding so 16B aligned
152         ".cfi_adjust_cfa_offset 8\n\t"
153         "ldr r9, [sp, #8]\n\t"
154 
155         // Push everything on the stack, so we don't rely on the order. What a mess. :-(
156         "sub sp, sp, #24\n\t"
157         "str %[arg0], [sp]\n\t"
158         "str %[arg1], [sp, #4]\n\t"
159         "str %[arg2], [sp, #8]\n\t"
160         "str %[code], [sp, #12]\n\t"
161         "str %[self], [sp, #16]\n\t"
162         "str %[hidden], [sp, #20]\n\t"
163         "ldr r0, [sp]\n\t"
164         "ldr r1, [sp, #4]\n\t"
165         "ldr r2, [sp, #8]\n\t"
166         "ldr r3, [sp, #12]\n\t"
167         "ldr r9, [sp, #16]\n\t"
168         "ldr r12, [sp, #20]\n\t"
169         "add sp, sp, #24\n\t"
170 
171         "blx r3\n\t"                // Call the stub
172         "add sp, sp, #12\n\t"       // Pop null and padding
173         ".cfi_adjust_cfa_offset -12\n\t"
174         "pop {r1-r12, lr}\n\t"      // Restore state
175         ".cfi_adjust_cfa_offset -52\n\t"
176         "mov %[result], r0\n\t"     // Save the result
177         : [result] "=r" (result)
178           // Use the result from r0
179         : [arg0] "r"(arg0), [arg1] "r"(arg1), [arg2] "r"(arg2), [code] "r"(code), [self] "r"(self),
180           [referrer] "r"(referrer), [hidden] "r"(hidden)
181         : "r0", "memory");  // clobber.
182 #elif defined(__aarch64__)
183     __asm__ __volatile__(
184         // Spill x0-x7 which we say we don't clobber. May contain args.
185         "sub sp, sp, #80\n\t"
186         ".cfi_adjust_cfa_offset 80\n\t"
187         "stp x0, x1, [sp]\n\t"
188         "stp x2, x3, [sp, #16]\n\t"
189         "stp x4, x5, [sp, #32]\n\t"
190         "stp x6, x7, [sp, #48]\n\t"
191         // To be extra defensive, store x20,x21. We do this because some of the stubs might make a
192         // transition into the runtime via the blr instruction below and *not* save x20.
193         "stp x20, x21, [sp, #64]\n\t"
194 
195         "sub sp, sp, #16\n\t"          // Reserve stack space, 16B aligned
196         ".cfi_adjust_cfa_offset 16\n\t"
197         "str %[referrer], [sp]\n\t"    // referrer
198 
199         // Push everything on the stack, so we don't rely on the order. What a mess. :-(
200         "sub sp, sp, #48\n\t"
201         ".cfi_adjust_cfa_offset 48\n\t"
202         // All things are "r" constraints, so direct str/stp should work.
203         "stp %[arg0], %[arg1], [sp]\n\t"
204         "stp %[arg2], %[code], [sp, #16]\n\t"
205         "stp %[self], %[hidden], [sp, #32]\n\t"
206 
207         // Now we definitely have x0-x3 free, use it to garble d8 - d15
208         "movk x0, #0xfad0\n\t"
209         "movk x0, #0xebad, lsl #16\n\t"
210         "movk x0, #0xfad0, lsl #32\n\t"
211         "movk x0, #0xebad, lsl #48\n\t"
212         "fmov d8, x0\n\t"
213         "add x0, x0, 1\n\t"
214         "fmov d9, x0\n\t"
215         "add x0, x0, 1\n\t"
216         "fmov d10, x0\n\t"
217         "add x0, x0, 1\n\t"
218         "fmov d11, x0\n\t"
219         "add x0, x0, 1\n\t"
220         "fmov d12, x0\n\t"
221         "add x0, x0, 1\n\t"
222         "fmov d13, x0\n\t"
223         "add x0, x0, 1\n\t"
224         "fmov d14, x0\n\t"
225         "add x0, x0, 1\n\t"
226         "fmov d15, x0\n\t"
227 
228         // Load call params into the right registers.
229         "ldp x0, x1, [sp]\n\t"
230         "ldp x2, x3, [sp, #16]\n\t"
231         "ldp x19, x17, [sp, #32]\n\t"
232         "add sp, sp, #48\n\t"
233         ".cfi_adjust_cfa_offset -48\n\t"
234 
235         "blr x3\n\t"              // Call the stub
236         "mov x8, x0\n\t"          // Store result
237         "add sp, sp, #16\n\t"     // Drop the quick "frame"
238         ".cfi_adjust_cfa_offset -16\n\t"
239 
240         // Test d8 - d15. We can use x1 and x2.
241         "movk x1, #0xfad0\n\t"
242         "movk x1, #0xebad, lsl #16\n\t"
243         "movk x1, #0xfad0, lsl #32\n\t"
244         "movk x1, #0xebad, lsl #48\n\t"
245         "fmov x2, d8\n\t"
246         "cmp x1, x2\n\t"
247         "b.ne 1f\n\t"
248         "add x1, x1, 1\n\t"
249 
250         "fmov x2, d9\n\t"
251         "cmp x1, x2\n\t"
252         "b.ne 1f\n\t"
253         "add x1, x1, 1\n\t"
254 
255         "fmov x2, d10\n\t"
256         "cmp x1, x2\n\t"
257         "b.ne 1f\n\t"
258         "add x1, x1, 1\n\t"
259 
260         "fmov x2, d11\n\t"
261         "cmp x1, x2\n\t"
262         "b.ne 1f\n\t"
263         "add x1, x1, 1\n\t"
264 
265         "fmov x2, d12\n\t"
266         "cmp x1, x2\n\t"
267         "b.ne 1f\n\t"
268         "add x1, x1, 1\n\t"
269 
270         "fmov x2, d13\n\t"
271         "cmp x1, x2\n\t"
272         "b.ne 1f\n\t"
273         "add x1, x1, 1\n\t"
274 
275         "fmov x2, d14\n\t"
276         "cmp x1, x2\n\t"
277         "b.ne 1f\n\t"
278         "add x1, x1, 1\n\t"
279 
280         "fmov x2, d15\n\t"
281         "cmp x1, x2\n\t"
282         "b.ne 1f\n\t"
283 
284         "mov x9, #0\n\t"              // Use x9 as flag, in clobber list
285 
286         // Finish up.
287         "2:\n\t"
288         "ldp x0, x1, [sp]\n\t"        // Restore stuff not named clobbered, may contain fpr_result
289         "ldp x2, x3, [sp, #16]\n\t"
290         "ldp x4, x5, [sp, #32]\n\t"
291         "ldp x6, x7, [sp, #48]\n\t"
292         "ldp x20, x21, [sp, #64]\n\t"
293         "add sp, sp, #80\n\t"         // Free stack space, now sp as on entry
294         ".cfi_adjust_cfa_offset -80\n\t"
295 
296         "str x9, %[fpr_result]\n\t"   // Store the FPR comparison result
297         "mov %[result], x8\n\t"              // Store the call result
298 
299         "b 3f\n\t"                     // Goto end
300 
301         // Failed fpr verification.
302         "1:\n\t"
303         "mov x9, #1\n\t"
304         "b 2b\n\t"                     // Goto finish-up
305 
306         // End
307         "3:\n\t"
308         : [result] "=r" (result)
309           // Use the result from r0
310         : [arg0] "0"(arg0), [arg1] "r"(arg1), [arg2] "r"(arg2), [code] "r"(code), [self] "r"(self),
311           [referrer] "r"(referrer), [hidden] "r"(hidden), [fpr_result] "m" (fpr_result)
312           // X18 is a reserved register, cannot be clobbered.
313           // Leave one register unclobbered, which is needed for compiling with
314           // -fstack-protector-strong. According to AAPCS64 registers x9-x15 are caller-saved,
315           // which means we should unclobber one of the callee-saved registers that are unused.
316           // Here we use x20.
317           // http://b/72613441, Clang 7.0 asks for one more register, so we do not reserve x21.
318         : "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19",
319           "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x30",
320           "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
321           "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
322           "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
323           "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
324           "memory");
325 #elif defined(__x86_64__) && !defined(__APPLE__)
326 #define PUSH(reg) "pushq " # reg "\n\t .cfi_adjust_cfa_offset 8\n\t"
327 #define POP(reg) "popq " # reg "\n\t .cfi_adjust_cfa_offset -8\n\t"
328     // Note: Uses the native convention. We do a callee-save regimen by manually spilling and
329     //       restoring almost all registers.
330     // TODO: Set the thread?
331     __asm__ __volatile__(
332         // Spill almost everything (except rax, rsp). 14 registers.
333         PUSH(%%rbx)
334         PUSH(%%rcx)
335         PUSH(%%rdx)
336         PUSH(%%rsi)
337         PUSH(%%rdi)
338         PUSH(%%rbp)
339         PUSH(%%r8)
340         PUSH(%%r9)
341         PUSH(%%r10)
342         PUSH(%%r11)
343         PUSH(%%r12)
344         PUSH(%%r13)
345         PUSH(%%r14)
346         PUSH(%%r15)
347 
348         PUSH(%[referrer])              // Push referrer & 16B alignment padding
349         PUSH(%[referrer])
350 
351         // Now juggle the input registers.
352         PUSH(%[arg0])
353         PUSH(%[arg1])
354         PUSH(%[arg2])
355         PUSH(%[hidden])
356         PUSH(%[code])
357         POP(%%r8)
358         POP(%%rax)
359         POP(%%rdx)
360         POP(%%rsi)
361         POP(%%rdi)
362 
363         "call *%%r8\n\t"                  // Call the stub
364         "addq $16, %%rsp\n\t"             // Pop null and padding
365         ".cfi_adjust_cfa_offset -16\n\t"
366 
367         POP(%%r15)
368         POP(%%r14)
369         POP(%%r13)
370         POP(%%r12)
371         POP(%%r11)
372         POP(%%r10)
373         POP(%%r9)
374         POP(%%r8)
375         POP(%%rbp)
376         POP(%%rdi)
377         POP(%%rsi)
378         POP(%%rdx)
379         POP(%%rcx)
380         POP(%%rbx)
381 
382         : "=a" (result)
383         // Use the result from rax
384         : [arg0] "r"(arg0), [arg1] "r"(arg1), [arg2] "r"(arg2), [code] "r"(code),
385           [referrer] "r"(referrer), [hidden] "r"(hidden)
386         // This places arg0 into rdi, arg1 into rsi, arg2 into rdx, and code into some other
387         // register. We can't use "b" (rbx), as ASAN uses this for the frame pointer.
388         : "memory");  // We spill and restore (almost) all registers, so only mention memory here.
389 #undef PUSH
390 #undef POP
391 #else
392     UNUSED(arg0, arg1, arg2, code, referrer, hidden);
393     LOG(WARNING) << "Was asked to invoke for an architecture I do not understand.";
394     result = 0;
395 #endif
396     // Pop transition.
397     self->PopManagedStackFragment(fragment);
398 
399     fp_result = fpr_result;
400     EXPECT_EQ(0U, fp_result);
401 
402     return result;
403   }
404 
GetEntrypoint(Thread * self,QuickEntrypointEnum entrypoint)405   static uintptr_t GetEntrypoint(Thread* self, QuickEntrypointEnum entrypoint) {
406     int32_t offset;
407     offset = GetThreadOffset<kRuntimePointerSize>(entrypoint).Int32Value();
408     return *reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(self) + offset);
409   }
410 
411  protected:
412   size_t fp_result;
413 };
414 
415 
TEST_F(StubTest,Memcpy)416 TEST_F(StubTest, Memcpy) {
417 #if defined(__i386__) || (defined(__x86_64__) && !defined(__APPLE__))
418   Thread* self = Thread::Current();
419 
420   uint32_t orig[20];
421   uint32_t trg[20];
422   for (size_t i = 0; i < 20; ++i) {
423     orig[i] = i;
424     trg[i] = 0;
425   }
426 
427   Invoke3(reinterpret_cast<size_t>(&trg[4]), reinterpret_cast<size_t>(&orig[4]),
428           10 * sizeof(uint32_t), StubTest::GetEntrypoint(self, kQuickMemcpy), self);
429 
430   EXPECT_EQ(orig[0], trg[0]);
431 
432   for (size_t i = 1; i < 4; ++i) {
433     EXPECT_NE(orig[i], trg[i]);
434   }
435 
436   for (size_t i = 4; i < 14; ++i) {
437     EXPECT_EQ(orig[i], trg[i]);
438   }
439 
440   for (size_t i = 14; i < 20; ++i) {
441     EXPECT_NE(orig[i], trg[i]);
442   }
443 
444   // TODO: Test overlapping?
445 
446 #else
447   LOG(INFO) << "Skipping memcpy as I don't know how to do that on " << kRuntimeISA;
448   // Force-print to std::cout so it's also outside the logcat.
449   std::cout << "Skipping memcpy as I don't know how to do that on " << kRuntimeISA << std::endl;
450 #endif
451 }
452 
TEST_F(StubTest,LockObject)453 TEST_F(StubTest, LockObject) {
454 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
455     (defined(__x86_64__) && !defined(__APPLE__))
456   static constexpr size_t kThinLockLoops = 100;
457 
458   Thread* self = Thread::Current();
459 
460   const uintptr_t art_quick_lock_object = StubTest::GetEntrypoint(self, kQuickLockObject);
461 
462   // Create an object
463   ScopedObjectAccess soa(self);
464   // garbage is created during ClassLinker::Init
465 
466   StackHandleScope<2> hs(soa.Self());
467   Handle<mirror::String> obj(
468       hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!")));
469   LockWord lock = obj->GetLockWord(false);
470   LockWord::LockState old_state = lock.GetState();
471   EXPECT_EQ(LockWord::LockState::kUnlocked, old_state);
472 
473   Invoke3(reinterpret_cast<size_t>(obj.Get()), 0U, 0U, art_quick_lock_object, self);
474 
475   LockWord lock_after = obj->GetLockWord(false);
476   LockWord::LockState new_state = lock_after.GetState();
477   EXPECT_EQ(LockWord::LockState::kThinLocked, new_state);
478   EXPECT_EQ(lock_after.ThinLockCount(), 0U);  // Thin lock starts count at zero
479 
480   for (size_t i = 1; i < kThinLockLoops; ++i) {
481     Invoke3(reinterpret_cast<size_t>(obj.Get()), 0U, 0U, art_quick_lock_object, self);
482 
483     // Check we're at lock count i
484 
485     LockWord l_inc = obj->GetLockWord(false);
486     LockWord::LockState l_inc_state = l_inc.GetState();
487     EXPECT_EQ(LockWord::LockState::kThinLocked, l_inc_state);
488     EXPECT_EQ(l_inc.ThinLockCount(), i);
489   }
490 
491   // Force a fat lock by running identity hashcode to fill up lock word.
492   Handle<mirror::String> obj2(hs.NewHandle(
493       mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!")));
494 
495   obj2->IdentityHashCode();
496 
497   Invoke3(reinterpret_cast<size_t>(obj2.Get()), 0U, 0U, art_quick_lock_object, self);
498 
499   LockWord lock_after2 = obj2->GetLockWord(false);
500   LockWord::LockState new_state2 = lock_after2.GetState();
501   EXPECT_EQ(LockWord::LockState::kFatLocked, new_state2);
502   EXPECT_NE(lock_after2.FatLockMonitor(), static_cast<Monitor*>(nullptr));
503 
504   // Test done.
505 #else
506   LOG(INFO) << "Skipping lock_object as I don't know how to do that on " << kRuntimeISA;
507   // Force-print to std::cout so it's also outside the logcat.
508   std::cout << "Skipping lock_object as I don't know how to do that on " << kRuntimeISA << std::endl;
509 #endif
510 }
511 
512 
513 class RandGen {
514  public:
RandGen(uint32_t seed)515   explicit RandGen(uint32_t seed) : val_(seed) {}
516 
next()517   uint32_t next() {
518     val_ = val_ * 48271 % 2147483647 + 13;
519     return val_;
520   }
521 
522   uint32_t val_;
523 };
524 
525 
526 // NO_THREAD_SAFETY_ANALYSIS as we do not want to grab exclusive mutator lock for MonitorInfo.
TestUnlockObject(StubTest * test)527 static void TestUnlockObject(StubTest* test) NO_THREAD_SAFETY_ANALYSIS {
528 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
529     (defined(__x86_64__) && !defined(__APPLE__))
530   static constexpr size_t kThinLockLoops = 100;
531 
532   Thread* self = Thread::Current();
533 
534   const uintptr_t art_quick_lock_object = StubTest::GetEntrypoint(self, kQuickLockObject);
535   const uintptr_t art_quick_unlock_object = StubTest::GetEntrypoint(self, kQuickUnlockObject);
536   // Create an object
537   ScopedObjectAccess soa(self);
538   // garbage is created during ClassLinker::Init
539   static constexpr size_t kNumberOfLocks = 10;  // Number of objects = lock
540   StackHandleScope<kNumberOfLocks + 1> hs(self);
541   Handle<mirror::String> obj(
542       hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!")));
543   LockWord lock = obj->GetLockWord(false);
544   LockWord::LockState old_state = lock.GetState();
545   EXPECT_EQ(LockWord::LockState::kUnlocked, old_state);
546 
547   test->Invoke3(reinterpret_cast<size_t>(obj.Get()), 0U, 0U, art_quick_unlock_object, self);
548   // This should be an illegal monitor state.
549   EXPECT_TRUE(self->IsExceptionPending());
550   self->ClearException();
551 
552   LockWord lock_after = obj->GetLockWord(false);
553   LockWord::LockState new_state = lock_after.GetState();
554   EXPECT_EQ(LockWord::LockState::kUnlocked, new_state);
555 
556   test->Invoke3(reinterpret_cast<size_t>(obj.Get()), 0U, 0U, art_quick_lock_object, self);
557 
558   LockWord lock_after2 = obj->GetLockWord(false);
559   LockWord::LockState new_state2 = lock_after2.GetState();
560   EXPECT_EQ(LockWord::LockState::kThinLocked, new_state2);
561 
562   test->Invoke3(reinterpret_cast<size_t>(obj.Get()), 0U, 0U, art_quick_unlock_object, self);
563 
564   LockWord lock_after3 = obj->GetLockWord(false);
565   LockWord::LockState new_state3 = lock_after3.GetState();
566   EXPECT_EQ(LockWord::LockState::kUnlocked, new_state3);
567 
568   // Stress test:
569   // Keep a number of objects and their locks in flight. Randomly lock or unlock one of them in
570   // each step.
571 
572   RandGen r(0x1234);
573 
574   constexpr size_t kIterations = 10000;  // Number of iterations
575   constexpr size_t kMoveToFat = 1000;     // Chance of 1:kMoveFat to make a lock fat.
576 
577   size_t counts[kNumberOfLocks];
578   bool fat[kNumberOfLocks];  // Whether a lock should be thin or fat.
579   Handle<mirror::String> objects[kNumberOfLocks];
580 
581   // Initialize = allocate.
582   for (size_t i = 0; i < kNumberOfLocks; ++i) {
583     counts[i] = 0;
584     fat[i] = false;
585     objects[i] = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), ""));
586   }
587 
588   for (size_t i = 0; i < kIterations; ++i) {
589     // Select which lock to update.
590     size_t index = r.next() % kNumberOfLocks;
591 
592     // Make lock fat?
593     if (!fat[index] && (r.next() % kMoveToFat == 0)) {
594       fat[index] = true;
595       objects[index]->IdentityHashCode();
596 
597       LockWord lock_iter = objects[index]->GetLockWord(false);
598       LockWord::LockState iter_state = lock_iter.GetState();
599       if (counts[index] == 0) {
600         EXPECT_EQ(LockWord::LockState::kHashCode, iter_state);
601       } else {
602         EXPECT_EQ(LockWord::LockState::kFatLocked, iter_state);
603       }
604     } else {
605       bool take_lock;  // Whether to lock or unlock in this step.
606       if (counts[index] == 0) {
607         take_lock = true;
608       } else if (counts[index] == kThinLockLoops) {
609         take_lock = false;
610       } else {
611         // Randomly.
612         take_lock = r.next() % 2 == 0;
613       }
614 
615       if (take_lock) {
616         test->Invoke3(reinterpret_cast<size_t>(objects[index].Get()), 0U, 0U, art_quick_lock_object,
617                       self);
618         counts[index]++;
619       } else {
620         test->Invoke3(reinterpret_cast<size_t>(objects[index].Get()), 0U, 0U,
621                       art_quick_unlock_object, self);
622         counts[index]--;
623       }
624 
625       EXPECT_FALSE(self->IsExceptionPending());
626 
627       // Check the new state.
628       LockWord lock_iter = objects[index]->GetLockWord(true);
629       LockWord::LockState iter_state = lock_iter.GetState();
630       if (fat[index]) {
631         // Abuse MonitorInfo.
632         EXPECT_EQ(LockWord::LockState::kFatLocked, iter_state) << index;
633         MonitorInfo info(objects[index].Get());
634         EXPECT_EQ(counts[index], info.entry_count_) << index;
635       } else {
636         if (counts[index] > 0) {
637           EXPECT_EQ(LockWord::LockState::kThinLocked, iter_state);
638           EXPECT_EQ(counts[index] - 1, lock_iter.ThinLockCount());
639         } else {
640           EXPECT_EQ(LockWord::LockState::kUnlocked, iter_state);
641         }
642       }
643     }
644   }
645 
646   // Unlock the remaining count times and then check it's unlocked. Then deallocate.
647   // Go reverse order to correctly handle Handles.
648   for (size_t i = 0; i < kNumberOfLocks; ++i) {
649     size_t index = kNumberOfLocks - 1 - i;
650     size_t count = counts[index];
651     while (count > 0) {
652       test->Invoke3(reinterpret_cast<size_t>(objects[index].Get()), 0U, 0U, art_quick_unlock_object,
653                     self);
654       count--;
655     }
656 
657     LockWord lock_after4 = objects[index]->GetLockWord(false);
658     LockWord::LockState new_state4 = lock_after4.GetState();
659     EXPECT_TRUE(LockWord::LockState::kUnlocked == new_state4
660                 || LockWord::LockState::kFatLocked == new_state4);
661   }
662 
663   // Test done.
664 #else
665   UNUSED(test);
666   LOG(INFO) << "Skipping unlock_object as I don't know how to do that on " << kRuntimeISA;
667   // Force-print to std::cout so it's also outside the logcat.
668   std::cout << "Skipping unlock_object as I don't know how to do that on " << kRuntimeISA << std::endl;
669 #endif
670 }
671 
TEST_F(StubTest,UnlockObject)672 TEST_F(StubTest, UnlockObject) {
673   // This will lead to monitor error messages in the log.
674   ScopedLogSeverity sls(LogSeverity::FATAL);
675 
676   TestUnlockObject(this);
677 }
678 
679 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
680     (defined(__x86_64__) && !defined(__APPLE__))
681 extern "C" void art_quick_check_instance_of(void);
682 #endif
683 
TEST_F(StubTest,CheckCast)684 TEST_F(StubTest, CheckCast) {
685 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
686     (defined(__x86_64__) && !defined(__APPLE__))
687   Thread* self = Thread::Current();
688 
689   const uintptr_t art_quick_check_instance_of =
690       StubTest::GetEntrypoint(self, kQuickCheckInstanceOf);
691 
692   // Find some classes.
693   ScopedObjectAccess soa(self);
694   // garbage is created during ClassLinker::Init
695 
696   VariableSizedHandleScope hs(soa.Self());
697   Handle<mirror::Class> klass_obj(
698       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
699   Handle<mirror::Class> klass_str(
700       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/String;")));
701   Handle<mirror::Class> klass_list(
702       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/util/List;")));
703   Handle<mirror::Class> klass_cloneable(
704         hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Cloneable;")));
705   Handle<mirror::Class> klass_array_list(
706       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/util/ArrayList;")));
707   Handle<mirror::Object> obj(hs.NewHandle(klass_obj->AllocObject(soa.Self())));
708   Handle<mirror::String> string(hs.NewHandle(
709       mirror::String::AllocFromModifiedUtf8(soa.Self(), "ABCD")));
710   Handle<mirror::Object> array_list(hs.NewHandle(klass_array_list->AllocObject(soa.Self())));
711 
712   EXPECT_FALSE(self->IsExceptionPending());
713 
714   Invoke3(reinterpret_cast<size_t>(obj.Get()),
715           reinterpret_cast<size_t>(klass_obj.Get()),
716           0U,
717           art_quick_check_instance_of,
718           self);
719   EXPECT_FALSE(self->IsExceptionPending());
720 
721   // Expected true: Test string instance of java.lang.String.
722   Invoke3(reinterpret_cast<size_t>(string.Get()),
723           reinterpret_cast<size_t>(klass_str.Get()),
724           0U,
725           art_quick_check_instance_of,
726           self);
727   EXPECT_FALSE(self->IsExceptionPending());
728 
729   // Expected true: Test string instance of java.lang.Object.
730   Invoke3(reinterpret_cast<size_t>(string.Get()),
731           reinterpret_cast<size_t>(klass_obj.Get()),
732           0U,
733           art_quick_check_instance_of,
734           self);
735   EXPECT_FALSE(self->IsExceptionPending());
736 
737   // Expected false: Test object instance of java.lang.String.
738   Invoke3(reinterpret_cast<size_t>(obj.Get()),
739           reinterpret_cast<size_t>(klass_str.Get()),
740           0U,
741           art_quick_check_instance_of,
742           self);
743   EXPECT_TRUE(self->IsExceptionPending());
744   self->ClearException();
745 
746   Invoke3(reinterpret_cast<size_t>(array_list.Get()),
747           reinterpret_cast<size_t>(klass_list.Get()),
748           0U,
749           art_quick_check_instance_of,
750           self);
751   EXPECT_FALSE(self->IsExceptionPending());
752 
753   Invoke3(reinterpret_cast<size_t>(array_list.Get()),
754           reinterpret_cast<size_t>(klass_cloneable.Get()),
755           0U,
756           art_quick_check_instance_of,
757           self);
758   EXPECT_FALSE(self->IsExceptionPending());
759 
760   Invoke3(reinterpret_cast<size_t>(string.Get()),
761           reinterpret_cast<size_t>(klass_array_list.Get()),
762           0U,
763           art_quick_check_instance_of,
764           self);
765   EXPECT_TRUE(self->IsExceptionPending());
766   self->ClearException();
767 
768   Invoke3(reinterpret_cast<size_t>(string.Get()),
769           reinterpret_cast<size_t>(klass_cloneable.Get()),
770           0U,
771           art_quick_check_instance_of,
772           self);
773   EXPECT_TRUE(self->IsExceptionPending());
774   self->ClearException();
775 
776 #else
777   LOG(INFO) << "Skipping check_cast as I don't know how to do that on " << kRuntimeISA;
778   // Force-print to std::cout so it's also outside the logcat.
779   std::cout << "Skipping check_cast as I don't know how to do that on " << kRuntimeISA << std::endl;
780 #endif
781 }
782 
TEST_F(StubTest,AllocObject)783 TEST_F(StubTest, AllocObject) {
784 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
785     (defined(__x86_64__) && !defined(__APPLE__))
786   // This will lead to OOM  error messages in the log.
787   ScopedLogSeverity sls(LogSeverity::FATAL);
788 
789   // TODO: Check the "Unresolved" allocation stubs
790 
791   Thread* self = Thread::Current();
792   // Create an object
793   ScopedObjectAccess soa(self);
794   // garbage is created during ClassLinker::Init
795 
796   StackHandleScope<2> hs(soa.Self());
797   Handle<mirror::Class> c(
798       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
799 
800   // Play with it...
801 
802   EXPECT_FALSE(self->IsExceptionPending());
803   {
804     size_t result = Invoke3(reinterpret_cast<size_t>(c.Get()), 0u, 0U,
805                             StubTest::GetEntrypoint(self, kQuickAllocObjectWithChecks),
806                             self);
807 
808     EXPECT_FALSE(self->IsExceptionPending());
809     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
810     ObjPtr<mirror::Object> obj = reinterpret_cast<mirror::Object*>(result);
811     EXPECT_OBJ_PTR_EQ(c.Get(), obj->GetClass());
812     VerifyObject(obj);
813   }
814 
815   {
816     size_t result = Invoke3(reinterpret_cast<size_t>(c.Get()), 0u, 0U,
817                             StubTest::GetEntrypoint(self, kQuickAllocObjectResolved),
818                             self);
819 
820     EXPECT_FALSE(self->IsExceptionPending());
821     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
822     ObjPtr<mirror::Object> obj = reinterpret_cast<mirror::Object*>(result);
823     EXPECT_OBJ_PTR_EQ(c.Get(), obj->GetClass());
824     VerifyObject(obj);
825   }
826 
827   {
828     size_t result = Invoke3(reinterpret_cast<size_t>(c.Get()), 0u, 0U,
829                             StubTest::GetEntrypoint(self, kQuickAllocObjectInitialized),
830                             self);
831 
832     EXPECT_FALSE(self->IsExceptionPending());
833     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
834     ObjPtr<mirror::Object> obj = reinterpret_cast<mirror::Object*>(result);
835     EXPECT_OBJ_PTR_EQ(c.Get(), obj->GetClass());
836     VerifyObject(obj);
837   }
838 
839   // Failure tests.
840 
841   // Out-of-memory.
842   {
843     Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
844 
845     // Array helps to fill memory faster.
846     Handle<mirror::Class> ca(
847         hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")));
848 
849     // Use arbitrary large amount for now.
850     static const size_t kMaxHandles = 1000000;
851     std::unique_ptr<StackHandleScope<kMaxHandles>> hsp(new StackHandleScope<kMaxHandles>(self));
852 
853     std::vector<Handle<mirror::Object>> handles;
854     // Start allocating with 128K
855     size_t length = 128 * KB / 4;
856     while (length > 10) {
857       Handle<mirror::Object> h(hsp->NewHandle<mirror::Object>(
858           mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), ca.Get(), length / 4)));
859       if (self->IsExceptionPending() || h == nullptr) {
860         self->ClearException();
861 
862         // Try a smaller length
863         length = length / 8;
864         // Use at most half the reported free space.
865         size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory();
866         if (length * 8 > mem) {
867           length = mem / 8;
868         }
869       } else {
870         handles.push_back(h);
871       }
872     }
873     LOG(INFO) << "Used " << handles.size() << " arrays to fill space.";
874 
875     // Allocate simple objects till it fails.
876     while (!self->IsExceptionPending()) {
877       Handle<mirror::Object> h = hsp->NewHandle(c->AllocObject(soa.Self()));
878       if (!self->IsExceptionPending() && h != nullptr) {
879         handles.push_back(h);
880       }
881     }
882     self->ClearException();
883 
884     size_t result = Invoke3(reinterpret_cast<size_t>(c.Get()), 0u, 0U,
885                             StubTest::GetEntrypoint(self, kQuickAllocObjectInitialized),
886                             self);
887     EXPECT_TRUE(self->IsExceptionPending());
888     self->ClearException();
889     EXPECT_EQ(reinterpret_cast<size_t>(nullptr), result);
890   }
891 
892   // Tests done.
893 #else
894   LOG(INFO) << "Skipping alloc_object as I don't know how to do that on " << kRuntimeISA;
895   // Force-print to std::cout so it's also outside the logcat.
896   std::cout << "Skipping alloc_object as I don't know how to do that on " << kRuntimeISA << std::endl;
897 #endif
898 }
899 
TEST_F(StubTest,AllocObjectArray)900 TEST_F(StubTest, AllocObjectArray) {
901 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
902     (defined(__x86_64__) && !defined(__APPLE__))
903   // TODO: Check the "Unresolved" allocation stubs
904 
905   // This will lead to OOM  error messages in the log.
906   ScopedLogSeverity sls(LogSeverity::FATAL);
907 
908   Thread* self = Thread::Current();
909   // Create an object
910   ScopedObjectAccess soa(self);
911   // garbage is created during ClassLinker::Init
912 
913   StackHandleScope<1> hs(self);
914   Handle<mirror::Class> c(
915       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")));
916 
917   // Play with it...
918 
919   EXPECT_FALSE(self->IsExceptionPending());
920 
921   {
922     // We can use null in the second argument as we do not need a method here (not used in
923     // resolved/initialized cases)
924     size_t result = Invoke3(reinterpret_cast<size_t>(c.Get()), 10U,
925                             reinterpret_cast<size_t>(nullptr),
926                             StubTest::GetEntrypoint(self, kQuickAllocArrayResolved32),
927                             self);
928     EXPECT_FALSE(self->IsExceptionPending()) << mirror::Object::PrettyTypeOf(self->GetException());
929     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
930     ObjPtr<mirror::Object> obj = reinterpret_cast<mirror::Object*>(result);
931     EXPECT_TRUE(obj->IsArrayInstance());
932     EXPECT_TRUE(obj->IsObjectArray());
933     EXPECT_OBJ_PTR_EQ(c.Get(), obj->GetClass());
934     VerifyObject(obj);
935     ObjPtr<mirror::Array> array = reinterpret_cast<mirror::Array*>(result);
936     EXPECT_EQ(array->GetLength(), 10);
937   }
938 
939   // Failure tests.
940 
941   // Out-of-memory.
942   {
943     size_t result = Invoke3(reinterpret_cast<size_t>(c.Get()),
944                             GB,  // that should fail...
945                             reinterpret_cast<size_t>(nullptr),
946                             StubTest::GetEntrypoint(self, kQuickAllocArrayResolved32),
947                             self);
948 
949     EXPECT_TRUE(self->IsExceptionPending());
950     self->ClearException();
951     EXPECT_EQ(reinterpret_cast<size_t>(nullptr), result);
952   }
953 
954   // Tests done.
955 #else
956   LOG(INFO) << "Skipping alloc_array as I don't know how to do that on " << kRuntimeISA;
957   // Force-print to std::cout so it's also outside the logcat.
958   std::cout << "Skipping alloc_array as I don't know how to do that on " << kRuntimeISA << std::endl;
959 #endif
960 }
961 
962 
TEST_F(StubTest,StringCompareTo)963 TEST_F(StubTest, StringCompareTo) {
964   // There is no StringCompareTo runtime entrypoint for __arm__ or __aarch64__.
965 #if defined(__i386__) || (defined(__x86_64__) && !defined(__APPLE__))
966   // TODO: Check the "Unresolved" allocation stubs
967 
968   Thread* self = Thread::Current();
969 
970   const uintptr_t art_quick_string_compareto = StubTest::GetEntrypoint(self, kQuickStringCompareTo);
971 
972   ScopedObjectAccess soa(self);
973   // garbage is created during ClassLinker::Init
974 
975   // Create some strings
976   // Use array so we can index into it and use a matrix for expected results
977   // Setup: The first half is standard. The second half uses a non-zero offset.
978   // TODO: Shared backing arrays.
979   const char* c[] = { "", "", "a", "aa", "ab",
980       "aacaacaacaacaacaac",  // This one's under the default limit to go to __memcmp16.
981       "aacaacaacaacaacaacaacaacaacaacaacaac",     // This one's over.
982       "aacaacaacaacaacaacaacaacaacaacaacaaca" };  // As is this one. We need a separate one to
983                                                   // defeat object-equal optimizations.
984   static constexpr size_t kStringCount = arraysize(c);
985 
986   StackHandleScope<kStringCount> hs(self);
987   Handle<mirror::String> s[kStringCount];
988 
989   for (size_t i = 0; i < kStringCount; ++i) {
990     s[i] = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), c[i]));
991   }
992 
993   // TODO: wide characters
994 
995   // Matrix of expectations. First component is first parameter. Note we only check against the
996   // sign, not the value. As we are testing random offsets, we need to compute this and need to
997   // rely on String::CompareTo being correct.
998   int32_t expected[kStringCount][kStringCount];
999   for (size_t x = 0; x < kStringCount; ++x) {
1000     for (size_t y = 0; y < kStringCount; ++y) {
1001       expected[x][y] = s[x]->CompareTo(s[y].Get());
1002     }
1003   }
1004 
1005   // Play with it...
1006 
1007   for (size_t x = 0; x < kStringCount; ++x) {
1008     for (size_t y = 0; y < kStringCount; ++y) {
1009       // Test string_compareto x y
1010       size_t result = Invoke3(reinterpret_cast<size_t>(s[x].Get()),
1011                               reinterpret_cast<size_t>(s[y].Get()), 0U,
1012                               art_quick_string_compareto, self);
1013 
1014       EXPECT_FALSE(self->IsExceptionPending());
1015 
1016       // The result is a 32b signed integer
1017       union {
1018         size_t r;
1019         int32_t i;
1020       } conv;
1021       conv.r = result;
1022       int32_t e = expected[x][y];
1023       EXPECT_TRUE(e == 0 ? conv.i == 0 : true) << "x=" << c[x] << " y=" << c[y] << " res=" <<
1024           conv.r;
1025       EXPECT_TRUE(e < 0 ? conv.i < 0 : true)   << "x=" << c[x] << " y="  << c[y] << " res=" <<
1026           conv.r;
1027       EXPECT_TRUE(e > 0 ? conv.i > 0 : true)   << "x=" << c[x] << " y=" << c[y] << " res=" <<
1028           conv.r;
1029     }
1030   }
1031 
1032   // TODO: Deallocate things.
1033 
1034   // Tests done.
1035 #else
1036   LOG(INFO) << "Skipping string_compareto as I don't know how to do that on " << kRuntimeISA;
1037   // Force-print to std::cout so it's also outside the logcat.
1038   std::cout << "Skipping string_compareto as I don't know how to do that on " << kRuntimeISA <<
1039       std::endl;
1040 #endif
1041 }
1042 
1043 
GetSetBooleanStatic(ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1044 static void GetSetBooleanStatic(ArtField* f, Thread* self,
1045                                 ArtMethod* referrer, StubTest* test)
1046     REQUIRES_SHARED(Locks::mutator_lock_) {
1047 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1048     (defined(__x86_64__) && !defined(__APPLE__))
1049   constexpr size_t num_values = 5;
1050   uint8_t values[num_values] = { 0, 1, 2, 128, 0xFF };
1051 
1052   for (size_t i = 0; i < num_values; ++i) {
1053     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1054                               static_cast<size_t>(values[i]),
1055                               0U,
1056                               StubTest::GetEntrypoint(self, kQuickSet8Static),
1057                               self,
1058                               referrer);
1059 
1060     size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1061                                            0U, 0U,
1062                                            StubTest::GetEntrypoint(self, kQuickGetBooleanStatic),
1063                                            self,
1064                                            referrer);
1065     // Boolean currently stores bools as uint8_t, be more zealous about asserting correct writes/gets.
1066     EXPECT_EQ(values[i], static_cast<uint8_t>(res)) << "Iteration " << i;
1067   }
1068 #else
1069   UNUSED(f, self, referrer, test);
1070   LOG(INFO) << "Skipping set_boolean_static as I don't know how to do that on " << kRuntimeISA;
1071   // Force-print to std::cout so it's also outside the logcat.
1072   std::cout << "Skipping set_boolean_static as I don't know how to do that on " << kRuntimeISA << std::endl;
1073 #endif
1074 }
GetSetByteStatic(ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1075 static void GetSetByteStatic(ArtField* f, Thread* self, ArtMethod* referrer,
1076                              StubTest* test)
1077     REQUIRES_SHARED(Locks::mutator_lock_) {
1078 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1079     (defined(__x86_64__) && !defined(__APPLE__))
1080   int8_t values[] = { -128, -64, 0, 64, 127 };
1081 
1082   for (size_t i = 0; i < arraysize(values); ++i) {
1083     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1084                               static_cast<size_t>(values[i]),
1085                               0U,
1086                               StubTest::GetEntrypoint(self, kQuickSet8Static),
1087                               self,
1088                               referrer);
1089 
1090     size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1091                                            0U, 0U,
1092                                            StubTest::GetEntrypoint(self, kQuickGetByteStatic),
1093                                            self,
1094                                            referrer);
1095     EXPECT_EQ(values[i], static_cast<int8_t>(res)) << "Iteration " << i;
1096   }
1097 #else
1098   UNUSED(f, self, referrer, test);
1099   LOG(INFO) << "Skipping set_byte_static as I don't know how to do that on " << kRuntimeISA;
1100   // Force-print to std::cout so it's also outside the logcat.
1101   std::cout << "Skipping set_byte_static as I don't know how to do that on " << kRuntimeISA << std::endl;
1102 #endif
1103 }
1104 
1105 
GetSetBooleanInstance(Handle<mirror::Object> * obj,ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1106 static void GetSetBooleanInstance(Handle<mirror::Object>* obj, ArtField* f, Thread* self,
1107                                   ArtMethod* referrer, StubTest* test)
1108     REQUIRES_SHARED(Locks::mutator_lock_) {
1109 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1110     (defined(__x86_64__) && !defined(__APPLE__))
1111   uint8_t values[] = { 0, true, 2, 128, 0xFF };
1112 
1113   for (size_t i = 0; i < arraysize(values); ++i) {
1114     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1115                               reinterpret_cast<size_t>(obj->Get()),
1116                               static_cast<size_t>(values[i]),
1117                               StubTest::GetEntrypoint(self, kQuickSet8Instance),
1118                               self,
1119                               referrer);
1120 
1121     uint8_t res = f->GetBoolean(obj->Get());
1122     EXPECT_EQ(values[i], res) << "Iteration " << i;
1123 
1124     f->SetBoolean<false>(obj->Get(), res);
1125 
1126     size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1127                                             reinterpret_cast<size_t>(obj->Get()),
1128                                             0U,
1129                                             StubTest::GetEntrypoint(self, kQuickGetBooleanInstance),
1130                                             self,
1131                                             referrer);
1132     EXPECT_EQ(res, static_cast<uint8_t>(res2));
1133   }
1134 #else
1135   UNUSED(obj, f, self, referrer, test);
1136   LOG(INFO) << "Skipping set_boolean_instance as I don't know how to do that on " << kRuntimeISA;
1137   // Force-print to std::cout so it's also outside the logcat.
1138   std::cout << "Skipping set_boolean_instance as I don't know how to do that on " << kRuntimeISA << std::endl;
1139 #endif
1140 }
GetSetByteInstance(Handle<mirror::Object> * obj,ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1141 static void GetSetByteInstance(Handle<mirror::Object>* obj, ArtField* f,
1142                              Thread* self, ArtMethod* referrer, StubTest* test)
1143     REQUIRES_SHARED(Locks::mutator_lock_) {
1144 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1145     (defined(__x86_64__) && !defined(__APPLE__))
1146   int8_t values[] = { -128, -64, 0, 64, 127 };
1147 
1148   for (size_t i = 0; i < arraysize(values); ++i) {
1149     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1150                               reinterpret_cast<size_t>(obj->Get()),
1151                               static_cast<size_t>(values[i]),
1152                               StubTest::GetEntrypoint(self, kQuickSet8Instance),
1153                               self,
1154                               referrer);
1155 
1156     int8_t res = f->GetByte(obj->Get());
1157     EXPECT_EQ(res, values[i]) << "Iteration " << i;
1158     f->SetByte<false>(obj->Get(), ++res);
1159 
1160     size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1161                                             reinterpret_cast<size_t>(obj->Get()),
1162                                             0U,
1163                                             StubTest::GetEntrypoint(self, kQuickGetByteInstance),
1164                                             self,
1165                                             referrer);
1166     EXPECT_EQ(res, static_cast<int8_t>(res2));
1167   }
1168 #else
1169   UNUSED(obj, f, self, referrer, test);
1170   LOG(INFO) << "Skipping set_byte_instance as I don't know how to do that on " << kRuntimeISA;
1171   // Force-print to std::cout so it's also outside the logcat.
1172   std::cout << "Skipping set_byte_instance as I don't know how to do that on " << kRuntimeISA << std::endl;
1173 #endif
1174 }
1175 
GetSetCharStatic(ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1176 static void GetSetCharStatic(ArtField* f, Thread* self, ArtMethod* referrer,
1177                              StubTest* test)
1178     REQUIRES_SHARED(Locks::mutator_lock_) {
1179 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1180     (defined(__x86_64__) && !defined(__APPLE__))
1181   uint16_t values[] = { 0, 1, 2, 255, 32768, 0xFFFF };
1182 
1183   for (size_t i = 0; i < arraysize(values); ++i) {
1184     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1185                               static_cast<size_t>(values[i]),
1186                               0U,
1187                               StubTest::GetEntrypoint(self, kQuickSet16Static),
1188                               self,
1189                               referrer);
1190 
1191     size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1192                                            0U, 0U,
1193                                            StubTest::GetEntrypoint(self, kQuickGetCharStatic),
1194                                            self,
1195                                            referrer);
1196 
1197     EXPECT_EQ(values[i], static_cast<uint16_t>(res)) << "Iteration " << i;
1198   }
1199 #else
1200   UNUSED(f, self, referrer, test);
1201   LOG(INFO) << "Skipping set_char_static as I don't know how to do that on " << kRuntimeISA;
1202   // Force-print to std::cout so it's also outside the logcat.
1203   std::cout << "Skipping set_char_static as I don't know how to do that on " << kRuntimeISA << std::endl;
1204 #endif
1205 }
GetSetShortStatic(ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1206 static void GetSetShortStatic(ArtField* f, Thread* self,
1207                               ArtMethod* referrer, StubTest* test)
1208     REQUIRES_SHARED(Locks::mutator_lock_) {
1209 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1210     (defined(__x86_64__) && !defined(__APPLE__))
1211   int16_t values[] = { -0x7FFF, -32768, 0, 255, 32767, 0x7FFE };
1212 
1213   for (size_t i = 0; i < arraysize(values); ++i) {
1214     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1215                               static_cast<size_t>(values[i]),
1216                               0U,
1217                               StubTest::GetEntrypoint(self, kQuickSet16Static),
1218                               self,
1219                               referrer);
1220 
1221     size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1222                                            0U, 0U,
1223                                            StubTest::GetEntrypoint(self, kQuickGetShortStatic),
1224                                            self,
1225                                            referrer);
1226 
1227     EXPECT_EQ(static_cast<int16_t>(res), values[i]) << "Iteration " << i;
1228   }
1229 #else
1230   UNUSED(f, self, referrer, test);
1231   LOG(INFO) << "Skipping set_short_static as I don't know how to do that on " << kRuntimeISA;
1232   // Force-print to std::cout so it's also outside the logcat.
1233   std::cout << "Skipping set_short_static as I don't know how to do that on " << kRuntimeISA << std::endl;
1234 #endif
1235 }
1236 
GetSetCharInstance(Handle<mirror::Object> * obj,ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1237 static void GetSetCharInstance(Handle<mirror::Object>* obj, ArtField* f,
1238                                Thread* self, ArtMethod* referrer, StubTest* test)
1239     REQUIRES_SHARED(Locks::mutator_lock_) {
1240 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1241     (defined(__x86_64__) && !defined(__APPLE__))
1242   uint16_t values[] = { 0, 1, 2, 255, 32768, 0xFFFF };
1243 
1244   for (size_t i = 0; i < arraysize(values); ++i) {
1245     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1246                               reinterpret_cast<size_t>(obj->Get()),
1247                               static_cast<size_t>(values[i]),
1248                               StubTest::GetEntrypoint(self, kQuickSet16Instance),
1249                               self,
1250                               referrer);
1251 
1252     uint16_t res = f->GetChar(obj->Get());
1253     EXPECT_EQ(res, values[i]) << "Iteration " << i;
1254     f->SetChar<false>(obj->Get(), ++res);
1255 
1256     size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1257                                             reinterpret_cast<size_t>(obj->Get()),
1258                                             0U,
1259                                             StubTest::GetEntrypoint(self, kQuickGetCharInstance),
1260                                             self,
1261                                             referrer);
1262     EXPECT_EQ(res, static_cast<uint16_t>(res2));
1263   }
1264 #else
1265   UNUSED(obj, f, self, referrer, test);
1266   LOG(INFO) << "Skipping set_char_instance as I don't know how to do that on " << kRuntimeISA;
1267   // Force-print to std::cout so it's also outside the logcat.
1268   std::cout << "Skipping set_char_instance as I don't know how to do that on " << kRuntimeISA << std::endl;
1269 #endif
1270 }
GetSetShortInstance(Handle<mirror::Object> * obj,ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1271 static void GetSetShortInstance(Handle<mirror::Object>* obj, ArtField* f,
1272                              Thread* self, ArtMethod* referrer, StubTest* test)
1273     REQUIRES_SHARED(Locks::mutator_lock_) {
1274 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1275     (defined(__x86_64__) && !defined(__APPLE__))
1276   int16_t values[] = { -0x7FFF, -32768, 0, 255, 32767, 0x7FFE };
1277 
1278   for (size_t i = 0; i < arraysize(values); ++i) {
1279     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1280                               reinterpret_cast<size_t>(obj->Get()),
1281                               static_cast<size_t>(values[i]),
1282                               StubTest::GetEntrypoint(self, kQuickSet16Instance),
1283                               self,
1284                               referrer);
1285 
1286     int16_t res = f->GetShort(obj->Get());
1287     EXPECT_EQ(res, values[i]) << "Iteration " << i;
1288     f->SetShort<false>(obj->Get(), ++res);
1289 
1290     size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1291                                             reinterpret_cast<size_t>(obj->Get()),
1292                                             0U,
1293                                             StubTest::GetEntrypoint(self, kQuickGetShortInstance),
1294                                             self,
1295                                             referrer);
1296     EXPECT_EQ(res, static_cast<int16_t>(res2));
1297   }
1298 #else
1299   UNUSED(obj, f, self, referrer, test);
1300   LOG(INFO) << "Skipping set_short_instance as I don't know how to do that on " << kRuntimeISA;
1301   // Force-print to std::cout so it's also outside the logcat.
1302   std::cout << "Skipping set_short_instance as I don't know how to do that on " << kRuntimeISA << std::endl;
1303 #endif
1304 }
1305 
GetSet32Static(ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1306 static void GetSet32Static(ArtField* f, Thread* self, ArtMethod* referrer,
1307                            StubTest* test)
1308     REQUIRES_SHARED(Locks::mutator_lock_) {
1309 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1310     (defined(__x86_64__) && !defined(__APPLE__))
1311   uint32_t values[] = { 0, 1, 2, 255, 32768, 1000000, 0xFFFFFFFF };
1312 
1313   for (size_t i = 0; i < arraysize(values); ++i) {
1314     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1315                               static_cast<size_t>(values[i]),
1316                               0U,
1317                               StubTest::GetEntrypoint(self, kQuickSet32Static),
1318                               self,
1319                               referrer);
1320 
1321     size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1322                                            0U, 0U,
1323                                            StubTest::GetEntrypoint(self, kQuickGet32Static),
1324                                            self,
1325                                            referrer);
1326 
1327     EXPECT_EQ(res, values[i]) << "Iteration " << i;
1328   }
1329 #else
1330   UNUSED(f, self, referrer, test);
1331   LOG(INFO) << "Skipping set32static as I don't know how to do that on " << kRuntimeISA;
1332   // Force-print to std::cout so it's also outside the logcat.
1333   std::cout << "Skipping set32static as I don't know how to do that on " << kRuntimeISA << std::endl;
1334 #endif
1335 }
1336 
1337 
GetSet32Instance(Handle<mirror::Object> * obj,ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1338 static void GetSet32Instance(Handle<mirror::Object>* obj, ArtField* f,
1339                              Thread* self, ArtMethod* referrer, StubTest* test)
1340     REQUIRES_SHARED(Locks::mutator_lock_) {
1341 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1342     (defined(__x86_64__) && !defined(__APPLE__))
1343   uint32_t values[] = { 0, 1, 2, 255, 32768, 1000000, 0xFFFFFFFF };
1344 
1345   for (size_t i = 0; i < arraysize(values); ++i) {
1346     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1347                               reinterpret_cast<size_t>(obj->Get()),
1348                               static_cast<size_t>(values[i]),
1349                               StubTest::GetEntrypoint(self, kQuickSet32Instance),
1350                               self,
1351                               referrer);
1352 
1353     int32_t res = f->GetInt(obj->Get());
1354     EXPECT_EQ(res, static_cast<int32_t>(values[i])) << "Iteration " << i;
1355 
1356     res++;
1357     f->SetInt<false>(obj->Get(), res);
1358 
1359     size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1360                                             reinterpret_cast<size_t>(obj->Get()),
1361                                             0U,
1362                                             StubTest::GetEntrypoint(self, kQuickGet32Instance),
1363                                             self,
1364                                             referrer);
1365     EXPECT_EQ(res, static_cast<int32_t>(res2));
1366   }
1367 #else
1368   UNUSED(obj, f, self, referrer, test);
1369   LOG(INFO) << "Skipping set32instance as I don't know how to do that on " << kRuntimeISA;
1370   // Force-print to std::cout so it's also outside the logcat.
1371   std::cout << "Skipping set32instance as I don't know how to do that on " << kRuntimeISA << std::endl;
1372 #endif
1373 }
1374 
1375 
1376 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1377     (defined(__x86_64__) && !defined(__APPLE__))
1378 
set_and_check_static(uint32_t f_idx,ObjPtr<mirror::Object> val,Thread * self,ArtMethod * referrer,StubTest * test)1379 static void set_and_check_static(uint32_t f_idx,
1380                                  ObjPtr<mirror::Object> val,
1381                                  Thread* self,
1382                                  ArtMethod* referrer,
1383                                  StubTest* test)
1384     REQUIRES_SHARED(Locks::mutator_lock_) {
1385   StackHandleScope<1u> hs(self);
1386   Handle<mirror::Object> h_val = hs.NewHandle(val);
1387   test->Invoke3WithReferrer(static_cast<size_t>(f_idx),
1388                             reinterpret_cast<size_t>(h_val.Get()),
1389                             0U,
1390                             StubTest::GetEntrypoint(self, kQuickSetObjStatic),
1391                             self,
1392                             referrer);
1393 
1394   size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f_idx),
1395                                          0U,
1396                                          0U,
1397                                          StubTest::GetEntrypoint(self, kQuickGetObjStatic),
1398                                          self,
1399                                          referrer);
1400 
1401   EXPECT_EQ(res, reinterpret_cast<size_t>(h_val.Get())) << "Value " << h_val.Get();
1402 }
1403 #endif
1404 
GetSetObjStatic(ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1405 static void GetSetObjStatic(ArtField* f, Thread* self, ArtMethod* referrer,
1406                             StubTest* test)
1407     REQUIRES_SHARED(Locks::mutator_lock_) {
1408 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1409     (defined(__x86_64__) && !defined(__APPLE__))
1410   set_and_check_static(f->GetDexFieldIndex(), nullptr, self, referrer, test);
1411 
1412   // Allocate a string object for simplicity.
1413   ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "Test");
1414   set_and_check_static(f->GetDexFieldIndex(), str, self, referrer, test);
1415 
1416   set_and_check_static(f->GetDexFieldIndex(), nullptr, self, referrer, test);
1417 #else
1418   UNUSED(f, self, referrer, test);
1419   LOG(INFO) << "Skipping setObjstatic as I don't know how to do that on " << kRuntimeISA;
1420   // Force-print to std::cout so it's also outside the logcat.
1421   std::cout << "Skipping setObjstatic as I don't know how to do that on " << kRuntimeISA << std::endl;
1422 #endif
1423 }
1424 
1425 
1426 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1427     (defined(__x86_64__) && !defined(__APPLE__))
set_and_check_instance(ArtField * f,ObjPtr<mirror::Object> trg,ObjPtr<mirror::Object> val,Thread * self,ArtMethod * referrer,StubTest * test)1428 static void set_and_check_instance(ArtField* f,
1429                                    ObjPtr<mirror::Object> trg,
1430                                    ObjPtr<mirror::Object> val,
1431                                    Thread* self,
1432                                    ArtMethod* referrer,
1433                                    StubTest* test)
1434     REQUIRES_SHARED(Locks::mutator_lock_) {
1435   StackHandleScope<2u> hs(self);
1436   Handle<mirror::Object> h_trg = hs.NewHandle(trg);
1437   Handle<mirror::Object> h_val = hs.NewHandle(val);
1438   test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1439                             reinterpret_cast<size_t>(h_trg.Get()),
1440                             reinterpret_cast<size_t>(h_val.Get()),
1441                             StubTest::GetEntrypoint(self, kQuickSetObjInstance),
1442                             self,
1443                             referrer);
1444 
1445   size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1446                                          reinterpret_cast<size_t>(h_trg.Get()),
1447                                          0U,
1448                                          StubTest::GetEntrypoint(self, kQuickGetObjInstance),
1449                                          self,
1450                                          referrer);
1451 
1452   EXPECT_EQ(res, reinterpret_cast<size_t>(h_val.Get())) << "Value " << h_val.Get();
1453 
1454   EXPECT_OBJ_PTR_EQ(h_val.Get(), f->GetObj(h_trg.Get()));
1455 }
1456 #endif
1457 
GetSetObjInstance(Handle<mirror::Object> * obj,ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1458 static void GetSetObjInstance(Handle<mirror::Object>* obj, ArtField* f,
1459                               Thread* self, ArtMethod* referrer, StubTest* test)
1460     REQUIRES_SHARED(Locks::mutator_lock_) {
1461 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1462     (defined(__x86_64__) && !defined(__APPLE__))
1463   set_and_check_instance(f, obj->Get(), nullptr, self, referrer, test);
1464 
1465   // Allocate a string object for simplicity.
1466   ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "Test");
1467   set_and_check_instance(f, obj->Get(), str, self, referrer, test);
1468 
1469   set_and_check_instance(f, obj->Get(), nullptr, self, referrer, test);
1470 #else
1471   UNUSED(obj, f, self, referrer, test);
1472   LOG(INFO) << "Skipping setObjinstance as I don't know how to do that on " << kRuntimeISA;
1473   // Force-print to std::cout so it's also outside the logcat.
1474   std::cout << "Skipping setObjinstance as I don't know how to do that on " << kRuntimeISA << std::endl;
1475 #endif
1476 }
1477 
1478 
1479 // TODO: Complete these tests for 32b architectures
1480 
GetSet64Static(ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1481 static void GetSet64Static(ArtField* f, Thread* self, ArtMethod* referrer,
1482                            StubTest* test)
1483     REQUIRES_SHARED(Locks::mutator_lock_) {
1484 #if (defined(__x86_64__) && !defined(__APPLE__)) || defined(__aarch64__)
1485   uint64_t values[] = { 0, 1, 2, 255, 32768, 1000000, 0xFFFFFFFF, 0xFFFFFFFFFFFF };
1486 
1487   for (size_t i = 0; i < arraysize(values); ++i) {
1488     // 64 bit FieldSet stores the set value in the second register.
1489     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1490                               values[i],
1491                               0U,
1492                               StubTest::GetEntrypoint(self, kQuickSet64Static),
1493                               self,
1494                               referrer);
1495 
1496     size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1497                                            0U, 0U,
1498                                            StubTest::GetEntrypoint(self, kQuickGet64Static),
1499                                            self,
1500                                            referrer);
1501 
1502     EXPECT_EQ(res, values[i]) << "Iteration " << i;
1503   }
1504 #else
1505   UNUSED(f, self, referrer, test);
1506   LOG(INFO) << "Skipping set64static as I don't know how to do that on " << kRuntimeISA;
1507   // Force-print to std::cout so it's also outside the logcat.
1508   std::cout << "Skipping set64static as I don't know how to do that on " << kRuntimeISA << std::endl;
1509 #endif
1510 }
1511 
1512 
GetSet64Instance(Handle<mirror::Object> * obj,ArtField * f,Thread * self,ArtMethod * referrer,StubTest * test)1513 static void GetSet64Instance(Handle<mirror::Object>* obj, ArtField* f,
1514                              Thread* self, ArtMethod* referrer, StubTest* test)
1515     REQUIRES_SHARED(Locks::mutator_lock_) {
1516 #if (defined(__x86_64__) && !defined(__APPLE__)) || defined(__aarch64__)
1517   uint64_t values[] = { 0, 1, 2, 255, 32768, 1000000, 0xFFFFFFFF, 0xFFFFFFFFFFFF };
1518 
1519   for (size_t i = 0; i < arraysize(values); ++i) {
1520     test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1521                               reinterpret_cast<size_t>(obj->Get()),
1522                               static_cast<size_t>(values[i]),
1523                               StubTest::GetEntrypoint(self, kQuickSet64Instance),
1524                               self,
1525                               referrer);
1526 
1527     int64_t res = f->GetLong(obj->Get());
1528     EXPECT_EQ(res, static_cast<int64_t>(values[i])) << "Iteration " << i;
1529 
1530     res++;
1531     f->SetLong<false>(obj->Get(), res);
1532 
1533     size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
1534                                             reinterpret_cast<size_t>(obj->Get()),
1535                                             0U,
1536                                             StubTest::GetEntrypoint(self, kQuickGet64Instance),
1537                                             self,
1538                                             referrer);
1539     EXPECT_EQ(res, static_cast<int64_t>(res2));
1540   }
1541 #else
1542   UNUSED(obj, f, self, referrer, test);
1543   LOG(INFO) << "Skipping set64instance as I don't know how to do that on " << kRuntimeISA;
1544   // Force-print to std::cout so it's also outside the logcat.
1545   std::cout << "Skipping set64instance as I don't know how to do that on " << kRuntimeISA << std::endl;
1546 #endif
1547 }
1548 
TestFields(Thread * self,StubTest * test,Primitive::Type test_type)1549 static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type) {
1550   // garbage is created during ClassLinker::Init
1551 
1552   JNIEnv* env = Thread::Current()->GetJniEnv();
1553   jclass jc = env->FindClass("AllFields");
1554   CHECK(jc != nullptr);
1555   jobject o = env->AllocObject(jc);
1556   CHECK(o != nullptr);
1557 
1558   ScopedObjectAccess soa(self);
1559   StackHandleScope<3> hs(self);
1560   Handle<mirror::Object> obj(hs.NewHandle(soa.Decode<mirror::Object>(o)));
1561   Handle<mirror::Class> c(hs.NewHandle(obj->GetClass()));
1562   // Need a method as a referrer
1563   ArtMethod* m = c->GetDirectMethod(0, kRuntimePointerSize);
1564 
1565   // Play with it...
1566 
1567   // Static fields.
1568   for (ArtField& f : c->GetSFields()) {
1569     Primitive::Type type = f.GetTypeAsPrimitiveType();
1570     if (test_type != type) {
1571      continue;
1572     }
1573     switch (type) {
1574       case Primitive::Type::kPrimBoolean:
1575         GetSetBooleanStatic(&f, self, m, test);
1576         break;
1577       case Primitive::Type::kPrimByte:
1578         GetSetByteStatic(&f, self, m, test);
1579         break;
1580       case Primitive::Type::kPrimChar:
1581         GetSetCharStatic(&f, self, m, test);
1582         break;
1583       case Primitive::Type::kPrimShort:
1584         GetSetShortStatic(&f, self, m, test);
1585         break;
1586       case Primitive::Type::kPrimInt:
1587         GetSet32Static(&f, self, m, test);
1588         break;
1589       case Primitive::Type::kPrimLong:
1590         GetSet64Static(&f, self, m, test);
1591         break;
1592       case Primitive::Type::kPrimNot:
1593         // Don't try array.
1594         if (f.GetTypeDescriptor()[0] != '[') {
1595           GetSetObjStatic(&f, self, m, test);
1596         }
1597         break;
1598       default:
1599         break;  // Skip.
1600     }
1601   }
1602 
1603   // Instance fields.
1604   for (ArtField& f : c->GetIFields()) {
1605     Primitive::Type type = f.GetTypeAsPrimitiveType();
1606     if (test_type != type) {
1607       continue;
1608     }
1609     switch (type) {
1610       case Primitive::Type::kPrimBoolean:
1611         GetSetBooleanInstance(&obj, &f, self, m, test);
1612         break;
1613       case Primitive::Type::kPrimByte:
1614         GetSetByteInstance(&obj, &f, self, m, test);
1615         break;
1616       case Primitive::Type::kPrimChar:
1617         GetSetCharInstance(&obj, &f, self, m, test);
1618         break;
1619       case Primitive::Type::kPrimShort:
1620         GetSetShortInstance(&obj, &f, self, m, test);
1621         break;
1622       case Primitive::Type::kPrimInt:
1623         GetSet32Instance(&obj, &f, self, m, test);
1624         break;
1625       case Primitive::Type::kPrimLong:
1626         GetSet64Instance(&obj, &f, self, m, test);
1627         break;
1628       case Primitive::Type::kPrimNot:
1629         // Don't try array.
1630         if (f.GetTypeDescriptor()[0] != '[') {
1631           GetSetObjInstance(&obj, &f, self, m, test);
1632         }
1633         break;
1634       default:
1635         break;  // Skip.
1636     }
1637   }
1638 
1639   // TODO: Deallocate things.
1640 }
1641 
TEST_F(StubTest,Fields8)1642 TEST_F(StubTest, Fields8) {
1643   Thread* self = Thread::Current();
1644 
1645   self->TransitionFromSuspendedToRunnable();
1646   LoadDex("AllFields");
1647   bool started = runtime_->Start();
1648   CHECK(started);
1649 
1650   TestFields(self, this, Primitive::Type::kPrimBoolean);
1651   TestFields(self, this, Primitive::Type::kPrimByte);
1652 }
1653 
TEST_F(StubTest,Fields16)1654 TEST_F(StubTest, Fields16) {
1655   Thread* self = Thread::Current();
1656 
1657   self->TransitionFromSuspendedToRunnable();
1658   LoadDex("AllFields");
1659   bool started = runtime_->Start();
1660   CHECK(started);
1661 
1662   TestFields(self, this, Primitive::Type::kPrimChar);
1663   TestFields(self, this, Primitive::Type::kPrimShort);
1664 }
1665 
TEST_F(StubTest,Fields32)1666 TEST_F(StubTest, Fields32) {
1667   Thread* self = Thread::Current();
1668 
1669   self->TransitionFromSuspendedToRunnable();
1670   LoadDex("AllFields");
1671   bool started = runtime_->Start();
1672   CHECK(started);
1673 
1674   TestFields(self, this, Primitive::Type::kPrimInt);
1675 }
1676 
TEST_F(StubTest,FieldsObj)1677 TEST_F(StubTest, FieldsObj) {
1678   Thread* self = Thread::Current();
1679 
1680   self->TransitionFromSuspendedToRunnable();
1681   LoadDex("AllFields");
1682   bool started = runtime_->Start();
1683   CHECK(started);
1684 
1685   TestFields(self, this, Primitive::Type::kPrimNot);
1686 }
1687 
TEST_F(StubTest,Fields64)1688 TEST_F(StubTest, Fields64) {
1689   Thread* self = Thread::Current();
1690 
1691   self->TransitionFromSuspendedToRunnable();
1692   LoadDex("AllFields");
1693   bool started = runtime_->Start();
1694   CHECK(started);
1695 
1696   TestFields(self, this, Primitive::Type::kPrimLong);
1697 }
1698 
1699 // Disabled, b/27991555 .
1700 // FIXME: Hacking the entry point to point to art_quick_to_interpreter_bridge is broken.
1701 // The bridge calls through to GetCalleeSaveMethodCaller() which looks up the pre-header
1702 // and gets a bogus OatQuickMethodHeader* pointing into our assembly code just before
1703 // the bridge and uses that to check for inlined frames, crashing in the process.
TEST_F(StubTest,DISABLED_IMT)1704 TEST_F(StubTest, DISABLED_IMT) {
1705 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || \
1706     (defined(__x86_64__) && !defined(__APPLE__))
1707   Thread* self = Thread::Current();
1708 
1709   ScopedObjectAccess soa(self);
1710   StackHandleScope<7> hs(self);
1711 
1712   JNIEnv* env = Thread::Current()->GetJniEnv();
1713 
1714   // ArrayList
1715 
1716   // Load ArrayList and used methods (JNI).
1717   jclass arraylist_jclass = env->FindClass("java/util/ArrayList");
1718   ASSERT_NE(nullptr, arraylist_jclass);
1719   jmethodID arraylist_constructor = env->GetMethodID(arraylist_jclass, "<init>", "()V");
1720   ASSERT_NE(nullptr, arraylist_constructor);
1721   jmethodID contains_jmethod = env->GetMethodID(
1722       arraylist_jclass, "contains", "(Ljava/lang/Object;)Z");
1723   ASSERT_NE(nullptr, contains_jmethod);
1724   jmethodID add_jmethod = env->GetMethodID(arraylist_jclass, "add", "(Ljava/lang/Object;)Z");
1725   ASSERT_NE(nullptr, add_jmethod);
1726 
1727   // Get representation.
1728   ArtMethod* contains_amethod = jni::DecodeArtMethod(contains_jmethod);
1729 
1730   // Patch up ArrayList.contains.
1731   if (contains_amethod->GetEntryPointFromQuickCompiledCode() == nullptr) {
1732     contains_amethod->SetEntryPointFromQuickCompiledCode(reinterpret_cast<void*>(
1733         StubTest::GetEntrypoint(self, kQuickQuickToInterpreterBridge)));
1734   }
1735 
1736   // List
1737 
1738   // Load List and used methods (JNI).
1739   jclass list_jclass = env->FindClass("java/util/List");
1740   ASSERT_NE(nullptr, list_jclass);
1741   jmethodID inf_contains_jmethod = env->GetMethodID(
1742       list_jclass, "contains", "(Ljava/lang/Object;)Z");
1743   ASSERT_NE(nullptr, inf_contains_jmethod);
1744 
1745   // Get mirror representation.
1746   ArtMethod* inf_contains = jni::DecodeArtMethod(inf_contains_jmethod);
1747 
1748   // Object
1749 
1750   jclass obj_jclass = env->FindClass("java/lang/Object");
1751   ASSERT_NE(nullptr, obj_jclass);
1752   jmethodID obj_constructor = env->GetMethodID(obj_jclass, "<init>", "()V");
1753   ASSERT_NE(nullptr, obj_constructor);
1754 
1755   // Create instances.
1756 
1757   jobject jarray_list = env->NewObject(arraylist_jclass, arraylist_constructor);
1758   ASSERT_NE(nullptr, jarray_list);
1759   Handle<mirror::Object> array_list(hs.NewHandle(soa.Decode<mirror::Object>(jarray_list)));
1760 
1761   jobject jobj = env->NewObject(obj_jclass, obj_constructor);
1762   ASSERT_NE(nullptr, jobj);
1763   Handle<mirror::Object> obj(hs.NewHandle(soa.Decode<mirror::Object>(jobj)));
1764 
1765   // Invocation tests.
1766 
1767   // 1. imt_conflict
1768 
1769   // Contains.
1770 
1771   // We construct the ImtConflictTable ourselves, as we cannot go into the runtime stub
1772   // that will create it: the runtime stub expects to be called by compiled code.
1773   LinearAlloc* linear_alloc = Runtime::Current()->GetLinearAlloc();
1774   ArtMethod* conflict_method = Runtime::Current()->CreateImtConflictMethod(linear_alloc);
1775   ImtConflictTable* empty_conflict_table =
1776       Runtime::Current()->GetClassLinker()->CreateImtConflictTable(/*count=*/0u, linear_alloc);
1777   void* data = linear_alloc->Alloc(
1778       self,
1779       ImtConflictTable::ComputeSizeWithOneMoreEntry(empty_conflict_table, kRuntimePointerSize),
1780       LinearAllocKind::kNoGCRoots);
1781   ImtConflictTable* new_table = new (data) ImtConflictTable(
1782       empty_conflict_table, inf_contains, contains_amethod, kRuntimePointerSize);
1783   conflict_method->SetImtConflictTable(new_table, kRuntimePointerSize);
1784 
1785   size_t result =
1786       Invoke3WithReferrerAndHidden(reinterpret_cast<size_t>(conflict_method),
1787                                    reinterpret_cast<size_t>(array_list.Get()),
1788                                    reinterpret_cast<size_t>(obj.Get()),
1789                                    StubTest::GetEntrypoint(self, kQuickQuickImtConflictTrampoline),
1790                                    self,
1791                                    contains_amethod,
1792                                    static_cast<size_t>(inf_contains->GetDexMethodIndex()));
1793 
1794   ASSERT_FALSE(self->IsExceptionPending());
1795   EXPECT_EQ(static_cast<size_t>(JNI_FALSE), result);
1796 
1797   // Add object.
1798 
1799   env->CallBooleanMethod(jarray_list, add_jmethod, jobj);
1800 
1801   ASSERT_FALSE(self->IsExceptionPending()) << mirror::Object::PrettyTypeOf(self->GetException());
1802 
1803   // Contains.
1804 
1805   result =
1806       Invoke3WithReferrerAndHidden(reinterpret_cast<size_t>(conflict_method),
1807                                    reinterpret_cast<size_t>(array_list.Get()),
1808                                    reinterpret_cast<size_t>(obj.Get()),
1809                                    StubTest::GetEntrypoint(self, kQuickQuickImtConflictTrampoline),
1810                                    self,
1811                                    contains_amethod,
1812                                    static_cast<size_t>(inf_contains->GetDexMethodIndex()));
1813 
1814   ASSERT_FALSE(self->IsExceptionPending());
1815   EXPECT_EQ(static_cast<size_t>(JNI_TRUE), result);
1816 
1817   // 2. regular interface trampoline
1818 
1819   result = Invoke3WithReferrer(static_cast<size_t>(inf_contains->GetDexMethodIndex()),
1820                                reinterpret_cast<size_t>(array_list.Get()),
1821                                reinterpret_cast<size_t>(obj.Get()),
1822                                StubTest::GetEntrypoint(self,
1823                                    kQuickInvokeInterfaceTrampolineWithAccessCheck),
1824                                self, contains_amethod);
1825 
1826   ASSERT_FALSE(self->IsExceptionPending());
1827   EXPECT_EQ(static_cast<size_t>(JNI_TRUE), result);
1828 
1829   result = Invoke3WithReferrer(
1830       static_cast<size_t>(inf_contains->GetDexMethodIndex()),
1831       reinterpret_cast<size_t>(array_list.Get()), reinterpret_cast<size_t>(array_list.Get()),
1832       StubTest::GetEntrypoint(self, kQuickInvokeInterfaceTrampolineWithAccessCheck), self,
1833       contains_amethod);
1834 
1835   ASSERT_FALSE(self->IsExceptionPending());
1836   EXPECT_EQ(static_cast<size_t>(JNI_FALSE), result);
1837 #else
1838   LOG(INFO) << "Skipping imt as I don't know how to do that on " << kRuntimeISA;
1839   // Force-print to std::cout so it's also outside the logcat.
1840   std::cout << "Skipping imt as I don't know how to do that on " << kRuntimeISA << std::endl;
1841 #endif
1842 }
1843 
TEST_F(StubTest,StringIndexOf)1844 TEST_F(StubTest, StringIndexOf) {
1845 #if defined(__arm__) || defined(__aarch64__)
1846   Thread* self = Thread::Current();
1847   ScopedObjectAccess soa(self);
1848   // garbage is created during ClassLinker::Init
1849 
1850   // Create some strings
1851   // Use array so we can index into it and use a matrix for expected results
1852   // Setup: The first half is standard. The second half uses a non-zero offset.
1853   // TODO: Shared backing arrays.
1854   const char* c_str[] = { "", "a", "ba", "cba", "dcba", "edcba", "asdfghjkl" };
1855   static constexpr size_t kStringCount = arraysize(c_str);
1856   const char c_char[] = { 'a', 'b', 'c', 'd', 'e' };
1857   static constexpr size_t kCharCount = arraysize(c_char);
1858 
1859   StackHandleScope<kStringCount> hs(self);
1860   Handle<mirror::String> s[kStringCount];
1861 
1862   for (size_t i = 0; i < kStringCount; ++i) {
1863     s[i] = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), c_str[i]));
1864   }
1865 
1866   // Matrix of expectations. First component is first parameter. Note we only check against the
1867   // sign, not the value. As we are testing random offsets, we need to compute this and need to
1868   // rely on String::CompareTo being correct.
1869   static constexpr size_t kMaxLen = 9;
1870   DCHECK_LE(strlen(c_str[kStringCount-1]), kMaxLen) << "Please fix the indexof test.";
1871 
1872   // Last dimension: start, offset by 1.
1873   int32_t expected[kStringCount][kCharCount][kMaxLen + 3];
1874   for (size_t x = 0; x < kStringCount; ++x) {
1875     for (size_t y = 0; y < kCharCount; ++y) {
1876       for (size_t z = 0; z <= kMaxLen + 2; ++z) {
1877         expected[x][y][z] = s[x]->FastIndexOf(c_char[y], static_cast<int32_t>(z) - 1);
1878       }
1879     }
1880   }
1881 
1882   // Play with it...
1883 
1884   for (size_t x = 0; x < kStringCount; ++x) {
1885     for (size_t y = 0; y < kCharCount; ++y) {
1886       for (size_t z = 0; z <= kMaxLen + 2; ++z) {
1887         int32_t start = static_cast<int32_t>(z) - 1;
1888 
1889         // Test string_compareto x y
1890         size_t result = Invoke3(reinterpret_cast<size_t>(s[x].Get()), c_char[y], start,
1891                                 StubTest::GetEntrypoint(self, kQuickIndexOf), self);
1892 
1893         EXPECT_FALSE(self->IsExceptionPending());
1894 
1895         // The result is a 32b signed integer
1896         union {
1897           size_t r;
1898           int32_t i;
1899         } conv;
1900         conv.r = result;
1901 
1902         EXPECT_EQ(expected[x][y][z], conv.i) << "Wrong result for " << c_str[x] << " / " <<
1903             c_char[y] << " @ " << start;
1904       }
1905     }
1906   }
1907 
1908   // TODO: Deallocate things.
1909 
1910   // Tests done.
1911 #else
1912   LOG(INFO) << "Skipping indexof as I don't know how to do that on " << kRuntimeISA;
1913   // Force-print to std::cout so it's also outside the logcat.
1914   std::cout << "Skipping indexof as I don't know how to do that on " << kRuntimeISA << std::endl;
1915 #endif
1916 }
1917 
1918 // TODO: Exercise the ReadBarrierMarkRegX entry points.
1919 
TEST_F(StubTest,ReadBarrier)1920 TEST_F(StubTest, ReadBarrier) {
1921 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) ||\
1922       (defined(__x86_64__) && !defined(__APPLE__))
1923   if (gUseReadBarrier) {
1924     Thread* self = Thread::Current();
1925 
1926     const uintptr_t readBarrierSlow = StubTest::GetEntrypoint(self, kQuickReadBarrierSlow);
1927 
1928     // Create an object
1929     ScopedObjectAccess soa(self);
1930     // garbage is created during ClassLinker::Init
1931 
1932     StackHandleScope<2> hs(soa.Self());
1933     Handle<mirror::Class> c(
1934         hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
1935 
1936     // Build an object instance
1937     Handle<mirror::Object> obj(hs.NewHandle(c->AllocObject(soa.Self())));
1938 
1939     EXPECT_FALSE(self->IsExceptionPending());
1940 
1941     size_t result = Invoke3(0U, reinterpret_cast<size_t>(obj.Get()),
1942                             mirror::Object::ClassOffset().SizeValue(), readBarrierSlow, self);
1943 
1944     EXPECT_FALSE(self->IsExceptionPending());
1945     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
1946     mirror::Class* klass = reinterpret_cast<mirror::Class*>(result);
1947     EXPECT_OBJ_PTR_EQ(klass, obj->GetClass());
1948     return;
1949   }
1950 #endif
1951   LOG(INFO) << "Skipping read_barrier_slow";
1952   // Force-print to std::cout so it's also outside the logcat.
1953   std::cout << "Skipping read_barrier_slow" << std::endl;
1954 }
1955 
TEST_F(StubTest,ReadBarrierForRoot)1956 TEST_F(StubTest, ReadBarrierForRoot) {
1957 #if defined(__i386__) || defined(__arm__) || defined(__aarch64__) ||\
1958       (defined(__x86_64__) && !defined(__APPLE__))
1959   if (gUseReadBarrier) {
1960     Thread* self = Thread::Current();
1961 
1962     const uintptr_t readBarrierForRootSlow =
1963         StubTest::GetEntrypoint(self, kQuickReadBarrierForRootSlow);
1964 
1965     // Create an object
1966     ScopedObjectAccess soa(self);
1967     // garbage is created during ClassLinker::Init
1968 
1969     StackHandleScope<1> hs(soa.Self());
1970 
1971     Handle<mirror::String> obj(
1972         hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!")));
1973 
1974     EXPECT_FALSE(self->IsExceptionPending());
1975 
1976     GcRoot<mirror::Class> root(GetClassRoot<mirror::String>());
1977     size_t result = Invoke3(reinterpret_cast<size_t>(&root), 0U, 0U, readBarrierForRootSlow, self);
1978 
1979     EXPECT_FALSE(self->IsExceptionPending());
1980     EXPECT_NE(reinterpret_cast<size_t>(nullptr), result);
1981     mirror::Class* klass = reinterpret_cast<mirror::Class*>(result);
1982     EXPECT_OBJ_PTR_EQ(klass, obj->GetClass());
1983     return;
1984   }
1985 #endif
1986   LOG(INFO) << "Skipping read_barrier_for_root_slow";
1987   // Force-print to std::cout so it's also outside the logcat.
1988   std::cout << "Skipping read_barrier_for_root_slow" << std::endl;
1989 }
1990 
1991 }  // namespace art
1992