Home | History | Annotate | Download | only in interpreter
      1 /*
      2  * Copyright (C) 2015 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 "unstarted_runtime.h"
     18 
     19 #include <cmath>
     20 #include <unordered_map>
     21 
     22 #include "ScopedLocalRef.h"
     23 
     24 #include "art_method-inl.h"
     25 #include "base/logging.h"
     26 #include "base/macros.h"
     27 #include "class_linker.h"
     28 #include "common_throws.h"
     29 #include "entrypoints/entrypoint_utils-inl.h"
     30 #include "handle_scope-inl.h"
     31 #include "interpreter/interpreter_common.h"
     32 #include "mirror/array-inl.h"
     33 #include "mirror/class.h"
     34 #include "mirror/field-inl.h"
     35 #include "mirror/object-inl.h"
     36 #include "mirror/object_array-inl.h"
     37 #include "mirror/string-inl.h"
     38 #include "nth_caller_visitor.h"
     39 #include "thread.h"
     40 #include "transaction.h"
     41 #include "well_known_classes.h"
     42 #include "zip_archive.h"
     43 
     44 namespace art {
     45 namespace interpreter {
     46 
     47 static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
     48     __attribute__((__format__(__printf__, 2, 3)))
     49     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     50 
     51 static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
     52   va_list args;
     53   if (Runtime::Current()->IsActiveTransaction()) {
     54     va_start(args, fmt);
     55     AbortTransactionV(self, fmt, args);
     56     va_end(args);
     57   } else {
     58     va_start(args, fmt);
     59     std::string msg;
     60     StringAppendV(&msg, fmt, args);
     61     va_end(args);
     62     LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
     63     UNREACHABLE();
     64   }
     65 }
     66 
     67 // Helper function to deal with class loading in an unstarted runtime.
     68 static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
     69                                       Handle<mirror::ClassLoader> class_loader, JValue* result,
     70                                       const std::string& method_name, bool initialize_class,
     71                                       bool abort_if_not_found)
     72     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     73   CHECK(className.Get() != nullptr);
     74   std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
     75   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
     76 
     77   mirror::Class* found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
     78   if (found == nullptr && abort_if_not_found) {
     79     if (!self->IsExceptionPending()) {
     80       AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
     81                              method_name.c_str(), PrettyDescriptor(descriptor.c_str()).c_str());
     82     }
     83     return;
     84   }
     85   if (found != nullptr && initialize_class) {
     86     StackHandleScope<1> hs(self);
     87     Handle<mirror::Class> h_class(hs.NewHandle(found));
     88     if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
     89       CHECK(self->IsExceptionPending());
     90       return;
     91     }
     92   }
     93   result->SetL(found);
     94 }
     95 
     96 // Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
     97 // rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
     98 // ClassNotFoundException), so need to do the same. The only exception is if the exception is
     99 // actually the transaction abort exception. This must not be wrapped, as it signals an
    100 // initialization abort.
    101 static void CheckExceptionGenerateClassNotFound(Thread* self)
    102     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    103   if (self->IsExceptionPending()) {
    104     // If it is not the transaction abort exception, wrap it.
    105     std::string type(PrettyTypeOf(self->GetException()));
    106     if (type != Transaction::kAbortExceptionDescriptor) {
    107       self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
    108                                      "ClassNotFoundException");
    109     }
    110   }
    111 }
    112 
    113 static mirror::String* GetClassName(Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
    114     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    115   mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
    116   if (param == nullptr) {
    117     AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
    118     return nullptr;
    119   }
    120   return param->AsString();
    121 }
    122 
    123 void UnstartedRuntime::UnstartedClassForName(
    124     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    125   mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
    126   if (class_name == nullptr) {
    127     return;
    128   }
    129   StackHandleScope<1> hs(self);
    130   Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
    131   UnstartedRuntimeFindClass(self, h_class_name, NullHandle<mirror::ClassLoader>(), result,
    132                             "Class.forName", true, false);
    133   CheckExceptionGenerateClassNotFound(self);
    134 }
    135 
    136 void UnstartedRuntime::UnstartedClassForNameLong(
    137     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    138   mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
    139   if (class_name == nullptr) {
    140     return;
    141   }
    142   bool initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
    143   mirror::ClassLoader* class_loader =
    144       down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
    145   StackHandleScope<2> hs(self);
    146   Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
    147   Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
    148   UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result, "Class.forName",
    149                             initialize_class, false);
    150   CheckExceptionGenerateClassNotFound(self);
    151 }
    152 
    153 void UnstartedRuntime::UnstartedClassClassForName(
    154     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    155   mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
    156   if (class_name == nullptr) {
    157     return;
    158   }
    159   bool initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
    160   mirror::ClassLoader* class_loader =
    161       down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
    162   StackHandleScope<2> hs(self);
    163   Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
    164   Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
    165   UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result, "Class.classForName",
    166                             initialize_class, false);
    167   CheckExceptionGenerateClassNotFound(self);
    168 }
    169 
    170 void UnstartedRuntime::UnstartedClassNewInstance(
    171     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    172   StackHandleScope<2> hs(self);  // Class, constructor, object.
    173   mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
    174   if (param == nullptr) {
    175     AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
    176     return;
    177   }
    178   mirror::Class* klass = param->AsClass();
    179   Handle<mirror::Class> h_klass(hs.NewHandle(klass));
    180 
    181   // Check that it's not null.
    182   if (h_klass.Get() == nullptr) {
    183     AbortTransactionOrFail(self, "Class reference is null for newInstance");
    184     return;
    185   }
    186 
    187   // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
    188   if (Runtime::Current()->IsActiveTransaction()) {
    189     if (h_klass.Get()->IsFinalizable()) {
    190       AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
    191                         PrettyClass(h_klass.Get()).c_str());
    192       return;
    193     }
    194   }
    195 
    196   // There are two situations in which we'll abort this run.
    197   //  1) If the class isn't yet initialized and initialization fails.
    198   //  2) If we can't find the default constructor. We'll postpone the exception to runtime.
    199   // Note that 2) could likely be handled here, but for safety abort the transaction.
    200   bool ok = false;
    201   auto* cl = Runtime::Current()->GetClassLinker();
    202   if (cl->EnsureInitialized(self, h_klass, true, true)) {
    203     auto* cons = h_klass->FindDeclaredDirectMethod("<init>", "()V", cl->GetImagePointerSize());
    204     if (cons != nullptr) {
    205       Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
    206       CHECK(h_obj.Get() != nullptr);  // We don't expect OOM at compile-time.
    207       EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
    208       if (!self->IsExceptionPending()) {
    209         result->SetL(h_obj.Get());
    210         ok = true;
    211       }
    212     } else {
    213       self->ThrowNewExceptionF("Ljava/lang/InternalError;",
    214                                "Could not find default constructor for '%s'",
    215                                PrettyClass(h_klass.Get()).c_str());
    216     }
    217   }
    218   if (!ok) {
    219     AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
    220                            PrettyClass(h_klass.Get()).c_str(),
    221                            PrettyTypeOf(self->GetException()).c_str());
    222   }
    223 }
    224 
    225 void UnstartedRuntime::UnstartedClassGetDeclaredField(
    226     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    227   // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
    228   // going the reflective Dex way.
    229   mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
    230   mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
    231   ArtField* found = nullptr;
    232   ArtField* fields = klass->GetIFields();
    233   for (int32_t i = 0, count = klass->NumInstanceFields(); i < count; ++i) {
    234     ArtField* f = &fields[i];
    235     if (name2->Equals(f->GetName())) {
    236       found = f;
    237       break;
    238     }
    239   }
    240   if (found == nullptr) {
    241     fields = klass->GetSFields();
    242     for (int32_t i = 0, count = klass->NumStaticFields(); i < count; ++i) {
    243       ArtField* f = &fields[i];
    244       if (name2->Equals(f->GetName())) {
    245         found = f;
    246         break;
    247       }
    248     }
    249   }
    250   if (found == nullptr) {
    251     AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
    252                            " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
    253                            PrettyDescriptor(klass).c_str());
    254     return;
    255   }
    256   if (Runtime::Current()->IsActiveTransaction()) {
    257     result->SetL(mirror::Field::CreateFromArtField<true>(self, found, true));
    258   } else {
    259     result->SetL(mirror::Field::CreateFromArtField<false>(self, found, true));
    260   }
    261 }
    262 
    263 void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
    264     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    265   mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
    266   mirror::ClassLoader* class_loader =
    267       down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
    268   StackHandleScope<2> hs(self);
    269   Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
    270   Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
    271   UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
    272                             "VMClassLoader.findLoadedClass", false, false);
    273   // This might have an error pending. But semantics are to just return null.
    274   if (self->IsExceptionPending()) {
    275     // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
    276     std::string type(PrettyTypeOf(self->GetException()));
    277     if (type != "java.lang.InternalError") {
    278       self->ClearException();
    279     }
    280   }
    281 }
    282 
    283 void UnstartedRuntime::UnstartedVoidLookupType(
    284     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED, JValue* result,
    285     size_t arg_offset ATTRIBUTE_UNUSED) {
    286   result->SetL(Runtime::Current()->GetClassLinker()->FindPrimitiveClass('V'));
    287 }
    288 
    289 // Arraycopy emulation.
    290 // Note: we can't use any fast copy functions, as they are not available under transaction.
    291 
    292 template <typename T>
    293 static void PrimitiveArrayCopy(Thread* self,
    294                                mirror::Array* src_array, int32_t src_pos,
    295                                mirror::Array* dst_array, int32_t dst_pos,
    296                                int32_t length)
    297     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    298   if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
    299     AbortTransactionOrFail(self, "Types mismatched in arraycopy: %s vs %s.",
    300                            PrettyDescriptor(src_array->GetClass()->GetComponentType()).c_str(),
    301                            PrettyDescriptor(dst_array->GetClass()->GetComponentType()).c_str());
    302     return;
    303   }
    304   mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
    305   mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
    306   const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
    307   if (copy_forward) {
    308     for (int32_t i = 0; i < length; ++i) {
    309       dst->Set(dst_pos + i, src->Get(src_pos + i));
    310     }
    311   } else {
    312     for (int32_t i = 1; i <= length; ++i) {
    313       dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
    314     }
    315   }
    316 }
    317 
    318 void UnstartedRuntime::UnstartedSystemArraycopy(
    319     Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
    320   // Special case array copying without initializing System.
    321   jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
    322   jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
    323   jint length = shadow_frame->GetVReg(arg_offset + 4);
    324   mirror::Array* src_array = shadow_frame->GetVRegReference(arg_offset)->AsArray();
    325   mirror::Array* dst_array = shadow_frame->GetVRegReference(arg_offset + 2)->AsArray();
    326 
    327   // Null checking.
    328   if (src_array == nullptr) {
    329     AbortTransactionOrFail(self, "src is null in arraycopy.");
    330     return;
    331   }
    332   if (dst_array == nullptr) {
    333     AbortTransactionOrFail(self, "dst is null in arraycopy.");
    334     return;
    335   }
    336 
    337   // Bounds checking.
    338   if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
    339       UNLIKELY(src_pos > src_array->GetLength() - length) ||
    340       UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
    341     self->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
    342                              "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
    343                              src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
    344                              length);
    345     AbortTransactionOrFail(self, "Index out of bounds.");
    346     return;
    347   }
    348 
    349   // Type checking.
    350   mirror::Class* src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
    351       GetComponentType();
    352 
    353   if (!src_type->IsPrimitive()) {
    354     // Check that the second type is not primitive.
    355     mirror::Class* trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
    356         GetComponentType();
    357     if (trg_type->IsPrimitiveInt()) {
    358       AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
    359                              PrettyDescriptor(src_array->GetClass()->GetComponentType()).c_str(),
    360                              PrettyDescriptor(dst_array->GetClass()->GetComponentType()).c_str());
    361       return;
    362     }
    363 
    364     // For simplicity only do this if the component types are the same. Otherwise we have to copy
    365     // even more code from the object-array functions.
    366     if (src_type != trg_type) {
    367       AbortTransactionOrFail(self, "Types not the same in arraycopy: %s vs %s",
    368                              PrettyDescriptor(src_array->GetClass()->GetComponentType()).c_str(),
    369                              PrettyDescriptor(dst_array->GetClass()->GetComponentType()).c_str());
    370       return;
    371     }
    372 
    373     mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
    374     mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
    375     if (src == dst) {
    376       // Can overlap, but not have type mismatches.
    377       const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
    378       if (copy_forward) {
    379         for (int32_t i = 0; i < length; ++i) {
    380           dst->Set(dst_pos + i, src->Get(src_pos + i));
    381         }
    382       } else {
    383         for (int32_t i = 1; i <= length; ++i) {
    384           dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
    385         }
    386       }
    387     } else {
    388       // Can't overlap. Would need type checks, but we abort above.
    389       for (int32_t i = 0; i < length; ++i) {
    390         dst->Set(dst_pos + i, src->Get(src_pos + i));
    391       }
    392     }
    393   } else if (src_type->IsPrimitiveChar()) {
    394     PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
    395   } else if (src_type->IsPrimitiveInt()) {
    396     PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
    397   } else {
    398     AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
    399                            PrettyDescriptor(src_type).c_str());
    400   }
    401 }
    402 
    403 void UnstartedRuntime::UnstartedSystemArraycopyChar(
    404     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    405   // Just forward.
    406   UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
    407 }
    408 
    409 void UnstartedRuntime::UnstartedSystemArraycopyInt(
    410     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    411   // Just forward.
    412   UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
    413 }
    414 
    415 void UnstartedRuntime::UnstartedThreadLocalGet(
    416     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
    417   std::string caller(PrettyMethod(shadow_frame->GetLink()->GetMethod()));
    418   bool ok = false;
    419   if (caller == "java.lang.String java.lang.IntegralToString.convertInt"
    420                 "(java.lang.AbstractStringBuilder, int)") {
    421     // Allocate non-threadlocal buffer.
    422     result->SetL(mirror::CharArray::Alloc(self, 11));
    423     ok = true;
    424   } else if (caller == "java.lang.RealToString java.lang.RealToString.getInstance()") {
    425     // Note: RealToString is implemented and used in a different fashion than IntegralToString.
    426     // Conversion is done over an actual object of RealToString (the conversion method is an
    427     // instance method). This means it is not as clear whether it is correct to return a new
    428     // object each time. The caller needs to be inspected by hand to see whether it (incorrectly)
    429     // stores the object for later use.
    430     // See also b/19548084 for a possible rewrite and bringing it in line with IntegralToString.
    431     if (shadow_frame->GetLink()->GetLink() != nullptr) {
    432       std::string caller2(PrettyMethod(shadow_frame->GetLink()->GetLink()->GetMethod()));
    433       if (caller2 == "java.lang.String java.lang.Double.toString(double)") {
    434         // Allocate new object.
    435         StackHandleScope<2> hs(self);
    436         Handle<mirror::Class> h_real_to_string_class(hs.NewHandle(
    437             shadow_frame->GetLink()->GetMethod()->GetDeclaringClass()));
    438         Handle<mirror::Object> h_real_to_string_obj(hs.NewHandle(
    439             h_real_to_string_class->AllocObject(self)));
    440         if (h_real_to_string_obj.Get() != nullptr) {
    441           auto* cl = Runtime::Current()->GetClassLinker();
    442           ArtMethod* init_method = h_real_to_string_class->FindDirectMethod(
    443               "<init>", "()V", cl->GetImagePointerSize());
    444           if (init_method == nullptr) {
    445             h_real_to_string_class->DumpClass(LOG(FATAL), mirror::Class::kDumpClassFullDetail);
    446           } else {
    447             JValue invoke_result;
    448             EnterInterpreterFromInvoke(self, init_method, h_real_to_string_obj.Get(), nullptr,
    449                                        nullptr);
    450             if (!self->IsExceptionPending()) {
    451               result->SetL(h_real_to_string_obj.Get());
    452               ok = true;
    453             }
    454           }
    455         }
    456       }
    457     }
    458   }
    459 
    460   if (!ok) {
    461     AbortTransactionOrFail(self, "Could not create RealToString object");
    462   }
    463 }
    464 
    465 void UnstartedRuntime::UnstartedMathCeil(
    466     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    467   double in = shadow_frame->GetVRegDouble(arg_offset);
    468   double out;
    469   // Special cases:
    470   // 1) NaN, infinity, +0, -0 -> out := in. All are guaranteed by cmath.
    471   // -1 < in < 0 -> out := -0.
    472   if (-1.0 < in && in < 0) {
    473     out = -0.0;
    474   } else {
    475     out = ceil(in);
    476   }
    477   result->SetD(out);
    478 }
    479 
    480 void UnstartedRuntime::UnstartedObjectHashCode(
    481     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    482   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
    483   result->SetI(obj->IdentityHashCode());
    484 }
    485 
    486 void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
    487     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    488   double in = shadow_frame->GetVRegDouble(arg_offset);
    489   result->SetJ(bit_cast<int64_t, double>(in));
    490 }
    491 
    492 static mirror::Object* GetDexFromDexCache(Thread* self, mirror::DexCache* dex_cache)
    493     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    494   const DexFile* dex_file = dex_cache->GetDexFile();
    495   if (dex_file == nullptr) {
    496     return nullptr;
    497   }
    498 
    499   // Create the direct byte buffer.
    500   JNIEnv* env = self->GetJniEnv();
    501   DCHECK(env != nullptr);
    502   void* address = const_cast<void*>(reinterpret_cast<const void*>(dex_file->Begin()));
    503   ScopedLocalRef<jobject> byte_buffer(env, env->NewDirectByteBuffer(address, dex_file->Size()));
    504   if (byte_buffer.get() == nullptr) {
    505     DCHECK(self->IsExceptionPending());
    506     return nullptr;
    507   }
    508 
    509   jvalue args[1];
    510   args[0].l = byte_buffer.get();
    511 
    512   ScopedLocalRef<jobject> dex(env, env->CallStaticObjectMethodA(
    513       WellKnownClasses::com_android_dex_Dex,
    514       WellKnownClasses::com_android_dex_Dex_create,
    515       args));
    516 
    517   return self->DecodeJObject(dex.get());
    518 }
    519 
    520 void UnstartedRuntime::UnstartedDexCacheGetDexNative(
    521     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    522   // We will create the Dex object, but the image writer will release it before creating the
    523   // art file.
    524   mirror::Object* src = shadow_frame->GetVRegReference(arg_offset);
    525   bool have_dex = false;
    526   if (src != nullptr) {
    527     mirror::Object* dex = GetDexFromDexCache(self, reinterpret_cast<mirror::DexCache*>(src));
    528     if (dex != nullptr) {
    529       have_dex = true;
    530       result->SetL(dex);
    531     }
    532   }
    533   if (!have_dex) {
    534     self->ClearException();
    535     Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Could not create Dex object");
    536   }
    537 }
    538 
    539 static void UnstartedMemoryPeek(
    540     Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    541   int64_t address = shadow_frame->GetVRegLong(arg_offset);
    542   // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
    543   //       aborting the transaction.
    544 
    545   switch (type) {
    546     case Primitive::kPrimByte: {
    547       result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
    548       return;
    549     }
    550 
    551     case Primitive::kPrimShort: {
    552       typedef int16_t unaligned_short __attribute__ ((aligned (1)));
    553       result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
    554       return;
    555     }
    556 
    557     case Primitive::kPrimInt: {
    558       typedef int32_t unaligned_int __attribute__ ((aligned (1)));
    559       result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
    560       return;
    561     }
    562 
    563     case Primitive::kPrimLong: {
    564       typedef int64_t unaligned_long __attribute__ ((aligned (1)));
    565       result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
    566       return;
    567     }
    568 
    569     case Primitive::kPrimBoolean:
    570     case Primitive::kPrimChar:
    571     case Primitive::kPrimFloat:
    572     case Primitive::kPrimDouble:
    573     case Primitive::kPrimVoid:
    574     case Primitive::kPrimNot:
    575       LOG(FATAL) << "Not in the Memory API: " << type;
    576       UNREACHABLE();
    577   }
    578   LOG(FATAL) << "Should not reach here";
    579   UNREACHABLE();
    580 }
    581 
    582 void UnstartedRuntime::UnstartedMemoryPeekByte(
    583     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    584   UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
    585 }
    586 
    587 void UnstartedRuntime::UnstartedMemoryPeekShort(
    588     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    589   UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
    590 }
    591 
    592 void UnstartedRuntime::UnstartedMemoryPeekInt(
    593     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    594   UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
    595 }
    596 
    597 void UnstartedRuntime::UnstartedMemoryPeekLong(
    598     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    599   UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
    600 }
    601 
    602 static void UnstartedMemoryPeekArray(
    603     Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
    604     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    605   int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
    606   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
    607   if (obj == nullptr) {
    608     Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
    609     return;
    610   }
    611   mirror::Array* array = obj->AsArray();
    612 
    613   int offset = shadow_frame->GetVReg(arg_offset + 3);
    614   int count = shadow_frame->GetVReg(arg_offset + 4);
    615   if (offset < 0 || offset + count > array->GetLength()) {
    616     std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
    617                                        offset, count, array->GetLength()));
    618     Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
    619     return;
    620   }
    621 
    622   switch (type) {
    623     case Primitive::kPrimByte: {
    624       int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
    625       mirror::ByteArray* byte_array = array->AsByteArray();
    626       for (int32_t i = 0; i < count; ++i, ++address) {
    627         byte_array->SetWithoutChecks<true>(i + offset, *address);
    628       }
    629       return;
    630     }
    631 
    632     case Primitive::kPrimShort:
    633     case Primitive::kPrimInt:
    634     case Primitive::kPrimLong:
    635       LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
    636       UNREACHABLE();
    637 
    638     case Primitive::kPrimBoolean:
    639     case Primitive::kPrimChar:
    640     case Primitive::kPrimFloat:
    641     case Primitive::kPrimDouble:
    642     case Primitive::kPrimVoid:
    643     case Primitive::kPrimNot:
    644       LOG(FATAL) << "Not in the Memory API: " << type;
    645       UNREACHABLE();
    646   }
    647   LOG(FATAL) << "Should not reach here";
    648   UNREACHABLE();
    649 }
    650 
    651 void UnstartedRuntime::UnstartedMemoryPeekByteArray(
    652     Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
    653   UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
    654 }
    655 
    656 // This allows reading security.properties in an unstarted runtime and initialize Security.
    657 void UnstartedRuntime::UnstartedSecurityGetSecurityPropertiesReader(
    658     Thread* self, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED, JValue* result,
    659     size_t arg_offset ATTRIBUTE_UNUSED) {
    660   Runtime* runtime = Runtime::Current();
    661   const std::vector<const DexFile*>& path = runtime->GetClassLinker()->GetBootClassPath();
    662   std::string canonical(DexFile::GetDexCanonicalLocation(path[0]->GetLocation().c_str()));
    663   mirror::String* string_data;
    664 
    665   // Use a block to enclose the I/O and MemMap code so buffers are released early.
    666   {
    667     std::string error_msg;
    668     std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(canonical.c_str(), &error_msg));
    669     if (zip_archive.get() == nullptr) {
    670       AbortTransactionOrFail(self, "Could not open zip file %s: %s", canonical.c_str(),
    671                              error_msg.c_str());
    672       return;
    673     }
    674     std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find("java/security/security.properties",
    675                                                           &error_msg));
    676     if (zip_entry.get() == nullptr) {
    677       AbortTransactionOrFail(self, "Could not find security.properties file in %s: %s",
    678                              canonical.c_str(), error_msg.c_str());
    679       return;
    680     }
    681     std::unique_ptr<MemMap> map(zip_entry->ExtractToMemMap(canonical.c_str(),
    682                                                            "java/security/security.properties",
    683                                                            &error_msg));
    684     if (map.get() == nullptr) {
    685       AbortTransactionOrFail(self, "Could not unzip security.properties file in %s: %s",
    686                              canonical.c_str(), error_msg.c_str());
    687       return;
    688     }
    689 
    690     uint32_t length = zip_entry->GetUncompressedLength();
    691     std::unique_ptr<char[]> tmp(new char[length + 1]);
    692     memcpy(tmp.get(), map->Begin(), length);
    693     tmp.get()[length] = 0;  // null terminator
    694 
    695     string_data = mirror::String::AllocFromModifiedUtf8(self, tmp.get());
    696   }
    697 
    698   if (string_data == nullptr) {
    699     AbortTransactionOrFail(self, "Could not create string from file content of %s",
    700                            canonical.c_str());
    701     return;
    702   }
    703 
    704   // Create a StringReader.
    705   StackHandleScope<3> hs(self);
    706   Handle<mirror::String> h_string(hs.NewHandle(string_data));
    707 
    708   Handle<mirror::Class> h_class(hs.NewHandle(
    709       runtime->GetClassLinker()->FindClass(self,
    710                                            "Ljava/io/StringReader;",
    711                                            NullHandle<mirror::ClassLoader>())));
    712   if (h_class.Get() == nullptr) {
    713     AbortTransactionOrFail(self, "Could not find StringReader class");
    714     return;
    715   }
    716 
    717   if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
    718     AbortTransactionOrFail(self, "Could not initialize StringReader class");
    719     return;
    720   }
    721 
    722   Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
    723   if (h_obj.Get() == nullptr) {
    724     AbortTransactionOrFail(self, "Could not allocate StringReader object");
    725     return;
    726   }
    727 
    728   auto* cl = Runtime::Current()->GetClassLinker();
    729   ArtMethod* constructor = h_class->FindDeclaredDirectMethod(
    730       "<init>", "(Ljava/lang/String;)V", cl->GetImagePointerSize());
    731   if (constructor == nullptr) {
    732     AbortTransactionOrFail(self, "Could not find StringReader constructor");
    733     return;
    734   }
    735 
    736   uint32_t args[1];
    737   args[0] = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_string.Get()));
    738   EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
    739 
    740   if (self->IsExceptionPending()) {
    741     AbortTransactionOrFail(self, "Could not run StringReader constructor");
    742     return;
    743   }
    744 
    745   result->SetL(h_obj.Get());
    746 }
    747 
    748 // This allows reading the new style of String objects during compilation.
    749 void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
    750     Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
    751   jint start = shadow_frame->GetVReg(arg_offset + 1);
    752   jint end = shadow_frame->GetVReg(arg_offset + 2);
    753   jint index = shadow_frame->GetVReg(arg_offset + 4);
    754   mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
    755   if (string == nullptr) {
    756     AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
    757     return;
    758   }
    759   DCHECK_GE(start, 0);
    760   DCHECK_GE(end, string->GetLength());
    761   StackHandleScope<1> hs(self);
    762   Handle<mirror::CharArray> h_char_array(
    763       hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
    764   DCHECK_LE(index, h_char_array->GetLength());
    765   DCHECK_LE(end - start, h_char_array->GetLength() - index);
    766   string->GetChars(start, end, h_char_array, index);
    767 }
    768 
    769 // This allows reading chars from the new style of String objects during compilation.
    770 void UnstartedRuntime::UnstartedStringCharAt(
    771     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    772   jint index = shadow_frame->GetVReg(arg_offset + 1);
    773   mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
    774   if (string == nullptr) {
    775     AbortTransactionOrFail(self, "String.charAt with null object");
    776     return;
    777   }
    778   result->SetC(string->CharAt(index));
    779 }
    780 
    781 // This allows setting chars from the new style of String objects during compilation.
    782 void UnstartedRuntime::UnstartedStringSetCharAt(
    783     Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
    784   jint index = shadow_frame->GetVReg(arg_offset + 1);
    785   jchar c = shadow_frame->GetVReg(arg_offset + 2);
    786   mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
    787   if (string == nullptr) {
    788     AbortTransactionOrFail(self, "String.setCharAt with null object");
    789     return;
    790   }
    791   string->SetCharAt(index, c);
    792 }
    793 
    794 // This allows creating the new style of String objects during compilation.
    795 void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
    796     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    797   jint offset = shadow_frame->GetVReg(arg_offset);
    798   jint char_count = shadow_frame->GetVReg(arg_offset + 1);
    799   DCHECK_GE(char_count, 0);
    800   StackHandleScope<1> hs(self);
    801   Handle<mirror::CharArray> h_char_array(
    802       hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
    803   Runtime* runtime = Runtime::Current();
    804   gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
    805   result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator));
    806 }
    807 
    808 // This allows creating the new style of String objects during compilation.
    809 void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
    810     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    811   mirror::String* to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
    812   if (to_copy == nullptr) {
    813     AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
    814     return;
    815   }
    816   StackHandleScope<1> hs(self);
    817   Handle<mirror::String> h_string(hs.NewHandle(to_copy));
    818   Runtime* runtime = Runtime::Current();
    819   gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
    820   result->SetL(mirror::String::AllocFromString<true>(self, h_string->GetLength(), h_string, 0,
    821                                                      allocator));
    822 }
    823 
    824 void UnstartedRuntime::UnstartedStringFastSubstring(
    825     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
    826   jint start = shadow_frame->GetVReg(arg_offset + 1);
    827   jint length = shadow_frame->GetVReg(arg_offset + 2);
    828   DCHECK_GE(start, 0);
    829   DCHECK_GE(length, 0);
    830   StackHandleScope<1> hs(self);
    831   Handle<mirror::String> h_string(
    832       hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
    833   DCHECK_LE(start, h_string->GetLength());
    834   DCHECK_LE(start + length, h_string->GetLength());
    835   Runtime* runtime = Runtime::Current();
    836   gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
    837   result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator));
    838 }
    839 
    840 // This allows getting the char array for new style of String objects during compilation.
    841 void UnstartedRuntime::UnstartedStringToCharArray(
    842     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
    843     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    844   mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
    845   if (string == nullptr) {
    846     AbortTransactionOrFail(self, "String.charAt with null object");
    847     return;
    848   }
    849   result->SetL(string->ToCharArray(self));
    850 }
    851 
    852 void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
    853     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
    854     uint32_t* args, JValue* result) {
    855   int32_t length = args[1];
    856   DCHECK_GE(length, 0);
    857   mirror::Class* element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
    858   Runtime* runtime = Runtime::Current();
    859   mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(self, &element_class);
    860   DCHECK(array_class != nullptr);
    861   gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
    862   result->SetL(mirror::Array::Alloc<true, true>(self, array_class, length,
    863                                                 array_class->GetComponentSizeShift(), allocator));
    864 }
    865 
    866 void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
    867     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
    868     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
    869   result->SetL(nullptr);
    870 }
    871 
    872 void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
    873     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
    874     uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
    875   NthCallerVisitor visitor(self, 3);
    876   visitor.WalkStack();
    877   if (visitor.caller != nullptr) {
    878     result->SetL(visitor.caller->GetDeclaringClass());
    879   }
    880 }
    881 
    882 void UnstartedRuntime::UnstartedJNIMathLog(
    883     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
    884     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
    885   JValue value;
    886   value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
    887   result->SetD(log(value.GetD()));
    888 }
    889 
    890 void UnstartedRuntime::UnstartedJNIMathExp(
    891     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
    892     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
    893   JValue value;
    894   value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
    895   result->SetD(exp(value.GetD()));
    896 }
    897 
    898 void UnstartedRuntime::UnstartedJNIClassGetNameNative(
    899     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
    900     uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
    901   StackHandleScope<1> hs(self);
    902   result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
    903 }
    904 
    905 void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
    906     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
    907     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
    908   result->SetI(args[0]);
    909 }
    910 
    911 void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
    912     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
    913     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
    914   result->SetI(args[0]);
    915 }
    916 
    917 void UnstartedRuntime::UnstartedJNIObjectInternalClone(
    918     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
    919     uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
    920   result->SetL(receiver->Clone(self));
    921 }
    922 
    923 void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
    924     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
    925     uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
    926   receiver->NotifyAll(self);
    927 }
    928 
    929 void UnstartedRuntime::UnstartedJNIStringCompareTo(
    930     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver, uint32_t* args,
    931     JValue* result) {
    932   mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
    933   if (rhs == nullptr) {
    934     AbortTransactionOrFail(self, "String.compareTo with null object");
    935   }
    936   result->SetI(receiver->AsString()->CompareTo(rhs));
    937 }
    938 
    939 void UnstartedRuntime::UnstartedJNIStringIntern(
    940     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
    941     uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
    942   result->SetL(receiver->AsString()->Intern());
    943 }
    944 
    945 void UnstartedRuntime::UnstartedJNIStringFastIndexOf(
    946     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
    947     uint32_t* args, JValue* result) {
    948   result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1]));
    949 }
    950 
    951 void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
    952     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
    953     uint32_t* args, JValue* result) {
    954   StackHandleScope<2> hs(self);
    955   auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
    956   auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
    957   result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
    958 }
    959 
    960 void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
    961     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
    962     uint32_t* args, JValue* result) {
    963   int32_t length = static_cast<int32_t>(args[1]);
    964   if (length < 0) {
    965     ThrowNegativeArraySizeException(length);
    966     return;
    967   }
    968   mirror::Class* element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
    969   Runtime* runtime = Runtime::Current();
    970   ClassLinker* class_linker = runtime->GetClassLinker();
    971   mirror::Class* array_class = class_linker->FindArrayClass(self, &element_class);
    972   if (UNLIKELY(array_class == nullptr)) {
    973     CHECK(self->IsExceptionPending());
    974     return;
    975   }
    976   DCHECK(array_class->IsObjectArrayClass());
    977   mirror::Array* new_array = mirror::ObjectArray<mirror::Object*>::Alloc(
    978       self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
    979   result->SetL(new_array);
    980 }
    981 
    982 void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
    983     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
    984     uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
    985   ScopedObjectAccessUnchecked soa(self);
    986   if (Runtime::Current()->IsActiveTransaction()) {
    987     result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<true>(soa)));
    988   } else {
    989     result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<false>(soa)));
    990   }
    991 }
    992 
    993 void UnstartedRuntime::UnstartedJNISystemIdentityHashCode(
    994     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
    995     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
    996   mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
    997   result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
    998 }
    999 
   1000 void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
   1001     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
   1002     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
   1003   result->SetZ(JNI_TRUE);
   1004 }
   1005 
   1006 void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
   1007     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
   1008     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
   1009   mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
   1010   jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
   1011   jint expectedValue = args[3];
   1012   jint newValue = args[4];
   1013   bool success;
   1014   if (Runtime::Current()->IsActiveTransaction()) {
   1015     success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
   1016                                                                 expectedValue, newValue);
   1017   } else {
   1018     success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
   1019                                                                  expectedValue, newValue);
   1020   }
   1021   result->SetZ(success ? JNI_TRUE : JNI_FALSE);
   1022 }
   1023 
   1024 void UnstartedRuntime::UnstartedJNIUnsafePutObject(
   1025     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
   1026     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result ATTRIBUTE_UNUSED) {
   1027   mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
   1028   jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
   1029   mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
   1030   if (Runtime::Current()->IsActiveTransaction()) {
   1031     obj->SetFieldObject<true>(MemberOffset(offset), newValue);
   1032   } else {
   1033     obj->SetFieldObject<false>(MemberOffset(offset), newValue);
   1034   }
   1035 }
   1036 
   1037 void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
   1038     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
   1039     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
   1040   mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
   1041   Primitive::Type primitive_type = component->GetPrimitiveType();
   1042   result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
   1043 }
   1044 
   1045 void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
   1046     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
   1047     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
   1048   mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
   1049   Primitive::Type primitive_type = component->GetPrimitiveType();
   1050   result->SetI(Primitive::ComponentSize(primitive_type));
   1051 }
   1052 
   1053 typedef void (*InvokeHandler)(Thread* self, ShadowFrame* shadow_frame, JValue* result,
   1054     size_t arg_size);
   1055 
   1056 typedef void (*JNIHandler)(Thread* self, ArtMethod* method, mirror::Object* receiver,
   1057     uint32_t* args, JValue* result);
   1058 
   1059 static bool tables_initialized_ = false;
   1060 static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
   1061 static std::unordered_map<std::string, JNIHandler> jni_handlers_;
   1062 
   1063 void UnstartedRuntime::InitializeInvokeHandlers() {
   1064 #define UNSTARTED_DIRECT(ShortName, Sig) \
   1065   invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
   1066 #include "unstarted_runtime_list.h"
   1067   UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
   1068 #undef UNSTARTED_RUNTIME_DIRECT_LIST
   1069 #undef UNSTARTED_RUNTIME_JNI_LIST
   1070 #undef UNSTARTED_DIRECT
   1071 }
   1072 
   1073 void UnstartedRuntime::InitializeJNIHandlers() {
   1074 #define UNSTARTED_JNI(ShortName, Sig) \
   1075   jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
   1076 #include "unstarted_runtime_list.h"
   1077   UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
   1078 #undef UNSTARTED_RUNTIME_DIRECT_LIST
   1079 #undef UNSTARTED_RUNTIME_JNI_LIST
   1080 #undef UNSTARTED_JNI
   1081 }
   1082 
   1083 void UnstartedRuntime::Initialize() {
   1084   CHECK(!tables_initialized_);
   1085 
   1086   InitializeInvokeHandlers();
   1087   InitializeJNIHandlers();
   1088 
   1089   tables_initialized_ = true;
   1090 }
   1091 
   1092 void UnstartedRuntime::Invoke(Thread* self, const DexFile::CodeItem* code_item,
   1093                               ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
   1094   // In a runtime that's not started we intercept certain methods to avoid complicated dependency
   1095   // problems in core libraries.
   1096   CHECK(tables_initialized_);
   1097 
   1098   std::string name(PrettyMethod(shadow_frame->GetMethod()));
   1099   const auto& iter = invoke_handlers_.find(name);
   1100   if (iter != invoke_handlers_.end()) {
   1101     // Clear out the result in case it's not zeroed out.
   1102     result->SetL(0);
   1103     (*iter->second)(self, shadow_frame, result, arg_offset);
   1104   } else {
   1105     // Not special, continue with regular interpreter execution.
   1106     artInterpreterToInterpreterBridge(self, code_item, shadow_frame, result);
   1107   }
   1108 }
   1109 
   1110 // Hand select a number of methods to be run in a not yet started runtime without using JNI.
   1111 void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
   1112                            uint32_t* args, JValue* result) {
   1113   std::string name(PrettyMethod(method));
   1114   const auto& iter = jni_handlers_.find(name);
   1115   if (iter != jni_handlers_.end()) {
   1116     // Clear out the result in case it's not zeroed out.
   1117     result->SetL(0);
   1118     (*iter->second)(self, method, receiver, args, result);
   1119   } else if (Runtime::Current()->IsActiveTransaction()) {
   1120     AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
   1121                       name.c_str());
   1122   } else {
   1123     LOG(FATAL) << "Calling native method " << PrettyMethod(method) << " in an unstarted "
   1124         "non-transactional runtime";
   1125   }
   1126 }
   1127 
   1128 }  // namespace interpreter
   1129 }  // namespace art
   1130