/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "unstarted_runtime.h"

#include <limits>
#include <locale>

#include "base/casts.h"
#include "base/enums.h"
#include "base/memory_tool.h"
#include "class_linker.h"
#include "class_root.h"
#include "common_runtime_test.h"
#include "dex/descriptors_names.h"
#include "dex/dex_instruction.h"
#include "handle.h"
#include "handle_scope-inl.h"
#include "interpreter/interpreter_common.h"
#include "mirror/class_loader.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-inl.h"
#include "mirror/string-inl.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "shadow_frame-inl.h"
#include "thread.h"
#include "transaction.h"

namespace art {
namespace interpreter {

class UnstartedRuntimeTest : public CommonRuntimeTest {
 protected:
  // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
  // test friends.

  // Methods that intercept available libcore implementations.
#define UNSTARTED_DIRECT(Name, SigIgnored)                 \
  static void Unstarted ## Name(Thread* self,              \
                                ShadowFrame* shadow_frame, \
                                JValue* result,            \
                                size_t arg_offset)         \
      REQUIRES_SHARED(Locks::mutator_lock_) {        \
    interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
  }
#include "unstarted_runtime_list.h"
  UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
#undef UNSTARTED_RUNTIME_DIRECT_LIST
#undef UNSTARTED_RUNTIME_JNI_LIST
#undef UNSTARTED_DIRECT

  // Methods that are native.
#define UNSTARTED_JNI(Name, SigIgnored)                       \
  static void UnstartedJNI ## Name(Thread* self,              \
                                   ArtMethod* method,         \
                                   mirror::Object* receiver,  \
                                   uint32_t* args,            \
                                   JValue* result)            \
      REQUIRES_SHARED(Locks::mutator_lock_) {           \
    interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
  }
#include "unstarted_runtime_list.h"
  UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
#undef UNSTARTED_RUNTIME_DIRECT_LIST
#undef UNSTARTED_RUNTIME_JNI_LIST
#undef UNSTARTED_JNI

  // Helpers for ArrayCopy.
  //
  // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
  //       of three everywhere. That is enough to test all cases.

  static ObjPtr<mirror::ObjectArray<mirror::Object>> CreateObjectArray(
      Thread* self,
      ObjPtr<mirror::Class> component_type,
      const StackHandleScope<3>& data)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    Runtime* runtime = Runtime::Current();
    ObjPtr<mirror::Class> array_type =
        runtime->GetClassLinker()->FindArrayClass(self, &component_type);
    CHECK(array_type != nullptr);
    ObjPtr<mirror::ObjectArray<mirror::Object>> result =
        mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
    CHECK(result != nullptr);
    for (size_t i = 0; i < 3; ++i) {
      result->Set(static_cast<int32_t>(i), data.GetReference(i));
      CHECK(!self->IsExceptionPending());
    }
    return result;
  }

  static void CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,
                               const StackHandleScope<3>& data)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    CHECK_EQ(array->GetLength(), 3);
    CHECK_EQ(data.NumberOfReferences(), 3U);
    for (size_t i = 0; i < 3; ++i) {
      EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
    }
  }

  void RunArrayCopy(Thread* self,
                    ShadowFrame* tmp,
                    bool expect_exception,
                    ObjPtr<mirror::ObjectArray<mirror::Object>> src,
                    int32_t src_pos,
                    ObjPtr<mirror::ObjectArray<mirror::Object>> dst,
                    int32_t dst_pos,
                    int32_t length)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    JValue result;
    tmp->SetVRegReference(0, src);
    tmp->SetVReg(1, src_pos);
    tmp->SetVRegReference(2, dst);
    tmp->SetVReg(3, dst_pos);
    tmp->SetVReg(4, length);
    UnstartedSystemArraycopy(self, tmp, &result, 0);
    bool exception_pending = self->IsExceptionPending();
    EXPECT_EQ(exception_pending, expect_exception);
    if (exception_pending) {
      self->ClearException();
    }
  }

  void RunArrayCopy(Thread* self,
                    ShadowFrame* tmp,
                    bool expect_exception,
                    ObjPtr<mirror::Class> src_component_class,
                    ObjPtr<mirror::Class> dst_component_class,
                    const StackHandleScope<3>& src_data,
                    int32_t src_pos,
                    const StackHandleScope<3>& dst_data,
                    int32_t dst_pos,
                    int32_t length,
                    const StackHandleScope<3>& expected_result)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    StackHandleScope<3> hs_misc(self);
    Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));

    Handle<mirror::ObjectArray<mirror::Object>> src_handle(
        hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));

    Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
        hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));

    RunArrayCopy(self,
                 tmp,
                 expect_exception,
                 src_handle.Get(),
                 src_pos,
                 dst_handle.Get(),
                 dst_pos,
                 length);
    CheckObjectArray(dst_handle.Get(), expected_result);
  }

  void TestCeilFloor(bool ceil,
                     Thread* self,
                     ShadowFrame* tmp,
                     double const test_pairs[][2],
                     size_t num_pairs)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    for (size_t i = 0; i < num_pairs; ++i) {
      tmp->SetVRegDouble(0, test_pairs[i][0]);

      JValue result;
      if (ceil) {
        UnstartedMathCeil(self, tmp, &result, 0);
      } else {
        UnstartedMathFloor(self, tmp, &result, 0);
      }

      ASSERT_FALSE(self->IsExceptionPending());

      // We want precise results.
      int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
      int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
      EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
    }
  }

  // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
  // loading code doesn't work under transactions.
  void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) {
    mirror::Object* result = Runtime::Current()->GetClassLinker()->FindClass(
        Thread::Current(),
        Transaction::kAbortExceptionSignature,
        ScopedNullHandle<mirror::ClassLoader>());
    CHECK(result != nullptr);
  }
};

TEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
  Thread* self = Thread::Current();

  ScopedObjectAccess soa(self);
  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
  const uint8_t* base_ptr = base_array;

  JValue result;
  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  for (int32_t i = 0; i < kBaseLen; ++i) {
    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));

    UnstartedMemoryPeekByte(self, tmp, &result, 0);

    EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
  }

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
  Thread* self = Thread::Current();

  ScopedObjectAccess soa(self);
  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
  const uint8_t* base_ptr = base_array;

  JValue result;
  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  int32_t adjusted_length = kBaseLen - sizeof(int16_t);
  for (int32_t i = 0; i < adjusted_length; ++i) {
    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));

    UnstartedMemoryPeekShort(self, tmp, &result, 0);

    typedef int16_t unaligned_short __attribute__ ((aligned (1)));
    const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
    EXPECT_EQ(result.GetS(), *short_ptr);
  }

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
  Thread* self = Thread::Current();

  ScopedObjectAccess soa(self);
  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
  const uint8_t* base_ptr = base_array;

  JValue result;
  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  int32_t adjusted_length = kBaseLen - sizeof(int32_t);
  for (int32_t i = 0; i < adjusted_length; ++i) {
    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));

    UnstartedMemoryPeekInt(self, tmp, &result, 0);

    typedef int32_t unaligned_int __attribute__ ((aligned (1)));
    const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
    EXPECT_EQ(result.GetI(), *int_ptr);
  }

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
  Thread* self = Thread::Current();

  ScopedObjectAccess soa(self);
  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
  const uint8_t* base_ptr = base_array;

  JValue result;
  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  int32_t adjusted_length = kBaseLen - sizeof(int64_t);
  for (int32_t i = 0; i < adjusted_length; ++i) {
    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));

    UnstartedMemoryPeekLong(self, tmp, &result, 0);

    typedef int64_t unaligned_long __attribute__ ((aligned (1)));
    const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
    EXPECT_EQ(result.GetJ(), *long_ptr);
  }

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
  Thread* self = Thread::Current();

  ScopedObjectAccess soa(self);
  StackHandleScope<2> hs(self);
  // TODO: Actual UTF.
  constexpr const char base_string[] = "abcdefghijklmnop";
  Handle<mirror::String> h_test_string(hs.NewHandle(
      mirror::String::AllocFromModifiedUtf8(self, base_string)));
  constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
  Handle<mirror::CharArray> h_char_array(hs.NewHandle(
      mirror::CharArray::Alloc(self, kBaseLen)));
  // A buffer so we can make sure we only modify the elements targetted.
  uint16_t buf[kBaseLen];

  JValue result;
  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
    for (int32_t count = 0; count <= kBaseLen; ++count) {
      for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
        // Only do it when in bounds.
        if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
          tmp->SetVRegReference(0, h_test_string.Get());
          tmp->SetVReg(1, start_index);
          tmp->SetVReg(2, count);
          tmp->SetVRegReference(3, h_char_array.Get());
          tmp->SetVReg(3, trg_offset);

          // Copy the char_array into buf.
          memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));

          UnstartedStringCharAt(self, tmp, &result, 0);

          uint16_t* data = h_char_array->GetData();

          bool success = true;

          // First segment should be unchanged.
          for (int32_t i = 0; i < trg_offset; ++i) {
            success = success && (data[i] == buf[i]);
          }
          // Second segment should be a copy.
          for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
            success = success && (data[i] == buf[i - trg_offset + start_index]);
          }
          // Third segment should be unchanged.
          for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
            success = success && (data[i] == buf[i]);
          }

          EXPECT_TRUE(success);
        }
      }
    }
  }

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, StringCharAt) {
  Thread* self = Thread::Current();

  ScopedObjectAccess soa(self);
  // TODO: Actual UTF.
  constexpr const char* base_string = "abcdefghijklmnop";
  int32_t base_len = static_cast<int32_t>(strlen(base_string));
  ObjPtr<mirror::String> test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);

  JValue result;
  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  for (int32_t i = 0; i < base_len; ++i) {
    tmp->SetVRegReference(0, test_string);
    tmp->SetVReg(1, i);

    UnstartedStringCharAt(self, tmp, &result, 0);

    EXPECT_EQ(result.GetI(), base_string[i]);
  }

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, StringInit) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);
  ObjPtr<mirror::Class> klass = mirror::String::GetJavaLangString();
  ArtMethod* method =
      klass->FindConstructor("(Ljava/lang/String;)V",
                             Runtime::Current()->GetClassLinker()->GetImagePointerSize());
  ASSERT_TRUE(method != nullptr);

  // create instruction data for invoke-direct {v0, v1} of method with fake index
  uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };

  JValue result;
  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
  const char* base_string = "hello_world";
  StackHandleScope<2> hs(self);
  Handle<mirror::String> string_arg =
      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, base_string));
  Handle<mirror::String> reference_empty_string =
      hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, ""));
  shadow_frame->SetVRegReference(0, reference_empty_string.Get());
  shadow_frame->SetVRegReference(1, string_arg.Get());

  interpreter::DoCall<false, false>(method,
                                    self,
                                    *shadow_frame,
                                    Instruction::At(inst_data),
                                    inst_data[0],
                                    &result);
  ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
  EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());

  if (string_arg->IsCompressed() && string_result->IsCompressed()) {
    EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(),
                     string_arg->GetLength() * sizeof(uint8_t)), 0);
  } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) {
    EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
                     string_arg->GetLength() * sizeof(uint16_t)), 0);
  } else {
    bool equal = true;
    for (int i = 0; i < string_arg->GetLength(); ++i) {
      if (string_arg->CharAt(i) != string_result->CharAt(i)) {
        equal = false;
        break;
      }
    }
    EXPECT_EQ(equal, true);
  }

  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
}

