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