// Tests the exceptions that should be checked before modifying the destination.
// (Doesn't check the object vs primitive case ATM.)
TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);
  JValue result;
  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
  //       allocate.
  StackHandleScope<3> hs_misc(self);
  Handle<mirror::Class> object_class(
      hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));

  StackHandleScope<3> hs_data(self);
  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));

  Handle<mirror::ObjectArray<mirror::Object>> array(
      hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));

  RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0);
  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0);
  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1);
  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4);
  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3);
  RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3);

  Handle<mirror::ObjectArray<mirror::Object>> class_as_array =
      hs_misc.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()));
  RunArrayCopy(self, tmp, true, class_as_array.Get(), 0, array.Get(), 0, 0);
  RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array.Get(), 0, 0);

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);
  JValue result;
  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  StackHandleScope<1> hs_object(self);
  Handle<mirror::Class> object_class(
      hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));

  // Simple test:
  // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
  {
    StackHandleScope<3> hs_src(self);
    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));

    StackHandleScope<3> hs_dst(self);
    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));

    StackHandleScope<3> hs_expected(self);
    hs_expected.NewHandle(hs_dst.GetReference(0));
    hs_expected.NewHandle(hs_dst.GetReference(1));
    hs_expected.NewHandle(hs_src.GetReference(1));

    RunArrayCopy(self,
                 tmp,
                 false,
                 object_class.Get(),
                 object_class.Get(),
                 hs_src,
                 1,
                 hs_dst,
                 2,
                 1,
                 hs_expected);
  }

  // Simple test:
  // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6]  (with dst String[])
  {
    StackHandleScope<3> hs_src(self);
    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));

    StackHandleScope<3> hs_dst(self);
    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));

    StackHandleScope<3> hs_expected(self);
    hs_expected.NewHandle(hs_dst.GetReference(0));
    hs_expected.NewHandle(hs_src.GetReference(1));
    hs_expected.NewHandle(hs_dst.GetReference(2));

    RunArrayCopy(self,
                 tmp,
                 false,
                 object_class.Get(),
                 mirror::String::GetJavaLangString(),
                 hs_src,
                 1,
                 hs_dst,
                 1,
                 1,
                 hs_expected);
  }

  // Simple test:
  // [1,*,3] into [4,5,6] = [1,5,6] + exc
  {
    StackHandleScope<3> hs_src(self);
    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
    hs_src.NewHandle(mirror::String::GetJavaLangString());
    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));

    StackHandleScope<3> hs_dst(self);
    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));

    StackHandleScope<3> hs_expected(self);
    hs_expected.NewHandle(hs_src.GetReference(0));
    hs_expected.NewHandle(hs_dst.GetReference(1));
    hs_expected.NewHandle(hs_dst.GetReference(2));

    RunArrayCopy(self,
                 tmp,
                 true,
                 object_class.Get(),
                 mirror::String::GetJavaLangString(),
                 hs_src,
                 0,
                 hs_dst,
                 0,
                 3,
                 hs_expected);
  }

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
  // suffixes).
  constexpr const char* test_string = "-2147483646";
  constexpr int32_t test_values[] = {
                6,
               46,
              646,
             3646,
            83646,
           483646,
          7483646,
         47483646,
        147483646,
       2147483646,
      -2147483646
  };

  static_assert(arraysize(test_values) == 11U, "test_values");
  CHECK_EQ(strlen(test_string), 11U);

  for (size_t i = 0; i <= 10; ++i) {
    const char* test_value = &test_string[10 - i];

    StackHandleScope<1> hs_str(self);
    Handle<mirror::String> h_str(
        hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
    ASSERT_NE(h_str.Get(), nullptr);
    ASSERT_FALSE(self->IsExceptionPending());

    tmp->SetVRegReference(0, h_str.Get());

    JValue result;
    UnstartedIntegerParseInt(self, tmp, &result, 0);

    ASSERT_FALSE(self->IsExceptionPending());
    EXPECT_EQ(result.GetI(), test_values[i]);
  }

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

// Right now the same as Integer.Parse
TEST_F(UnstartedRuntimeTest, LongParseLongTest) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
  // suffixes).
  constexpr const char* test_string = "-2147483646";
  constexpr int64_t test_values[] = {
                6,
               46,
              646,
             3646,
            83646,
           483646,
          7483646,
         47483646,
        147483646,
       2147483646,
      -2147483646
  };

  static_assert(arraysize(test_values) == 11U, "test_values");
  CHECK_EQ(strlen(test_string), 11U);

  for (size_t i = 0; i <= 10; ++i) {
    const char* test_value = &test_string[10 - i];

    StackHandleScope<1> hs_str(self);
    Handle<mirror::String> h_str(
        hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
    ASSERT_NE(h_str.Get(), nullptr);
    ASSERT_FALSE(self->IsExceptionPending());

    tmp->SetVRegReference(0, h_str.Get());

    JValue result;
    UnstartedLongParseLong(self, tmp, &result, 0);

    ASSERT_FALSE(self->IsExceptionPending());
    EXPECT_EQ(result.GetJ(), test_values[i]);
  }

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, Ceil) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  constexpr double nan = std::numeric_limits<double>::quiet_NaN();
  constexpr double inf = std::numeric_limits<double>::infinity();
  constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
  constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
  constexpr double test_pairs[][2] = {
      { -0.0, -0.0 },
      {  0.0,  0.0 },
      { -0.5, -0.0 },
      { -1.0, -1.0 },
      {  0.5,  1.0 },
      {  1.0,  1.0 },
      {  nan,  nan },
      {  inf,  inf },
      { -inf, -inf },
      {  ld1,  ld1 },
      {  ld2,  ld2 }
  };

  TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs));

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, Floor) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  constexpr double nan = std::numeric_limits<double>::quiet_NaN();
  constexpr double inf = std::numeric_limits<double>::infinity();
  constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
  constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
  constexpr double test_pairs[][2] = {
      { -0.0, -0.0 },
      {  0.0,  0.0 },
      { -0.5, -1.0 },
      { -1.0, -1.0 },
      {  0.5,  0.0 },
      {  1.0,  1.0 },
      {  nan,  nan },
      {  inf,  inf },
      { -inf, -inf },
      {  ld1,  ld1 },
      {  ld2,  ld2 }
  };

  TestCeilFloor(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs));

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, ToLowerUpper) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  std::locale c_locale("C");

  // Check ASCII.
  for (uint32_t i = 0; i < 128; ++i) {
    bool c_upper = std::isupper(static_cast<char>(i), c_locale);
    bool c_lower = std::islower(static_cast<char>(i), c_locale);
    EXPECT_FALSE(c_upper && c_lower) << i;

    // Check toLowerCase.
    {
      JValue result;
      tmp->SetVReg(0, static_cast<int32_t>(i));
      UnstartedCharacterToLowerCase(self, tmp, &result, 0);
      ASSERT_FALSE(self->IsExceptionPending());
      uint32_t lower_result = static_cast<uint32_t>(result.GetI());
      if (c_lower) {
        EXPECT_EQ(i, lower_result);
      } else if (c_upper) {
        EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
                  lower_result);
      } else {
        EXPECT_EQ(i, lower_result);
      }
    }

    // Check toUpperCase.
    {
      JValue result2;
      tmp->SetVReg(0, static_cast<int32_t>(i));
      UnstartedCharacterToUpperCase(self, tmp, &result2, 0);
      ASSERT_FALSE(self->IsExceptionPending());
      uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
      if (c_upper) {
        EXPECT_EQ(i, upper_result);
      } else if (c_lower) {
        EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
                  upper_result);
      } else {
        EXPECT_EQ(i, upper_result);
      }
    }
  }

  // Check abort for other things. Can't test all.

  PrepareForAborts();

  for (uint32_t i = 128; i < 256; ++i) {
    {
      JValue result;
      tmp->SetVReg(0, static_cast<int32_t>(i));
      Runtime::Current()->EnterTransactionMode();
      UnstartedCharacterToLowerCase(self, tmp, &result, 0);
      ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
      Runtime::Current()->ExitTransactionMode();
      ASSERT_TRUE(self->IsExceptionPending());
    }
    {
      JValue result;
      tmp->SetVReg(0, static_cast<int32_t>(i));
      Runtime::Current()->EnterTransactionMode();
      UnstartedCharacterToUpperCase(self, tmp, &result, 0);
      ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
      Runtime::Current()->ExitTransactionMode();
      ASSERT_TRUE(self->IsExceptionPending());
    }
  }
  for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
    {
      JValue result;
      tmp->SetVReg(0, static_cast<int32_t>(i));
      Runtime::Current()->EnterTransactionMode();
      UnstartedCharacterToLowerCase(self, tmp, &result, 0);
      ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
      Runtime::Current()->ExitTransactionMode();
      ASSERT_TRUE(self->IsExceptionPending());
    }
    {
      JValue result;
      tmp->SetVReg(0, static_cast<int32_t>(i));
      Runtime::Current()->EnterTransactionMode();
      UnstartedCharacterToUpperCase(self, tmp, &result, 0);
      ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
      Runtime::Current()->ExitTransactionMode();
      ASSERT_TRUE(self->IsExceptionPending());
    }
  }

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, Sin) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  // Test an important value, PI/6. That's the one we see in practice.
  constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));

  JValue result;
  UnstartedMathSin(self, tmp, &result, 0);

  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
  EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, Cos) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  // Test an important value, PI/6. That's the one we see in practice.
  constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));

  JValue result;
  UnstartedMathCos(self, tmp, &result, 0);

  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
  EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, Pow) {
  // Valgrind seems to get this wrong, actually. Disable for valgrind.
  if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) {
    return;
  }

  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  // Test an important pair.
  constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
  constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);

  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
  tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));

  JValue result;
  UnstartedMathPow(self, tmp, &result, 0);

  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
  EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

TEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  JValue result;
  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  ObjPtr<mirror::Class> class_klass = mirror::Class::GetJavaLangClass();
  shadow_frame->SetVRegReference(0, class_klass);
  UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
  EXPECT_EQ(result.GetZ(), 0);

  jobject class_loader = LoadDex("Nested");
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
  ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
  ASSERT_TRUE(c != nullptr);
  shadow_frame->SetVRegReference(0, c);
  UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
  EXPECT_EQ(result.GetZ(), 1);

  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
}

TEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  JValue result;
  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  jobject class_loader = LoadDex("Nested");
  StackHandleScope<4> hs(self);
  Handle<mirror::ClassLoader> loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));

  Handle<mirror::Class> nested_klass(hs.NewHandle(
      class_linker_->FindClass(soa.Self(), "LNested;", loader)));
  Handle<mirror::Class> inner_klass(hs.NewHandle(
      class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader)));
  Handle<mirror::Class> anon_klass(hs.NewHandle(
      class_linker_->FindClass(soa.Self(), "LNested$1;", loader)));

  shadow_frame->SetVRegReference(0, nested_klass.Get());
  UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
  EXPECT_EQ(result.GetL(), nullptr);

  shadow_frame->SetVRegReference(0, inner_klass.Get());
  UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
  EXPECT_EQ(result.GetL(), nested_klass.Get());

  shadow_frame->SetVRegReference(0, anon_klass.Get());
  UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
  EXPECT_EQ(result.GetL(), nullptr);

  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
}

TEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  JValue result;
  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  StackHandleScope<1> hs(self);
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();

  // Positive test. See that We get something for float conversion.
  {
    Handle<mirror::Class> floating_decimal = hs.NewHandle(
        class_linker->FindClass(self,
                                "Lsun/misc/FloatingDecimal;",
                                ScopedNullHandle<mirror::ClassLoader>()));
    ASSERT_TRUE(floating_decimal != nullptr);
    ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true));

    ArtMethod* caller_method = floating_decimal->FindClassMethod(
        "getBinaryToASCIIBuffer",
        "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;",
        class_linker->GetImagePointerSize());
    // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
    ASSERT_TRUE(caller_method != nullptr);
    ASSERT_TRUE(caller_method->IsDirect());
    ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get());
    ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0);
    shadow_frame->SetLink(caller_frame);

    UnstartedThreadLocalGet(self, shadow_frame, &result, 0);
    EXPECT_TRUE(result.GetL() != nullptr);
    EXPECT_FALSE(self->IsExceptionPending());

    ShadowFrame::DeleteDeoptimizedFrame(caller_frame);
  }

  // Negative test.
  PrepareForAborts();

  {
    // Just use a method in Class.
    ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass();
    ArtMethod* caller_method =
        &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin();
    ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0);
    shadow_frame->SetLink(caller_frame);

    Runtime::Current()->EnterTransactionMode();
    UnstartedThreadLocalGet(self, shadow_frame, &result, 0);
    ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
    Runtime::Current()->ExitTransactionMode();
    ASSERT_TRUE(self->IsExceptionPending());
    self->ClearException();

    ShadowFrame::DeleteDeoptimizedFrame(caller_frame);
  }

  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
}

TEST_F(UnstartedRuntimeTest, FloatConversion) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  StackHandleScope<1> hs(self);
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  Handle<mirror::Class> double_class = hs.NewHandle(
          class_linker->FindClass(self,
                                  "Ljava/lang/Double;",
                                  ScopedNullHandle<mirror::ClassLoader>()));
  ASSERT_TRUE(double_class != nullptr);
  ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true));

  ArtMethod* method = double_class->FindClassMethod("toString",
                                                    "(D)Ljava/lang/String;",
                                                    class_linker->GetImagePointerSize());
  ASSERT_TRUE(method != nullptr);
  ASSERT_TRUE(method->IsDirect());
  ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get());

  // create instruction data for invoke-direct {v0, v1} of method with fake index
  uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };

  JValue result;
  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
  shadow_frame->SetVRegDouble(0, 1.23);
  interpreter::DoCall<false, false>(method,
                                    self,
                                    *shadow_frame,
                                    Instruction::At(inst_data),
                                    inst_data[0],
                                    &result);
  ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
  ASSERT_TRUE(string_result != nullptr);

  std::string mod_utf = string_result->ToModifiedUtf8();
  EXPECT_EQ("1.23", mod_utf);

  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
}

TEST_F(UnstartedRuntimeTest, ThreadCurrentThread) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  JValue result;
  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  StackHandleScope<1> hs(self);
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  Handle<mirror::Class> thread_class = hs.NewHandle(
      class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>()));
  ASSERT_TRUE(thread_class.Get() != nullptr);
  ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true));

  // Negative test. In general, currentThread should fail (as we should not leak a peer that will
  // be recreated at runtime).
  PrepareForAborts();

  {
    Runtime::Current()->EnterTransactionMode();
    UnstartedThreadCurrentThread(self, shadow_frame, &result, 0);
    ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
    Runtime::Current()->ExitTransactionMode();
    ASSERT_TRUE(self->IsExceptionPending());
    self->ClearException();
  }

  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
}

TEST_F(UnstartedRuntimeTest, LogManager) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  StackHandleScope<1> hs(self);
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  Handle<mirror::Class> log_manager_class = hs.NewHandle(
      class_linker->FindClass(self,
                              "Ljava/util/logging/LogManager;",
                              ScopedNullHandle<mirror::ClassLoader>()));
  ASSERT_TRUE(log_manager_class.Get() != nullptr);
  ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true));
}

class UnstartedClassForNameTest : public UnstartedRuntimeTest {
 public:
  template <typename T>
  void RunTest(T& runner, bool in_transaction, bool should_succeed) {
    Thread* self = Thread::Current();
    ScopedObjectAccess soa(self);

    // Ensure that Class is initialized.
    {
      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
      StackHandleScope<1> hs(self);
      Handle<mirror::Class> h_class = hs.NewHandle(mirror::Class::GetJavaLangClass());
      CHECK(class_linker->EnsureInitialized(self, h_class, true, true));
    }

    // A selection of classes from different core classpath components.
    constexpr const char* kTestCases[] = {
        "java.net.CookieManager",  // From libcore.
        "dalvik.system.ClassExt",  // From libart.
    };

    if (in_transaction) {
      // For transaction mode, we cannot load any classes, as the pre-fence initialization of
      // classes isn't transactional. Load them ahead of time.
      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
      for (const char* name : kTestCases) {
        class_linker->FindClass(self,
                                DotToDescriptor(name).c_str(),
                                ScopedNullHandle<mirror::ClassLoader>());
        CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
      }
    }

    if (!should_succeed) {
      // Negative test. In general, currentThread should fail (as we should not leak a peer that will
      // be recreated at runtime).
      PrepareForAborts();
    }

    JValue result;
    ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

    for (const char* name : kTestCases) {
      ObjPtr<mirror::String> name_string = mirror::String::AllocFromModifiedUtf8(self, name);
      CHECK(name_string != nullptr);

      if (in_transaction) {
        Runtime::Current()->EnterTransactionMode();
      }
      CHECK(!self->IsExceptionPending());

      runner(self, shadow_frame, name_string, &result);

      if (should_succeed) {
        CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump();
        CHECK(result.GetL() != nullptr) << name;
      } else {
        CHECK(self->IsExceptionPending()) << name;
        if (in_transaction) {
          ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
        }
        self->ClearException();
      }

      if (in_transaction) {
        Runtime::Current()->ExitTransactionMode();
      }
    }

    ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
  }

  mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) {
    Thread* self = Thread::Current();
    StackHandleScope<2> hs(self);
    MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr);

    {
      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();

      // Create the fake boot classloader. Any instance is fine, they are technically interchangeable.
      Handle<mirror::Class> boot_cp_class = hs.NewHandle(
          class_linker->FindClass(self,
                                  "Ljava/lang/BootClassLoader;",
                                  ScopedNullHandle<mirror::ClassLoader>()));
      CHECK(boot_cp_class != nullptr);
      CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true));

      boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader());
      CHECK(boot_cp != nullptr);

      ArtMethod* boot_cp_init = boot_cp_class->FindConstructor(
          "()V", class_linker->GetImagePointerSize());
      CHECK(boot_cp_init != nullptr);

      JValue result;
      ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, boot_cp_init, 0);
      shadow_frame->SetVRegReference(0, boot_cp.Get());

      // create instruction data for invoke-direct {v0} of method with fake index
      uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 };

      interpreter::DoCall<false, false>(boot_cp_init,
                                        self,
                                        *shadow_frame,
                                        Instruction::At(inst_data),
                                        inst_data[0],
                                        &result);
      CHECK(!self->IsExceptionPending());

      ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
    }

    return boot_cp.Get();
  }
};

TEST_F(UnstartedClassForNameTest, ClassForName) {
  auto runner = [](Thread* self,
                   ShadowFrame* shadow_frame,
                   ObjPtr<mirror::String> name,
                   JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
    shadow_frame->SetVRegReference(0, name);
    UnstartedClassForName(self, shadow_frame, result, 0);
  };
  RunTest(runner, false, true);
}

TEST_F(UnstartedClassForNameTest, ClassForNameLong) {
  auto runner = [](Thread* self,
                   ShadowFrame* shadow_frame,
                   ObjPtr<mirror::String> name,
                   JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
    shadow_frame->SetVRegReference(0, name);
    shadow_frame->SetVReg(1, 0);
    shadow_frame->SetVRegReference(2, nullptr);
    UnstartedClassForNameLong(self, shadow_frame, result, 0);
  };
  RunTest(runner, false, true);
}

TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  StackHandleScope<1> hs(self);
  Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());

  auto runner = [&](Thread* th,
                    ShadowFrame* shadow_frame,
                    ObjPtr<mirror::String> name,
                    JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
    shadow_frame->SetVRegReference(0, name);
    shadow_frame->SetVReg(1, 0);
    shadow_frame->SetVRegReference(2, boot_cp.Get());
    UnstartedClassForNameLong(th, shadow_frame, result, 0);
  };
  RunTest(runner, false, true);
}

TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  StackHandleScope<1> hs(self);
  Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());

  auto runner = [&](Thread* th,
                    ShadowFrame* shadow_frame,
                    ObjPtr<mirror::String> name,
                    JValue* result)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    shadow_frame->SetVRegReference(0, name);
    shadow_frame->SetVReg(1, 0);
    shadow_frame->SetVRegReference(2, boot_cp.Get());
    UnstartedClassForNameLong(th, shadow_frame, result, 0);
  };
  RunTest(runner, true, true);
}

TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  StackHandleScope<2> hs(self);
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  jobject path_jobj = class_linker->CreatePathClassLoader(self, {});
  ASSERT_TRUE(path_jobj != nullptr);
  Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>(
      self->DecodeJObject(path_jobj)->AsClassLoader());

  auto runner = [&](Thread* th,
                    ShadowFrame* shadow_frame,
                    ObjPtr<mirror::String> name,
                    JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
    shadow_frame->SetVRegReference(0, name);
    shadow_frame->SetVReg(1, 0);
    shadow_frame->SetVRegReference(2, path_cp.Get());
    UnstartedClassForNameLong(th, shadow_frame, result, 0);
  };
  RunTest(runner, true, false);
}

TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  StackHandleScope<1> hs(self);
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  Handle<mirror::Class> list_class = hs.NewHandle(
      class_linker->FindClass(self,
                              "Ljava/util/List;",
                              ScopedNullHandle<mirror::ClassLoader>()));
  ASSERT_TRUE(list_class.Get() != nullptr);
  ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true));

  JValue result;
  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  shadow_frame->SetVRegReference(0, list_class.Get());
  UnstartedClassGetSignatureAnnotation(self, shadow_frame, &result, 0);
  ASSERT_TRUE(result.GetL() != nullptr);
  ASSERT_FALSE(self->IsExceptionPending());

  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);

  ASSERT_TRUE(result.GetL()->IsObjectArray());
  ObjPtr<mirror::ObjectArray<mirror::Object>> array =
      result.GetL()->AsObjectArray<mirror::Object>();
  std::ostringstream oss;
  for (int32_t i = 0; i != array->GetLength(); ++i) {
    ObjPtr<mirror::Object> elem = array->Get(i);
    ASSERT_TRUE(elem != nullptr);
    ASSERT_TRUE(elem->IsString());
    oss << elem->AsString()->ToModifiedUtf8();
  }
  std::string output_string = oss.str();
  ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;");
}

TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);

  StackHandleScope<4> hs(self);
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();

  // Get Throwable.
  Handle<mirror::Class> throw_class = hs.NewHandle(mirror::Throwable::GetJavaLangThrowable());
  ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true));

  // Get an input object.
  Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));

  // Find the constructor.
  ArtMethod* throw_cons = throw_class->FindConstructor(
      "(Ljava/lang/String;)V", class_linker->GetImagePointerSize());
  ASSERT_TRUE(throw_cons != nullptr);
  Handle<mirror::Constructor> cons;
  if (class_linker->GetImagePointerSize() == PointerSize::k64) {
     cons = hs.NewHandle(
        mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons));
    ASSERT_TRUE(cons != nullptr);
  } else {
    cons = hs.NewHandle(
        mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons));
    ASSERT_TRUE(cons != nullptr);
  }

  Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
      mirror::ObjectArray<mirror::Object>::Alloc(
          self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker_), 1));
  ASSERT_TRUE(args != nullptr);
  args->Set(0, input.Get());

  // OK, we're ready now.
  JValue result;
  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
  shadow_frame->SetVRegReference(0, cons.Get());
  shadow_frame->SetVRegReference(1, args.Get());
  UnstartedConstructorNewInstance0(self, shadow_frame, &result, 0);

  ASSERT_TRUE(result.GetL() != nullptr);
  ASSERT_FALSE(self->IsExceptionPending());

  // Should be a new object.
  ASSERT_NE(result.GetL(), input.Get());
  // Should be a String.
  ASSERT_EQ(mirror::Throwable::GetJavaLangThrowable(), result.GetL()->GetClass());
  // Should have the right string.
  ObjPtr<mirror::String> result_msg =
      reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
  EXPECT_OBJ_PTR_EQ(input.Get(), result_msg);

  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
}

TEST_F(UnstartedRuntimeTest, IdentityHashCode) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);
  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);

  JValue result;
  UnstartedSystemIdentityHashCode(self, tmp, &result, 0);

  EXPECT_EQ(0, result.GetI());
  ASSERT_FALSE(self->IsExceptionPending());

  ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
  tmp->SetVRegReference(0, str);
  UnstartedSystemIdentityHashCode(self, tmp, &result, 0);
  EXPECT_NE(0, result.GetI());
  EXPECT_EQ(str->IdentityHashCode(), result.GetI());
  ASSERT_FALSE(self->IsExceptionPending());

  ShadowFrame::DeleteDeoptimizedFrame(tmp);
}

}  // namespace interpreter
}  // namespace art
