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 <ctype.h>
20 #include <errno.h>
21 #include <stdlib.h>
22 
23 #include <cmath>
24 #include <initializer_list>
25 #include <limits>
26 #include <locale>
27 #include <unordered_map>
28 
29 #include <android-base/logging.h>
30 #include <android-base/stringprintf.h>
31 
32 #include "art_method-inl.h"
33 #include "base/casts.h"
34 #include "base/enums.h"
35 #include "base/macros.h"
36 #include "base/quasi_atomic.h"
37 #include "base/zip_archive.h"
38 #include "class_linker.h"
39 #include "common_throws.h"
40 #include "dex/descriptors_names.h"
41 #include "entrypoints/entrypoint_utils-inl.h"
42 #include "gc/reference_processor.h"
43 #include "handle_scope-inl.h"
44 #include "hidden_api.h"
45 #include "interpreter/interpreter_common.h"
46 #include "jvalue-inl.h"
47 #include "mirror/array-alloc-inl.h"
48 #include "mirror/array-inl.h"
49 #include "mirror/class-alloc-inl.h"
50 #include "mirror/executable-inl.h"
51 #include "mirror/field-inl.h"
52 #include "mirror/method.h"
53 #include "mirror/object-inl.h"
54 #include "mirror/object_array-alloc-inl.h"
55 #include "mirror/object_array-inl.h"
56 #include "mirror/string-alloc-inl.h"
57 #include "mirror/string-inl.h"
58 #include "nativehelper/scoped_local_ref.h"
59 #include "nth_caller_visitor.h"
60 #include "reflection.h"
61 #include "thread-inl.h"
62 #include "transaction.h"
63 #include "well_known_classes.h"
64 
65 namespace art {
66 namespace interpreter {
67 
68 using android::base::StringAppendV;
69 using android::base::StringPrintf;
70 
71 static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
72     __attribute__((__format__(__printf__, 2, 3)))
73     REQUIRES_SHARED(Locks::mutator_lock_);
74 
AbortTransactionOrFail(Thread * self,const char * fmt,...)75 static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
76   va_list args;
77   if (Runtime::Current()->IsActiveTransaction()) {
78     va_start(args, fmt);
79     AbortTransactionV(self, fmt, args);
80     va_end(args);
81   } else {
82     va_start(args, fmt);
83     std::string msg;
84     StringAppendV(&msg, fmt, args);
85     va_end(args);
86     LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
87     UNREACHABLE();
88   }
89 }
90 
91 // Restricted support for character upper case / lower case. Only support ASCII, where
92 // it's easy. Abort the transaction otherwise.
CharacterLowerUpper(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset,bool to_lower_case)93 static void CharacterLowerUpper(Thread* self,
94                                 ShadowFrame* shadow_frame,
95                                 JValue* result,
96                                 size_t arg_offset,
97                                 bool to_lower_case) REQUIRES_SHARED(Locks::mutator_lock_) {
98   uint32_t int_value = static_cast<uint32_t>(shadow_frame->GetVReg(arg_offset));
99 
100   // Only ASCII (7-bit).
101   if (!isascii(int_value)) {
102     AbortTransactionOrFail(self,
103                            "Only support ASCII characters for toLowerCase/toUpperCase: %u",
104                            int_value);
105     return;
106   }
107 
108   std::locale c_locale("C");
109   char char_value = static_cast<char>(int_value);
110 
111   if (to_lower_case) {
112     result->SetI(std::tolower(char_value, c_locale));
113   } else {
114     result->SetI(std::toupper(char_value, c_locale));
115   }
116 }
117 
UnstartedCharacterToLowerCase(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)118 void UnstartedRuntime::UnstartedCharacterToLowerCase(
119     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
120   CharacterLowerUpper(self, shadow_frame, result, arg_offset, true);
121 }
122 
UnstartedCharacterToUpperCase(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)123 void UnstartedRuntime::UnstartedCharacterToUpperCase(
124     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
125   CharacterLowerUpper(self, shadow_frame, result, arg_offset, false);
126 }
127 
128 // Helper function to deal with class loading in an unstarted runtime.
UnstartedRuntimeFindClass(Thread * self,Handle<mirror::String> className,Handle<mirror::ClassLoader> class_loader,JValue * result,const std::string & method_name,bool initialize_class,bool abort_if_not_found)129 static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
130                                       Handle<mirror::ClassLoader> class_loader, JValue* result,
131                                       const std::string& method_name, bool initialize_class,
132                                       bool abort_if_not_found)
133     REQUIRES_SHARED(Locks::mutator_lock_) {
134   CHECK(className != nullptr);
135   std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
136   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
137 
138   ObjPtr<mirror::Class> found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
139   if (found == nullptr && abort_if_not_found) {
140     if (!self->IsExceptionPending()) {
141       AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
142                              method_name.c_str(),
143                              PrettyDescriptor(descriptor.c_str()).c_str());
144     }
145     return;
146   }
147   if (found != nullptr && initialize_class) {
148     StackHandleScope<1> hs(self);
149     HandleWrapperObjPtr<mirror::Class> h_class = hs.NewHandleWrapper(&found);
150     if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
151       CHECK(self->IsExceptionPending());
152       return;
153     }
154   }
155   result->SetL(found);
156 }
157 
158 // Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
159 // rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
160 // ClassNotFoundException), so need to do the same. The only exception is if the exception is
161 // actually the transaction abort exception. This must not be wrapped, as it signals an
162 // initialization abort.
CheckExceptionGenerateClassNotFound(Thread * self)163 static void CheckExceptionGenerateClassNotFound(Thread* self)
164     REQUIRES_SHARED(Locks::mutator_lock_) {
165   if (self->IsExceptionPending()) {
166     // If it is not the transaction abort exception, wrap it.
167     std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
168     if (type != Transaction::kAbortExceptionDescriptor) {
169       self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
170                                      "ClassNotFoundException");
171     }
172   }
173 }
174 
GetClassName(Thread * self,ShadowFrame * shadow_frame,size_t arg_offset)175 static ObjPtr<mirror::String> GetClassName(Thread* self,
176                                            ShadowFrame* shadow_frame,
177                                            size_t arg_offset)
178     REQUIRES_SHARED(Locks::mutator_lock_) {
179   mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
180   if (param == nullptr) {
181     AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
182     return nullptr;
183   }
184   return param->AsString();
185 }
186 
GetHiddenapiAccessContextFunction(ShadowFrame * frame)187 static std::function<hiddenapi::AccessContext()> GetHiddenapiAccessContextFunction(
188     ShadowFrame* frame) {
189   return [=]() REQUIRES_SHARED(Locks::mutator_lock_) {
190     return hiddenapi::AccessContext(frame->GetMethod()->GetDeclaringClass());
191   };
192 }
193 
194 template<typename T>
ShouldDenyAccessToMember(T * member,ShadowFrame * frame)195 static ALWAYS_INLINE bool ShouldDenyAccessToMember(T* member, ShadowFrame* frame)
196     REQUIRES_SHARED(Locks::mutator_lock_) {
197   // All uses in this file are from reflection
198   constexpr hiddenapi::AccessMethod kAccessMethod = hiddenapi::AccessMethod::kReflection;
199   return hiddenapi::ShouldDenyAccessToMember(member,
200                                              GetHiddenapiAccessContextFunction(frame),
201                                              kAccessMethod);
202 }
203 
UnstartedClassForNameCommon(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset,bool long_form,const char * caller)204 void UnstartedRuntime::UnstartedClassForNameCommon(Thread* self,
205                                                    ShadowFrame* shadow_frame,
206                                                    JValue* result,
207                                                    size_t arg_offset,
208                                                    bool long_form,
209                                                    const char* caller) {
210   ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
211   if (class_name == nullptr) {
212     return;
213   }
214   bool initialize_class;
215   ObjPtr<mirror::ClassLoader> class_loader;
216   if (long_form) {
217     initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
218     class_loader =
219         ObjPtr<mirror::ClassLoader>::DownCast(shadow_frame->GetVRegReference(arg_offset + 2));
220   } else {
221     initialize_class = true;
222     // TODO: This is really only correct for the boot classpath, and for robustness we should
223     //       check the caller.
224     class_loader = nullptr;
225   }
226 
227   ScopedObjectAccessUnchecked soa(self);
228   if (class_loader != nullptr && !ClassLinker::IsBootClassLoader(soa, class_loader)) {
229     AbortTransactionOrFail(self,
230                            "Only the boot classloader is supported: %s",
231                            mirror::Object::PrettyTypeOf(class_loader).c_str());
232     return;
233   }
234 
235   StackHandleScope<1> hs(self);
236   Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
237   UnstartedRuntimeFindClass(self,
238                             h_class_name,
239                             ScopedNullHandle<mirror::ClassLoader>(),
240                             result,
241                             caller,
242                             initialize_class,
243                             false);
244   CheckExceptionGenerateClassNotFound(self);
245 }
246 
UnstartedClassForName(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)247 void UnstartedRuntime::UnstartedClassForName(
248     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
249   UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, false, "Class.forName");
250 }
251 
UnstartedClassForNameLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)252 void UnstartedRuntime::UnstartedClassForNameLong(
253     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
254   UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.forName");
255 }
256 
UnstartedClassGetPrimitiveClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)257 void UnstartedRuntime::UnstartedClassGetPrimitiveClass(
258     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
259   ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
260   ObjPtr<mirror::Class> klass = mirror::Class::GetPrimitiveClass(class_name);
261   if (UNLIKELY(klass == nullptr)) {
262     DCHECK(self->IsExceptionPending());
263     AbortTransactionOrFail(self,
264                            "Class.getPrimitiveClass() failed: %s",
265                            self->GetException()->GetDetailMessage()->ToModifiedUtf8().c_str());
266     return;
267   }
268   result->SetL(klass);
269 }
270 
UnstartedClassClassForName(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)271 void UnstartedRuntime::UnstartedClassClassForName(
272     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
273   UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.classForName");
274 }
275 
UnstartedClassNewInstance(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)276 void UnstartedRuntime::UnstartedClassNewInstance(
277     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
278   StackHandleScope<2> hs(self);  // Class, constructor, object.
279   mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
280   if (param == nullptr) {
281     AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
282     return;
283   }
284   Handle<mirror::Class> h_klass(hs.NewHandle(param->AsClass()));
285 
286   // Check that it's not null.
287   if (h_klass == nullptr) {
288     AbortTransactionOrFail(self, "Class reference is null for newInstance");
289     return;
290   }
291 
292   // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
293   if (Runtime::Current()->IsActiveTransaction()) {
294     if (h_klass->IsFinalizable()) {
295       AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
296                         h_klass->PrettyClass().c_str());
297       return;
298     }
299   }
300 
301   // There are two situations in which we'll abort this run.
302   //  1) If the class isn't yet initialized and initialization fails.
303   //  2) If we can't find the default constructor. We'll postpone the exception to runtime.
304   // Note that 2) could likely be handled here, but for safety abort the transaction.
305   bool ok = false;
306   auto* cl = Runtime::Current()->GetClassLinker();
307   if (cl->EnsureInitialized(self, h_klass, true, true)) {
308     ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
309     if (cons != nullptr && ShouldDenyAccessToMember(cons, shadow_frame)) {
310       cons = nullptr;
311     }
312     if (cons != nullptr) {
313       Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(self)));
314       CHECK(h_obj != nullptr);  // We don't expect OOM at compile-time.
315       EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
316       if (!self->IsExceptionPending()) {
317         result->SetL(h_obj.Get());
318         ok = true;
319       }
320     } else {
321       self->ThrowNewExceptionF("Ljava/lang/InternalError;",
322                                "Could not find default constructor for '%s'",
323                                h_klass->PrettyClass().c_str());
324     }
325   }
326   if (!ok) {
327     AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
328                            h_klass->PrettyClass().c_str(),
329                            mirror::Object::PrettyTypeOf(self->GetException()).c_str());
330   }
331 }
332 
UnstartedClassGetDeclaredField(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)333 void UnstartedRuntime::UnstartedClassGetDeclaredField(
334     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
335   // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
336   // going the reflective Dex way.
337   ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
338   ObjPtr<mirror::String> name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
339   ArtField* found = nullptr;
340   for (ArtField& field : klass->GetIFields()) {
341     if (name2->Equals(field.GetName())) {
342       found = &field;
343       break;
344     }
345   }
346   if (found == nullptr) {
347     for (ArtField& field : klass->GetSFields()) {
348       if (name2->Equals(field.GetName())) {
349         found = &field;
350         break;
351       }
352     }
353   }
354   if (found != nullptr && ShouldDenyAccessToMember(found, shadow_frame)) {
355     found = nullptr;
356   }
357   if (found == nullptr) {
358     AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
359                            " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
360                            klass->PrettyDescriptor().c_str());
361     return;
362   }
363   Runtime* runtime = Runtime::Current();
364   PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
365   ObjPtr<mirror::Field> field;
366   if (runtime->IsActiveTransaction()) {
367     if (pointer_size == PointerSize::k64) {
368       field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
369           self, found, true);
370     } else {
371       field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
372           self, found, true);
373     }
374   } else {
375     if (pointer_size == PointerSize::k64) {
376       field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
377           self, found, true);
378     } else {
379       field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
380           self, found, true);
381     }
382   }
383   result->SetL(field);
384 }
385 
386 // This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
UnstartedClassGetDeclaredMethod(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)387 void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
388     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
389   // Special managed code cut-out to allow method lookup in a un-started runtime.
390   ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
391   if (klass == nullptr) {
392     ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
393     return;
394   }
395   ObjPtr<mirror::String> name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
396   ObjPtr<mirror::ObjectArray<mirror::Class>> args =
397       shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
398   Runtime* runtime = Runtime::Current();
399   bool transaction = runtime->IsActiveTransaction();
400   PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
401   auto fn_hiddenapi_access_context = GetHiddenapiAccessContextFunction(shadow_frame);
402   ObjPtr<mirror::Method> method;
403   if (transaction) {
404     if (pointer_size == PointerSize::k64) {
405       method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
406           self, klass, name, args, fn_hiddenapi_access_context);
407     } else {
408       method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
409           self, klass, name, args, fn_hiddenapi_access_context);
410     }
411   } else {
412     if (pointer_size == PointerSize::k64) {
413       method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
414           self, klass, name, args, fn_hiddenapi_access_context);
415     } else {
416       method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
417           self, klass, name, args, fn_hiddenapi_access_context);
418     }
419   }
420   if (method != nullptr && ShouldDenyAccessToMember(method->GetArtMethod(), shadow_frame)) {
421     method = nullptr;
422   }
423   result->SetL(method);
424 }
425 
426 // Special managed code cut-out to allow constructor lookup in a un-started runtime.
UnstartedClassGetDeclaredConstructor(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)427 void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
428     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
429   ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
430   if (klass == nullptr) {
431     ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
432     return;
433   }
434   ObjPtr<mirror::ObjectArray<mirror::Class>> args =
435       shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
436   Runtime* runtime = Runtime::Current();
437   bool transaction = runtime->IsActiveTransaction();
438   PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
439   ObjPtr<mirror::Constructor> constructor;
440   if (transaction) {
441     if (pointer_size == PointerSize::k64) {
442       constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
443                                                                   true>(self, klass, args);
444     } else {
445       constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
446                                                                   true>(self, klass, args);
447     }
448   } else {
449     if (pointer_size == PointerSize::k64) {
450       constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
451                                                                   false>(self, klass, args);
452     } else {
453       constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
454                                                                   false>(self, klass, args);
455     }
456   }
457   if (constructor != nullptr &&
458       ShouldDenyAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
459     constructor = nullptr;
460   }
461   result->SetL(constructor);
462 }
463 
UnstartedClassGetDeclaringClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)464 void UnstartedRuntime::UnstartedClassGetDeclaringClass(
465     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
466   StackHandleScope<1> hs(self);
467   Handle<mirror::Class> klass(hs.NewHandle(
468       reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
469   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
470     result->SetL(nullptr);
471     return;
472   }
473   // Return null for anonymous classes.
474   JValue is_anon_result;
475   UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
476   if (is_anon_result.GetZ() != 0) {
477     result->SetL(nullptr);
478     return;
479   }
480   result->SetL(annotations::GetDeclaringClass(klass));
481 }
482 
UnstartedClassGetEnclosingClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)483 void UnstartedRuntime::UnstartedClassGetEnclosingClass(
484     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
485   StackHandleScope<1> hs(self);
486   Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
487   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
488     result->SetL(nullptr);
489   }
490   result->SetL(annotations::GetEnclosingClass(klass));
491 }
492 
UnstartedClassGetInnerClassFlags(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)493 void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
494     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
495   StackHandleScope<1> hs(self);
496   Handle<mirror::Class> klass(hs.NewHandle(
497       reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
498   const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
499   result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
500 }
501 
UnstartedClassGetSignatureAnnotation(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)502 void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
503     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
504   StackHandleScope<1> hs(self);
505   Handle<mirror::Class> klass(hs.NewHandle(
506       reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
507 
508   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
509     result->SetL(nullptr);
510     return;
511   }
512 
513   result->SetL(annotations::GetSignatureAnnotationForClass(klass));
514 }
515 
UnstartedClassIsAnonymousClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)516 void UnstartedRuntime::UnstartedClassIsAnonymousClass(
517     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
518   StackHandleScope<1> hs(self);
519   Handle<mirror::Class> klass(hs.NewHandle(
520       reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
521   if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
522     result->SetZ(false);
523     return;
524   }
525   ObjPtr<mirror::String> class_name = nullptr;
526   if (!annotations::GetInnerClass(klass, &class_name)) {
527     result->SetZ(false);
528     return;
529   }
530   result->SetZ(class_name == nullptr);
531 }
532 
FindAndExtractEntry(const std::string & jar_file,const char * entry_name,size_t * size,std::string * error_msg)533 static MemMap FindAndExtractEntry(const std::string& jar_file,
534                                   const char* entry_name,
535                                   size_t* size,
536                                   std::string* error_msg) {
537   CHECK(size != nullptr);
538 
539   std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
540   if (zip_archive == nullptr) {
541     return MemMap::Invalid();
542   }
543   std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
544   if (zip_entry == nullptr) {
545     return MemMap::Invalid();
546   }
547   MemMap tmp_map = zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg);
548   if (!tmp_map.IsValid()) {
549     return MemMap::Invalid();
550   }
551 
552   // OK, from here everything seems fine.
553   *size = zip_entry->GetUncompressedLength();
554   return tmp_map;
555 }
556 
GetResourceAsStream(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)557 static void GetResourceAsStream(Thread* self,
558                                 ShadowFrame* shadow_frame,
559                                 JValue* result,
560                                 size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
561   mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
562   if (resource_obj == nullptr) {
563     AbortTransactionOrFail(self, "null name for getResourceAsStream");
564     return;
565   }
566   CHECK(resource_obj->IsString());
567   ObjPtr<mirror::String> resource_name = resource_obj->AsString();
568 
569   std::string resource_name_str = resource_name->ToModifiedUtf8();
570   if (resource_name_str.empty() || resource_name_str == "/") {
571     AbortTransactionOrFail(self,
572                            "Unsupported name %s for getResourceAsStream",
573                            resource_name_str.c_str());
574     return;
575   }
576   const char* resource_cstr = resource_name_str.c_str();
577   if (resource_cstr[0] == '/') {
578     resource_cstr++;
579   }
580 
581   Runtime* runtime = Runtime::Current();
582 
583   const std::vector<std::string>& boot_class_path = Runtime::Current()->GetBootClassPath();
584   if (boot_class_path.empty()) {
585     AbortTransactionOrFail(self, "Boot classpath not set");
586     return;
587   }
588 
589   MemMap mem_map;
590   size_t map_size;
591   std::string last_error_msg;  // Only store the last message (we could concatenate).
592 
593   for (const std::string& jar_file : boot_class_path) {
594     mem_map = FindAndExtractEntry(jar_file, resource_cstr, &map_size, &last_error_msg);
595     if (mem_map.IsValid()) {
596       break;
597     }
598   }
599 
600   if (!mem_map.IsValid()) {
601     // Didn't find it. There's a good chance this will be the same at runtime, but still
602     // conservatively abort the transaction here.
603     AbortTransactionOrFail(self,
604                            "Could not find resource %s. Last error was %s.",
605                            resource_name_str.c_str(),
606                            last_error_msg.c_str());
607     return;
608   }
609 
610   StackHandleScope<3> hs(self);
611 
612   // Create byte array for content.
613   Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
614   if (h_array == nullptr) {
615     AbortTransactionOrFail(self, "Could not find/create byte array class");
616     return;
617   }
618   // Copy in content.
619   memcpy(h_array->GetData(), mem_map.Begin(), map_size);
620   // Be proactive releasing memory.
621   mem_map.Reset();
622 
623   // Create a ByteArrayInputStream.
624   Handle<mirror::Class> h_class(hs.NewHandle(
625       runtime->GetClassLinker()->FindClass(self,
626                                            "Ljava/io/ByteArrayInputStream;",
627                                            ScopedNullHandle<mirror::ClassLoader>())));
628   if (h_class == nullptr) {
629     AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
630     return;
631   }
632   if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
633     AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
634     return;
635   }
636 
637   Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
638   if (h_obj == nullptr) {
639     AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
640     return;
641   }
642 
643   auto* cl = Runtime::Current()->GetClassLinker();
644   ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
645   if (constructor == nullptr) {
646     AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
647     return;
648   }
649 
650   uint32_t args[1];
651   args[0] = reinterpret_cast32<uint32_t>(h_array.Get());
652   EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
653 
654   if (self->IsExceptionPending()) {
655     AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
656     return;
657   }
658 
659   result->SetL(h_obj.Get());
660 }
661 
UnstartedClassLoaderGetResourceAsStream(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)662 void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
663     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
664   {
665     mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
666     CHECK(this_obj != nullptr);
667     CHECK(this_obj->IsClassLoader());
668 
669     StackHandleScope<1> hs(self);
670     Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
671 
672     if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
673             this_classloader_class.Get()) {
674       AbortTransactionOrFail(self,
675                              "Unsupported classloader type %s for getResourceAsStream",
676                              mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
677       return;
678     }
679   }
680 
681   GetResourceAsStream(self, shadow_frame, result, arg_offset);
682 }
683 
UnstartedConstructorNewInstance0(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)684 void UnstartedRuntime::UnstartedConstructorNewInstance0(
685     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
686   // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
687   StackHandleScope<4> hs(self);
688   Handle<mirror::Constructor> m = hs.NewHandle(
689       reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
690   Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
691       reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
692           shadow_frame->GetVRegReference(arg_offset + 1)));
693   Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
694   if (UNLIKELY(c->IsAbstract())) {
695     AbortTransactionOrFail(self, "Cannot handle abstract classes");
696     return;
697   }
698   // Verify that we can access the class.
699   if (!m->IsAccessible() && !c->IsPublic()) {
700     // Go 2 frames back, this method is always called from newInstance0, which is called from
701     // Constructor.newInstance(Object... args).
702     ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
703     // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
704     // access checks anyways. TODO: Investigate if this the correct behavior.
705     if (caller != nullptr && !caller->CanAccess(c.Get())) {
706       AbortTransactionOrFail(self, "Cannot access class");
707       return;
708     }
709   }
710   if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
711     DCHECK(self->IsExceptionPending());
712     return;
713   }
714   if (c->IsClassClass()) {
715     AbortTransactionOrFail(self, "new Class() is not supported");
716     return;
717   }
718 
719   // String constructor is replaced by a StringFactory method in InvokeMethod.
720   if (c->IsStringClass()) {
721     // We don't support strings.
722     AbortTransactionOrFail(self, "String construction is not supported");
723     return;
724   }
725 
726   Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
727   if (receiver == nullptr) {
728     AbortTransactionOrFail(self, "Could not allocate");
729     return;
730   }
731 
732   // It's easier to use reflection to make the call, than create the uint32_t array.
733   {
734     ScopedObjectAccessUnchecked soa(self);
735     ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
736                                        soa.AddLocalReference<jobject>(m.Get()));
737     ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
738                                        soa.AddLocalReference<jobject>(receiver.Get()));
739     ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
740                                      soa.AddLocalReference<jobject>(args.Get()));
741     InvokeMethod(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
742   }
743   if (self->IsExceptionPending()) {
744     AbortTransactionOrFail(self, "Failed running constructor");
745   } else {
746     result->SetL(receiver.Get());
747   }
748 }
749 
UnstartedVmClassLoaderFindLoadedClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)750 void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
751     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
752   ObjPtr<mirror::String> class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
753   ObjPtr<mirror::ClassLoader> class_loader =
754       ObjPtr<mirror::ClassLoader>::DownCast(shadow_frame->GetVRegReference(arg_offset));
755   StackHandleScope<2> hs(self);
756   Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
757   Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
758   UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
759                             "VMClassLoader.findLoadedClass", false, false);
760   // This might have an error pending. But semantics are to just return null.
761   if (self->IsExceptionPending()) {
762     // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
763     std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
764     if (type != "java.lang.InternalError") {
765       self->ClearException();
766     }
767   }
768 }
769 
770 // Arraycopy emulation.
771 // Note: we can't use any fast copy functions, as they are not available under transaction.
772 
773 template <typename T>
PrimitiveArrayCopy(Thread * self,ObjPtr<mirror::Array> src_array,int32_t src_pos,ObjPtr<mirror::Array> dst_array,int32_t dst_pos,int32_t length)774 static void PrimitiveArrayCopy(Thread* self,
775                                ObjPtr<mirror::Array> src_array,
776                                int32_t src_pos,
777                                ObjPtr<mirror::Array> dst_array,
778                                int32_t dst_pos,
779                                int32_t length)
780     REQUIRES_SHARED(Locks::mutator_lock_) {
781   if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
782     AbortTransactionOrFail(self,
783                            "Types mismatched in arraycopy: %s vs %s.",
784                            mirror::Class::PrettyDescriptor(
785                                src_array->GetClass()->GetComponentType()).c_str(),
786                            mirror::Class::PrettyDescriptor(
787                                dst_array->GetClass()->GetComponentType()).c_str());
788     return;
789   }
790   ObjPtr<mirror::PrimitiveArray<T>> src = ObjPtr<mirror::PrimitiveArray<T>>::DownCast(src_array);
791   ObjPtr<mirror::PrimitiveArray<T>> dst = ObjPtr<mirror::PrimitiveArray<T>>::DownCast(dst_array);
792   const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
793   if (copy_forward) {
794     for (int32_t i = 0; i < length; ++i) {
795       dst->Set(dst_pos + i, src->Get(src_pos + i));
796     }
797   } else {
798     for (int32_t i = 1; i <= length; ++i) {
799       dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
800     }
801   }
802 }
803 
UnstartedSystemArraycopy(Thread * self,ShadowFrame * shadow_frame,JValue * result ATTRIBUTE_UNUSED,size_t arg_offset)804 void UnstartedRuntime::UnstartedSystemArraycopy(
805     Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
806   // Special case array copying without initializing System.
807   jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
808   jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
809   jint length = shadow_frame->GetVReg(arg_offset + 4);
810 
811   mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
812   mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
813   // Null checking. For simplicity, abort transaction.
814   if (src_obj == nullptr) {
815     AbortTransactionOrFail(self, "src is null in arraycopy.");
816     return;
817   }
818   if (dst_obj == nullptr) {
819     AbortTransactionOrFail(self, "dst is null in arraycopy.");
820     return;
821   }
822   // Test for arrayness. Throw ArrayStoreException.
823   if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
824     self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
825     return;
826   }
827 
828   ObjPtr<mirror::Array> src_array = src_obj->AsArray();
829   ObjPtr<mirror::Array> dst_array = dst_obj->AsArray();
830 
831   // Bounds checking. Throw IndexOutOfBoundsException.
832   if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
833       UNLIKELY(src_pos > src_array->GetLength() - length) ||
834       UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
835     self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
836                              "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
837                              src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
838                              length);
839     return;
840   }
841 
842   if (Runtime::Current()->IsActiveTransaction() && !CheckWriteConstraint(self, dst_obj)) {
843     DCHECK(self->IsExceptionPending());
844     return;
845   }
846 
847   // Type checking.
848   ObjPtr<mirror::Class> src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
849       GetComponentType();
850 
851   if (!src_type->IsPrimitive()) {
852     // Check that the second type is not primitive.
853     ObjPtr<mirror::Class> trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
854         GetComponentType();
855     if (trg_type->IsPrimitiveInt()) {
856       AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
857                              mirror::Class::PrettyDescriptor(
858                                  src_array->GetClass()->GetComponentType()).c_str(),
859                              mirror::Class::PrettyDescriptor(
860                                  dst_array->GetClass()->GetComponentType()).c_str());
861       return;
862     }
863 
864     ObjPtr<mirror::ObjectArray<mirror::Object>> src = src_array->AsObjectArray<mirror::Object>();
865     ObjPtr<mirror::ObjectArray<mirror::Object>> dst = dst_array->AsObjectArray<mirror::Object>();
866     if (src == dst) {
867       // Can overlap, but not have type mismatches.
868       // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
869       const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
870       if (copy_forward) {
871         for (int32_t i = 0; i < length; ++i) {
872           dst->Set(dst_pos + i, src->Get(src_pos + i));
873         }
874       } else {
875         for (int32_t i = 1; i <= length; ++i) {
876           dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
877         }
878       }
879     } else {
880       // We're being lazy here. Optimally this could be a memcpy (if component types are
881       // assignable), but the ObjectArray implementation doesn't support transactions. The
882       // checking version, however, does.
883       if (Runtime::Current()->IsActiveTransaction()) {
884         dst->AssignableCheckingMemcpy<true>(
885             dst_pos, src, src_pos, length, /* throw_exception= */ true);
886       } else {
887         dst->AssignableCheckingMemcpy<false>(
888             dst_pos, src, src_pos, length, /* throw_exception= */ true);
889       }
890     }
891   } else if (src_type->IsPrimitiveByte()) {
892     PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
893   } else if (src_type->IsPrimitiveChar()) {
894     PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
895   } else if (src_type->IsPrimitiveInt()) {
896     PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
897   } else {
898     AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
899                            src_type->PrettyDescriptor().c_str());
900   }
901 }
902 
UnstartedSystemArraycopyByte(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)903 void UnstartedRuntime::UnstartedSystemArraycopyByte(
904     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
905   // Just forward.
906   UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
907 }
908 
UnstartedSystemArraycopyChar(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)909 void UnstartedRuntime::UnstartedSystemArraycopyChar(
910     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
911   // Just forward.
912   UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
913 }
914 
UnstartedSystemArraycopyInt(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)915 void UnstartedRuntime::UnstartedSystemArraycopyInt(
916     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
917   // Just forward.
918   UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
919 }
920 
UnstartedSystemGetSecurityManager(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame ATTRIBUTE_UNUSED,JValue * result,size_t arg_offset ATTRIBUTE_UNUSED)921 void UnstartedRuntime::UnstartedSystemGetSecurityManager(
922     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
923     JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
924   result->SetL(nullptr);
925 }
926 
927 static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
928 
GetSystemProperty(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset,bool is_default_version)929 static void GetSystemProperty(Thread* self,
930                               ShadowFrame* shadow_frame,
931                               JValue* result,
932                               size_t arg_offset,
933                               bool is_default_version)
934     REQUIRES_SHARED(Locks::mutator_lock_) {
935   StackHandleScope<4> hs(self);
936   Handle<mirror::String> h_key(
937       hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
938   if (h_key == nullptr) {
939     AbortTransactionOrFail(self, "getProperty key was null");
940     return;
941   }
942 
943   // This is overall inefficient, but reflecting the values here is not great, either. So
944   // for simplicity, and with the assumption that the number of getProperty calls is not
945   // too great, just iterate each time.
946 
947   // Get the storage class.
948   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
949   Handle<mirror::Class> h_props_class(hs.NewHandle(
950       class_linker->FindClass(self,
951                               "Ljava/lang/AndroidHardcodedSystemProperties;",
952                               ScopedNullHandle<mirror::ClassLoader>())));
953   if (h_props_class == nullptr) {
954     AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
955     return;
956   }
957   if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
958     AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
959     return;
960   }
961 
962   // Get the storage array.
963   ArtField* static_properties =
964       h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
965                                              "[[Ljava/lang/String;");
966   if (static_properties == nullptr) {
967     AbortTransactionOrFail(self,
968                            "Could not find %s field",
969                            kAndroidHardcodedSystemPropertiesFieldName);
970     return;
971   }
972   ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
973   Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
974       props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
975   if (h_2string_array == nullptr) {
976     AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
977     return;
978   }
979 
980   // Iterate over it.
981   const int32_t prop_count = h_2string_array->GetLength();
982   // Use the third handle as mutable.
983   MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
984       hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
985   for (int32_t i = 0; i < prop_count; ++i) {
986     h_string_array.Assign(h_2string_array->Get(i));
987     if (h_string_array == nullptr ||
988         h_string_array->GetLength() != 2 ||
989         h_string_array->Get(0) == nullptr) {
990       AbortTransactionOrFail(self,
991                              "Unexpected content of %s",
992                              kAndroidHardcodedSystemPropertiesFieldName);
993       return;
994     }
995     if (h_key->Equals(h_string_array->Get(0))) {
996       // Found a value.
997       if (h_string_array->Get(1) == nullptr && is_default_version) {
998         // Null is being delegated to the default map, and then resolved to the given default value.
999         // As there's no default map, return the given value.
1000         result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
1001       } else {
1002         result->SetL(h_string_array->Get(1));
1003       }
1004       return;
1005     }
1006   }
1007 
1008   // Key is not supported.
1009   AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
1010 }
1011 
UnstartedSystemGetProperty(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1012 void UnstartedRuntime::UnstartedSystemGetProperty(
1013     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1014   GetSystemProperty(self, shadow_frame, result, arg_offset, false);
1015 }
1016 
UnstartedSystemGetPropertyWithDefault(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1017 void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
1018     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1019   GetSystemProperty(self, shadow_frame, result, arg_offset, true);
1020 }
1021 
GetImmediateCaller(ShadowFrame * shadow_frame)1022 static std::string GetImmediateCaller(ShadowFrame* shadow_frame)
1023     REQUIRES_SHARED(Locks::mutator_lock_) {
1024   if (shadow_frame->GetLink() == nullptr) {
1025     return "<no caller>";
1026   }
1027   return ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1028 }
1029 
CheckCallers(ShadowFrame * shadow_frame,std::initializer_list<std::string> allowed_call_stack)1030 static bool CheckCallers(ShadowFrame* shadow_frame,
1031                          std::initializer_list<std::string> allowed_call_stack)
1032     REQUIRES_SHARED(Locks::mutator_lock_) {
1033   for (const std::string& allowed_caller : allowed_call_stack) {
1034     if (shadow_frame->GetLink() == nullptr) {
1035       return false;
1036     }
1037 
1038     std::string found_caller = ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1039     if (allowed_caller != found_caller) {
1040       return false;
1041     }
1042 
1043     shadow_frame = shadow_frame->GetLink();
1044   }
1045   return true;
1046 }
1047 
CreateInstanceOf(Thread * self,const char * class_descriptor)1048 static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_descriptor)
1049     REQUIRES_SHARED(Locks::mutator_lock_) {
1050   // Find the requested class.
1051   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1052   ObjPtr<mirror::Class> klass =
1053       class_linker->FindClass(self, class_descriptor, ScopedNullHandle<mirror::ClassLoader>());
1054   if (klass == nullptr) {
1055     AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
1056     return nullptr;
1057   }
1058 
1059   StackHandleScope<2> hs(self);
1060   Handle<mirror::Class> h_class(hs.NewHandle(klass));
1061   Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
1062   if (h_obj != nullptr) {
1063     ArtMethod* init_method = h_class->FindConstructor("()V", class_linker->GetImagePointerSize());
1064     if (init_method == nullptr) {
1065       AbortTransactionOrFail(self, "Could not find <init> for %s", class_descriptor);
1066       return nullptr;
1067     } else {
1068       JValue invoke_result;
1069       EnterInterpreterFromInvoke(self, init_method, h_obj.Get(), nullptr, nullptr);
1070       if (!self->IsExceptionPending()) {
1071         return h_obj.Get();
1072       }
1073       AbortTransactionOrFail(self, "Could not run <init> for %s", class_descriptor);
1074     }
1075   }
1076   AbortTransactionOrFail(self, "Could not allocate instance of %s", class_descriptor);
1077   return nullptr;
1078 }
1079 
UnstartedThreadLocalGet(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset ATTRIBUTE_UNUSED)1080 void UnstartedRuntime::UnstartedThreadLocalGet(
1081     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1082   if (CheckCallers(shadow_frame, { "sun.misc.FloatingDecimal$BinaryToASCIIBuffer "
1083                                        "sun.misc.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1084     result->SetL(CreateInstanceOf(self, "Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;"));
1085   } else {
1086     AbortTransactionOrFail(self,
1087                            "ThreadLocal.get() does not support %s",
1088                            GetImmediateCaller(shadow_frame).c_str());
1089   }
1090 }
1091 
UnstartedThreadCurrentThread(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset ATTRIBUTE_UNUSED)1092 void UnstartedRuntime::UnstartedThreadCurrentThread(
1093     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1094   if (CheckCallers(shadow_frame,
1095                    { "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1096                          "java.lang.String, long, java.security.AccessControlContext)",
1097                      "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1098                          "java.lang.String, long)",
1099                      "void java.lang.Thread.<init>()",
1100                      "void java.util.logging.LogManager$Cleaner.<init>("
1101                          "java.util.logging.LogManager)" })) {
1102     // Whitelist LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
1103     // Thread constructor only asks for the current thread to set up defaults and add the
1104     // thread as unstarted to the ThreadGroup. A faked-up main thread peer is good enough for
1105     // these purposes.
1106     Runtime::Current()->InitThreadGroups(self);
1107     jobject main_peer =
1108         self->CreateCompileTimePeer(self->GetJniEnv(),
1109                                     "main",
1110                                     false,
1111                                     Runtime::Current()->GetMainThreadGroup());
1112     if (main_peer == nullptr) {
1113       AbortTransactionOrFail(self, "Failed allocating peer");
1114       return;
1115     }
1116 
1117     result->SetL(self->DecodeJObject(main_peer));
1118     self->GetJniEnv()->DeleteLocalRef(main_peer);
1119   } else {
1120     AbortTransactionOrFail(self,
1121                            "Thread.currentThread() does not support %s",
1122                            GetImmediateCaller(shadow_frame).c_str());
1123   }
1124 }
1125 
UnstartedThreadGetNativeState(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset ATTRIBUTE_UNUSED)1126 void UnstartedRuntime::UnstartedThreadGetNativeState(
1127     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1128   if (CheckCallers(shadow_frame,
1129                    { "java.lang.Thread$State java.lang.Thread.getState()",
1130                      "java.lang.ThreadGroup java.lang.Thread.getThreadGroup()",
1131                      "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1132                          "java.lang.String, long, java.security.AccessControlContext)",
1133                      "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1134                          "java.lang.String, long)",
1135                      "void java.lang.Thread.<init>()",
1136                      "void java.util.logging.LogManager$Cleaner.<init>("
1137                          "java.util.logging.LogManager)" })) {
1138     // Whitelist reading the state of the "main" thread when creating another (unstarted) thread
1139     // for LogManager. Report the thread as "new" (it really only counts that it isn't terminated).
1140     constexpr int32_t kJavaRunnable = 1;
1141     result->SetI(kJavaRunnable);
1142   } else {
1143     AbortTransactionOrFail(self,
1144                            "Thread.getNativeState() does not support %s",
1145                            GetImmediateCaller(shadow_frame).c_str());
1146   }
1147 }
1148 
UnstartedMathCeil(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1149 void UnstartedRuntime::UnstartedMathCeil(
1150     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1151   result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
1152 }
1153 
UnstartedMathFloor(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1154 void UnstartedRuntime::UnstartedMathFloor(
1155     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1156   result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
1157 }
1158 
UnstartedMathSin(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1159 void UnstartedRuntime::UnstartedMathSin(
1160     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1161   result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
1162 }
1163 
UnstartedMathCos(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1164 void UnstartedRuntime::UnstartedMathCos(
1165     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1166   result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
1167 }
1168 
UnstartedMathPow(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1169 void UnstartedRuntime::UnstartedMathPow(
1170     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1171   result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
1172                    shadow_frame->GetVRegDouble(arg_offset + 2)));
1173 }
1174 
UnstartedObjectHashCode(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1175 void UnstartedRuntime::UnstartedObjectHashCode(
1176     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1177   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1178   result->SetI(obj->IdentityHashCode());
1179 }
1180 
UnstartedDoubleDoubleToRawLongBits(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1181 void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
1182     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1183   double in = shadow_frame->GetVRegDouble(arg_offset);
1184   result->SetJ(bit_cast<int64_t, double>(in));
1185 }
1186 
UnstartedMemoryPeek(Primitive::Type type,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1187 static void UnstartedMemoryPeek(
1188     Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1189   int64_t address = shadow_frame->GetVRegLong(arg_offset);
1190   // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
1191   //       aborting the transaction.
1192 
1193   switch (type) {
1194     case Primitive::kPrimByte: {
1195       result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
1196       return;
1197     }
1198 
1199     case Primitive::kPrimShort: {
1200       using unaligned_short __attribute__((__aligned__(1))) = int16_t;
1201       result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
1202       return;
1203     }
1204 
1205     case Primitive::kPrimInt: {
1206       using unaligned_int __attribute__((__aligned__(1))) = int32_t;
1207       result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
1208       return;
1209     }
1210 
1211     case Primitive::kPrimLong: {
1212       using unaligned_long __attribute__((__aligned__(1))) = int64_t;
1213       result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
1214       return;
1215     }
1216 
1217     case Primitive::kPrimBoolean:
1218     case Primitive::kPrimChar:
1219     case Primitive::kPrimFloat:
1220     case Primitive::kPrimDouble:
1221     case Primitive::kPrimVoid:
1222     case Primitive::kPrimNot:
1223       LOG(FATAL) << "Not in the Memory API: " << type;
1224       UNREACHABLE();
1225   }
1226   LOG(FATAL) << "Should not reach here";
1227   UNREACHABLE();
1228 }
1229 
UnstartedMemoryPeekByte(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1230 void UnstartedRuntime::UnstartedMemoryPeekByte(
1231     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1232   UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
1233 }
1234 
UnstartedMemoryPeekShort(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1235 void UnstartedRuntime::UnstartedMemoryPeekShort(
1236     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1237   UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
1238 }
1239 
UnstartedMemoryPeekInt(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1240 void UnstartedRuntime::UnstartedMemoryPeekInt(
1241     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1242   UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
1243 }
1244 
UnstartedMemoryPeekLong(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1245 void UnstartedRuntime::UnstartedMemoryPeekLong(
1246     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1247   UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
1248 }
1249 
UnstartedMemoryPeekArray(Primitive::Type type,Thread * self,ShadowFrame * shadow_frame,size_t arg_offset)1250 static void UnstartedMemoryPeekArray(
1251     Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
1252     REQUIRES_SHARED(Locks::mutator_lock_) {
1253   int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1254   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1255   if (obj == nullptr) {
1256     Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
1257     return;
1258   }
1259   ObjPtr<mirror::Array> array = obj->AsArray();
1260 
1261   int offset = shadow_frame->GetVReg(arg_offset + 3);
1262   int count = shadow_frame->GetVReg(arg_offset + 4);
1263   if (offset < 0 || offset + count > array->GetLength()) {
1264     std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
1265                                        offset, count, array->GetLength()));
1266     Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
1267     return;
1268   }
1269 
1270   switch (type) {
1271     case Primitive::kPrimByte: {
1272       int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
1273       ObjPtr<mirror::ByteArray> byte_array = array->AsByteArray();
1274       for (int32_t i = 0; i < count; ++i, ++address) {
1275         byte_array->SetWithoutChecks<true>(i + offset, *address);
1276       }
1277       return;
1278     }
1279 
1280     case Primitive::kPrimShort:
1281     case Primitive::kPrimInt:
1282     case Primitive::kPrimLong:
1283       LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1284       UNREACHABLE();
1285 
1286     case Primitive::kPrimBoolean:
1287     case Primitive::kPrimChar:
1288     case Primitive::kPrimFloat:
1289     case Primitive::kPrimDouble:
1290     case Primitive::kPrimVoid:
1291     case Primitive::kPrimNot:
1292       LOG(FATAL) << "Not in the Memory API: " << type;
1293       UNREACHABLE();
1294   }
1295   LOG(FATAL) << "Should not reach here";
1296   UNREACHABLE();
1297 }
1298 
UnstartedMemoryPeekByteArray(Thread * self,ShadowFrame * shadow_frame,JValue * result ATTRIBUTE_UNUSED,size_t arg_offset)1299 void UnstartedRuntime::UnstartedMemoryPeekByteArray(
1300     Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
1301   UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
1302 }
1303 
1304 // This allows reading the new style of String objects during compilation.
UnstartedStringGetCharsNoCheck(Thread * self,ShadowFrame * shadow_frame,JValue * result ATTRIBUTE_UNUSED,size_t arg_offset)1305 void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
1306     Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
1307   jint start = shadow_frame->GetVReg(arg_offset + 1);
1308   jint end = shadow_frame->GetVReg(arg_offset + 2);
1309   jint index = shadow_frame->GetVReg(arg_offset + 4);
1310   ObjPtr<mirror::String> string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1311   if (string == nullptr) {
1312     AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1313     return;
1314   }
1315   DCHECK_GE(start, 0);
1316   DCHECK_LE(start, end);
1317   DCHECK_LE(end, string->GetLength());
1318   StackHandleScope<1> hs(self);
1319   Handle<mirror::CharArray> h_char_array(
1320       hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
1321   DCHECK_GE(index, 0);
1322   DCHECK_LE(index, h_char_array->GetLength());
1323   DCHECK_LE(end - start, h_char_array->GetLength() - index);
1324   string->GetChars(start, end, h_char_array, index);
1325 }
1326 
1327 // This allows reading chars from the new style of String objects during compilation.
UnstartedStringCharAt(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1328 void UnstartedRuntime::UnstartedStringCharAt(
1329     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1330   jint index = shadow_frame->GetVReg(arg_offset + 1);
1331   ObjPtr<mirror::String> string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1332   if (string == nullptr) {
1333     AbortTransactionOrFail(self, "String.charAt with null object");
1334     return;
1335   }
1336   result->SetC(string->CharAt(index));
1337 }
1338 
1339 // This allows creating String objects with replaced characters during compilation.
1340 // String.doReplace(char, char) is called from String.replace(char, char) when there is a match.
UnstartedStringDoReplace(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1341 void UnstartedRuntime::UnstartedStringDoReplace(
1342     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1343   jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
1344   jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
1345   StackHandleScope<1> hs(self);
1346   Handle<mirror::String> string =
1347       hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
1348   if (string == nullptr) {
1349     AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
1350     return;
1351   }
1352   result->SetL(mirror::String::DoReplace(self, string, old_c, new_c));
1353 }
1354 
1355 // This allows creating the new style of String objects during compilation.
UnstartedStringFactoryNewStringFromChars(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1356 void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
1357     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1358   jint offset = shadow_frame->GetVReg(arg_offset);
1359   jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1360   DCHECK_GE(char_count, 0);
1361   StackHandleScope<1> hs(self);
1362   Handle<mirror::CharArray> h_char_array(
1363       hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
1364   Runtime* runtime = Runtime::Current();
1365   gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1366   result->SetL(
1367       mirror::String::AllocFromCharArray(self, char_count, h_char_array, offset, allocator));
1368 }
1369 
1370 // This allows creating the new style of String objects during compilation.
UnstartedStringFactoryNewStringFromString(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1371 void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
1372     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1373   ObjPtr<mirror::String> to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1374   if (to_copy == nullptr) {
1375     AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1376     return;
1377   }
1378   StackHandleScope<1> hs(self);
1379   Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1380   Runtime* runtime = Runtime::Current();
1381   gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1382   result->SetL(
1383       mirror::String::AllocFromString(self, h_string->GetLength(), h_string, 0, allocator));
1384 }
1385 
UnstartedStringFastSubstring(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1386 void UnstartedRuntime::UnstartedStringFastSubstring(
1387     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1388   jint start = shadow_frame->GetVReg(arg_offset + 1);
1389   jint length = shadow_frame->GetVReg(arg_offset + 2);
1390   DCHECK_GE(start, 0);
1391   DCHECK_GE(length, 0);
1392   StackHandleScope<1> hs(self);
1393   Handle<mirror::String> h_string(
1394       hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
1395   DCHECK_LE(start, h_string->GetLength());
1396   DCHECK_LE(start + length, h_string->GetLength());
1397   Runtime* runtime = Runtime::Current();
1398   gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1399   result->SetL(mirror::String::AllocFromString(self, length, h_string, start, allocator));
1400 }
1401 
1402 // This allows getting the char array for new style of String objects during compilation.
UnstartedStringToCharArray(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1403 void UnstartedRuntime::UnstartedStringToCharArray(
1404     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1405     REQUIRES_SHARED(Locks::mutator_lock_) {
1406   StackHandleScope<1> hs(self);
1407   Handle<mirror::String> string =
1408       hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
1409   if (string == nullptr) {
1410     AbortTransactionOrFail(self, "String.charAt with null object");
1411     return;
1412   }
1413   result->SetL(mirror::String::ToCharArray(string, self));
1414 }
1415 
1416 // This allows statically initializing ConcurrentHashMap and SynchronousQueue.
UnstartedReferenceGetReferent(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1417 void UnstartedRuntime::UnstartedReferenceGetReferent(
1418     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1419   const ObjPtr<mirror::Reference> ref = down_cast<mirror::Reference*>(
1420       shadow_frame->GetVRegReference(arg_offset));
1421   if (ref == nullptr) {
1422     AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1423     return;
1424   }
1425   const ObjPtr<mirror::Object> referent =
1426       Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1427   result->SetL(referent);
1428 }
1429 
1430 // This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1431 // conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1432 // where we can predict the behavior (somewhat).
1433 // Note: this is required (instead of lazy initialization) as these classes are used in the static
1434 //       initialization of other classes, so will *use* the value.
UnstartedRuntimeAvailableProcessors(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset ATTRIBUTE_UNUSED)1435 void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1436     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1437   if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
1438     // SynchronousQueue really only separates between single- and multiprocessor case. Return
1439     // 8 as a conservative upper approximation.
1440     result->SetI(8);
1441   } else if (CheckCallers(shadow_frame,
1442                           { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
1443     // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1444     // a good upper bound.
1445     // TODO: Consider resetting in the zygote?
1446     result->SetI(8);
1447   } else {
1448     // Not supported.
1449     AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1450   }
1451 }
1452 
1453 // This allows accessing ConcurrentHashMap/SynchronousQueue.
1454 
UnstartedUnsafeCompareAndSwapLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1455 void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1456     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1457   // Argument 0 is the Unsafe instance, skip.
1458   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1459   if (obj == nullptr) {
1460     AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1461     return;
1462   }
1463   int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1464   int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1465   int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
1466   bool success;
1467   // Check whether we're in a transaction, call accordingly.
1468   if (Runtime::Current()->IsActiveTransaction()) {
1469     if (!CheckWriteConstraint(self, obj)) {
1470       DCHECK(self->IsExceptionPending());
1471       return;
1472     }
1473     success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1474                                                                 expectedValue,
1475                                                                 newValue);
1476   } else {
1477     success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1478                                                                  expectedValue,
1479                                                                  newValue);
1480   }
1481   result->SetZ(success ? 1 : 0);
1482 }
1483 
UnstartedUnsafeCompareAndSwapObject(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1484 void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1485     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1486   // Argument 0 is the Unsafe instance, skip.
1487   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1488   if (obj == nullptr) {
1489     AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1490     return;
1491   }
1492   int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1493   mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1494   mirror::Object* new_value = shadow_frame->GetVRegReference(arg_offset + 5);
1495 
1496   // Must use non transactional mode.
1497   if (kUseReadBarrier) {
1498     // Need to make sure the reference stored in the field is a to-space one before attempting the
1499     // CAS or the CAS could fail incorrectly.
1500     mirror::HeapReference<mirror::Object>* field_addr =
1501         reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1502             reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
1503     ReadBarrier::Barrier<
1504         mirror::Object,
1505         /* kIsVolatile= */ false,
1506         kWithReadBarrier,
1507         /* kAlwaysUpdateField= */ true>(
1508         obj,
1509         MemberOffset(offset),
1510         field_addr);
1511   }
1512   bool success;
1513   // Check whether we're in a transaction, call accordingly.
1514   if (Runtime::Current()->IsActiveTransaction()) {
1515     if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, new_value)) {
1516       DCHECK(self->IsExceptionPending());
1517       return;
1518     }
1519     success = obj->CasFieldObject<true>(MemberOffset(offset),
1520                                         expected_value,
1521                                         new_value,
1522                                         CASMode::kStrong,
1523                                         std::memory_order_seq_cst);
1524   } else {
1525     success = obj->CasFieldObject<false>(MemberOffset(offset),
1526                                          expected_value,
1527                                          new_value,
1528                                          CASMode::kStrong,
1529                                          std::memory_order_seq_cst);
1530   }
1531   result->SetZ(success ? 1 : 0);
1532 }
1533 
UnstartedUnsafeGetObjectVolatile(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1534 void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1535     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1536     REQUIRES_SHARED(Locks::mutator_lock_) {
1537   // Argument 0 is the Unsafe instance, skip.
1538   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1539   if (obj == nullptr) {
1540     AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1541     return;
1542   }
1543   int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1544   ObjPtr<mirror::Object> value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1545   result->SetL(value);
1546 }
1547 
UnstartedUnsafePutObjectVolatile(Thread * self,ShadowFrame * shadow_frame,JValue * result ATTRIBUTE_UNUSED,size_t arg_offset)1548 void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1549     Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
1550     REQUIRES_SHARED(Locks::mutator_lock_) {
1551   // Argument 0 is the Unsafe instance, skip.
1552   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1553   if (obj == nullptr) {
1554     AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1555     return;
1556   }
1557   int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1558   mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1559   if (Runtime::Current()->IsActiveTransaction()) {
1560     if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, value)) {
1561       DCHECK(self->IsExceptionPending());
1562       return;
1563     }
1564     obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1565   } else {
1566     obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1567   }
1568 }
1569 
UnstartedUnsafePutOrderedObject(Thread * self,ShadowFrame * shadow_frame,JValue * result ATTRIBUTE_UNUSED,size_t arg_offset)1570 void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1571     Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
1572     REQUIRES_SHARED(Locks::mutator_lock_) {
1573   // Argument 0 is the Unsafe instance, skip.
1574   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1575   if (obj == nullptr) {
1576     AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1577     return;
1578   }
1579   int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1580   mirror::Object* new_value = shadow_frame->GetVRegReference(arg_offset + 4);
1581   std::atomic_thread_fence(std::memory_order_release);
1582   if (Runtime::Current()->IsActiveTransaction()) {
1583     if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, new_value)) {
1584       DCHECK(self->IsExceptionPending());
1585       return;
1586     }
1587     obj->SetFieldObject<true>(MemberOffset(offset), new_value);
1588   } else {
1589     obj->SetFieldObject<false>(MemberOffset(offset), new_value);
1590   }
1591 }
1592 
1593 // A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1594 // of correctly handling the corner cases.
UnstartedIntegerParseInt(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1595 void UnstartedRuntime::UnstartedIntegerParseInt(
1596     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1597     REQUIRES_SHARED(Locks::mutator_lock_) {
1598   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1599   if (obj == nullptr) {
1600     AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1601     return;
1602   }
1603 
1604   std::string string_value = obj->AsString()->ToModifiedUtf8();
1605   if (string_value.empty()) {
1606     AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1607     return;
1608   }
1609 
1610   const char* c_str = string_value.c_str();
1611   char *end;
1612   // Can we set errno to 0? Is this always a variable, and not a macro?
1613   // Worst case, we'll incorrectly fail a transaction. Seems OK.
1614   int64_t l = strtol(c_str, &end, 10);
1615 
1616   if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1617       (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1618     AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1619     return;
1620   }
1621   if (l == 0) {
1622     // Check whether the string wasn't exactly zero.
1623     if (string_value != "0") {
1624       AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1625       return;
1626     }
1627   } else if (*end != '\0') {
1628     AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1629     return;
1630   }
1631 
1632   result->SetI(static_cast<int32_t>(l));
1633 }
1634 
1635 // A cutout for Long.parseLong.
1636 //
1637 // Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1638 //       well.
UnstartedLongParseLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1639 void UnstartedRuntime::UnstartedLongParseLong(
1640     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1641     REQUIRES_SHARED(Locks::mutator_lock_) {
1642   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1643   if (obj == nullptr) {
1644     AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1645     return;
1646   }
1647 
1648   std::string string_value = obj->AsString()->ToModifiedUtf8();
1649   if (string_value.empty()) {
1650     AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1651     return;
1652   }
1653 
1654   const char* c_str = string_value.c_str();
1655   char *end;
1656   // Can we set errno to 0? Is this always a variable, and not a macro?
1657   // Worst case, we'll incorrectly fail a transaction. Seems OK.
1658   int64_t l = strtol(c_str, &end, 10);
1659 
1660   // Note: comparing against int32_t min/max is intentional here.
1661   if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1662       (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1663     AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1664     return;
1665   }
1666   if (l == 0) {
1667     // Check whether the string wasn't exactly zero.
1668     if (string_value != "0") {
1669       AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1670       return;
1671     }
1672   } else if (*end != '\0') {
1673     AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1674     return;
1675   }
1676 
1677   result->SetJ(l);
1678 }
1679 
UnstartedMethodInvoke(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1680 void UnstartedRuntime::UnstartedMethodInvoke(
1681     Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1682     REQUIRES_SHARED(Locks::mutator_lock_) {
1683   JNIEnvExt* env = self->GetJniEnv();
1684   ScopedObjectAccessUnchecked soa(self);
1685 
1686   ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
1687   ScopedLocalRef<jobject> java_method(env,
1688       java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
1689 
1690   ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
1691   ScopedLocalRef<jobject> java_receiver(env,
1692       java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1693 
1694   ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
1695   ScopedLocalRef<jobject> java_args(env,
1696       java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1697 
1698   ScopedLocalRef<jobject> result_jobj(env,
1699       InvokeMethod(soa, java_method.get(), java_receiver.get(), java_args.get()));
1700 
1701   result->SetL(self->DecodeJObject(result_jobj.get()));
1702 
1703   // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1704   // InvocationTargetExceptions.
1705   if (self->IsExceptionPending()) {
1706     AbortTransactionOrFail(self, "Failed Method.invoke");
1707   }
1708 }
1709 
UnstartedSystemIdentityHashCode(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1710 void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1711     Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1712     REQUIRES_SHARED(Locks::mutator_lock_) {
1713   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1714   result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1715 }
1716 
1717 // Checks whether the runtime is s64-bit. This is needed for the clinit of
1718 // java.lang.invoke.VarHandle clinit. The clinit determines sets of
1719 // available VarHandle accessors and these differ based on machine
1720 // word size.
UnstartedJNIVMRuntimeIs64Bit(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1721 void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1722     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1723     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1724   PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1725   jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1726   result->SetZ(is64bit);
1727 }
1728 
UnstartedJNIVMRuntimeNewUnpaddedArray(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1729 void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
1730     Thread* self,
1731     ArtMethod* method ATTRIBUTE_UNUSED,
1732     mirror::Object* receiver ATTRIBUTE_UNUSED,
1733     uint32_t* args,
1734     JValue* result) {
1735   int32_t length = args[1];
1736   DCHECK_GE(length, 0);
1737   ObjPtr<mirror::Object> element_class = reinterpret_cast32<mirror::Object*>(args[0])->AsClass();
1738   if (element_class == nullptr) {
1739     AbortTransactionOrFail(self, "VMRuntime.newUnpaddedArray with null element_class.");
1740     return;
1741   }
1742   Runtime* runtime = Runtime::Current();
1743   ObjPtr<mirror::Class> array_class =
1744       runtime->GetClassLinker()->FindArrayClass(self, element_class->AsClass());
1745   DCHECK(array_class != nullptr);
1746   gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1747   result->SetL(mirror::Array::Alloc</*kIsInstrumented=*/ true, /*kFillUsable=*/ true>(
1748       self, array_class, length, array_class->GetComponentSizeShift(), allocator));
1749 }
1750 
UnstartedJNIVMStackGetCallingClassLoader(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1751 void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1752     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1753     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1754   result->SetL(nullptr);
1755 }
1756 
UnstartedJNIVMStackGetStackClass2(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1757 void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1758     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1759     uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1760   NthCallerVisitor visitor(self, 3);
1761   visitor.WalkStack();
1762   if (visitor.caller != nullptr) {
1763     result->SetL(visitor.caller->GetDeclaringClass());
1764   }
1765 }
1766 
UnstartedJNIMathLog(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1767 void UnstartedRuntime::UnstartedJNIMathLog(
1768     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1769     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1770   JValue value;
1771   value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1772   result->SetD(log(value.GetD()));
1773 }
1774 
UnstartedJNIMathExp(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1775 void UnstartedRuntime::UnstartedJNIMathExp(
1776     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1777     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1778   JValue value;
1779   value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1780   result->SetD(exp(value.GetD()));
1781 }
1782 
UnstartedJNIAtomicLongVMSupportsCS8(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1783 void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1784     Thread* self ATTRIBUTE_UNUSED,
1785     ArtMethod* method ATTRIBUTE_UNUSED,
1786     mirror::Object* receiver ATTRIBUTE_UNUSED,
1787     uint32_t* args ATTRIBUTE_UNUSED,
1788     JValue* result) {
1789   result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1790                    ? 0
1791                    : 1);
1792 }
1793 
UnstartedJNIClassGetNameNative(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1794 void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1795     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1796     uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1797   StackHandleScope<1> hs(self);
1798   result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1799 }
1800 
UnstartedJNIDoubleLongBitsToDouble(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1801 void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1802     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1803     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1804   uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1805   result->SetD(bit_cast<double>(long_input));
1806 }
1807 
UnstartedJNIFloatFloatToRawIntBits(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1808 void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1809     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1810     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1811   result->SetI(args[0]);
1812 }
1813 
UnstartedJNIFloatIntBitsToFloat(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1814 void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1815     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1816     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1817   result->SetI(args[0]);
1818 }
1819 
UnstartedJNIObjectInternalClone(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1820 void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1821     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1822     uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1823   StackHandleScope<1> hs(self);
1824   Handle<mirror::Object> h_receiver = hs.NewHandle(receiver);
1825   result->SetL(mirror::Object::Clone(h_receiver, self));
1826 }
1827 
UnstartedJNIObjectNotifyAll(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver,uint32_t * args ATTRIBUTE_UNUSED,JValue * result ATTRIBUTE_UNUSED)1828 void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1829     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1830     uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
1831   receiver->NotifyAll(self);
1832 }
1833 
UnstartedJNIStringCompareTo(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver,uint32_t * args,JValue * result)1834 void UnstartedRuntime::UnstartedJNIStringCompareTo(Thread* self,
1835                                                    ArtMethod* method ATTRIBUTE_UNUSED,
1836                                                    mirror::Object* receiver,
1837                                                    uint32_t* args,
1838                                                    JValue* result) {
1839   ObjPtr<mirror::Object> rhs = reinterpret_cast32<mirror::Object*>(args[0]);
1840   if (rhs == nullptr) {
1841     AbortTransactionOrFail(self, "String.compareTo with null object.");
1842     return;
1843   }
1844   result->SetI(receiver->AsString()->CompareTo(rhs->AsString()));
1845 }
1846 
UnstartedJNIStringIntern(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1847 void UnstartedRuntime::UnstartedJNIStringIntern(
1848     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1849     uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1850   result->SetL(receiver->AsString()->Intern());
1851 }
1852 
UnstartedJNIArrayCreateMultiArray(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1853 void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1854     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1855     uint32_t* args, JValue* result) {
1856   StackHandleScope<2> hs(self);
1857   auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1858   auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1859   result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1860 }
1861 
UnstartedJNIArrayCreateObjectArray(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1862 void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1863     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1864     uint32_t* args, JValue* result) {
1865   int32_t length = static_cast<int32_t>(args[1]);
1866   if (length < 0) {
1867     ThrowNegativeArraySizeException(length);
1868     return;
1869   }
1870   ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
1871   Runtime* runtime = Runtime::Current();
1872   ClassLinker* class_linker = runtime->GetClassLinker();
1873   ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, element_class);
1874   if (UNLIKELY(array_class == nullptr)) {
1875     CHECK(self->IsExceptionPending());
1876     return;
1877   }
1878   DCHECK(array_class->IsObjectArrayClass());
1879   ObjPtr<mirror::Array> new_array = mirror::ObjectArray<mirror::Object>::Alloc(
1880       self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1881   result->SetL(new_array);
1882 }
1883 
UnstartedJNIThrowableNativeFillInStackTrace(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1884 void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1885     Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1886     uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1887   ScopedObjectAccessUnchecked soa(self);
1888   if (Runtime::Current()->IsActiveTransaction()) {
1889     result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<true>(soa)));
1890   } else {
1891     result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<false>(soa)));
1892   }
1893 }
1894 
UnstartedJNIByteOrderIsLittleEndian(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1895 void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
1896     Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1897     mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1898   result->SetZ(JNI_TRUE);
1899 }
1900 
UnstartedJNIUnsafeCompareAndSwapInt(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1901 void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
1902     Thread* self,
1903     ArtMethod* method ATTRIBUTE_UNUSED,
1904     mirror::Object* receiver ATTRIBUTE_UNUSED,
1905     uint32_t* args,
1906     JValue* result) {
1907   ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1908   if (obj == nullptr) {
1909     AbortTransactionOrFail(self, "Unsafe.compareAndSwapInt with null object.");
1910     return;
1911   }
1912   jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1913   jint expectedValue = args[3];
1914   jint newValue = args[4];
1915   bool success;
1916   if (Runtime::Current()->IsActiveTransaction()) {
1917     if (!CheckWriteConstraint(self, obj)) {
1918       DCHECK(self->IsExceptionPending());
1919       return;
1920     }
1921     success = obj->CasField32<true>(MemberOffset(offset),
1922                                     expectedValue,
1923                                     newValue,
1924                                     CASMode::kStrong,
1925                                     std::memory_order_seq_cst);
1926   } else {
1927     success = obj->CasField32<false>(MemberOffset(offset),
1928                                      expectedValue,
1929                                      newValue,
1930                                      CASMode::kStrong,
1931                                      std::memory_order_seq_cst);
1932   }
1933   result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1934 }
1935 
UnstartedJNIUnsafeGetIntVolatile(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1936 void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(Thread* self,
1937                                                         ArtMethod* method ATTRIBUTE_UNUSED,
1938                                                         mirror::Object* receiver ATTRIBUTE_UNUSED,
1939                                                         uint32_t* args,
1940                                                         JValue* result) {
1941   ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1942   if (obj == nullptr) {
1943     AbortTransactionOrFail(self, "Unsafe.compareAndSwapIntVolatile with null object.");
1944     return;
1945   }
1946 
1947   jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1948   result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1949 }
1950 
UnstartedJNIUnsafePutObject(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result ATTRIBUTE_UNUSED)1951 void UnstartedRuntime::UnstartedJNIUnsafePutObject(Thread* self,
1952                                                    ArtMethod* method ATTRIBUTE_UNUSED,
1953                                                    mirror::Object* receiver ATTRIBUTE_UNUSED,
1954                                                    uint32_t* args,
1955                                                    JValue* result ATTRIBUTE_UNUSED) {
1956   ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1957   if (obj == nullptr) {
1958     AbortTransactionOrFail(self, "Unsafe.putObject with null object.");
1959     return;
1960   }
1961   jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1962   ObjPtr<mirror::Object> new_value = reinterpret_cast32<mirror::Object*>(args[3]);
1963   if (Runtime::Current()->IsActiveTransaction()) {
1964     if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, new_value)) {
1965       DCHECK(self->IsExceptionPending());
1966       return;
1967     }
1968     obj->SetFieldObject<true>(MemberOffset(offset), new_value);
1969   } else {
1970     obj->SetFieldObject<false>(MemberOffset(offset), new_value);
1971   }
1972 }
1973 
UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1974 void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
1975     Thread* self,
1976     ArtMethod* method ATTRIBUTE_UNUSED,
1977     mirror::Object* receiver ATTRIBUTE_UNUSED,
1978     uint32_t* args,
1979     JValue* result) {
1980   ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
1981   if (component == nullptr) {
1982     AbortTransactionOrFail(self, "Unsafe.getArrayBaseOffsetForComponentType with null component.");
1983     return;
1984   }
1985   Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
1986   result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1987 }
1988 
UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1989 void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
1990     Thread* self,
1991     ArtMethod* method ATTRIBUTE_UNUSED,
1992     mirror::Object* receiver ATTRIBUTE_UNUSED,
1993     uint32_t* args,
1994     JValue* result) {
1995   ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
1996   if (component == nullptr) {
1997     AbortTransactionOrFail(self, "Unsafe.getArrayIndexScaleForComponentType with null component.");
1998     return;
1999   }
2000   Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
2001   result->SetI(Primitive::ComponentSize(primitive_type));
2002 }
2003 
2004 using InvokeHandler = void(*)(Thread* self,
2005                               ShadowFrame* shadow_frame,
2006                               JValue* result,
2007                               size_t arg_size);
2008 
2009 using JNIHandler = void(*)(Thread* self,
2010                            ArtMethod* method,
2011                            mirror::Object* receiver,
2012                            uint32_t* args,
2013                            JValue* result);
2014 
2015 static bool tables_initialized_ = false;
2016 static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
2017 static std::unordered_map<std::string, JNIHandler> jni_handlers_;
2018 
InitializeInvokeHandlers()2019 void UnstartedRuntime::InitializeInvokeHandlers() {
2020 #define UNSTARTED_DIRECT(ShortName, Sig) \
2021   invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
2022 #include "unstarted_runtime_list.h"
2023   UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
2024 #undef UNSTARTED_RUNTIME_DIRECT_LIST
2025 #undef UNSTARTED_RUNTIME_JNI_LIST
2026 #undef UNSTARTED_DIRECT
2027 }
2028 
InitializeJNIHandlers()2029 void UnstartedRuntime::InitializeJNIHandlers() {
2030 #define UNSTARTED_JNI(ShortName, Sig) \
2031   jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
2032 #include "unstarted_runtime_list.h"
2033   UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
2034 #undef UNSTARTED_RUNTIME_DIRECT_LIST
2035 #undef UNSTARTED_RUNTIME_JNI_LIST
2036 #undef UNSTARTED_JNI
2037 }
2038 
Initialize()2039 void UnstartedRuntime::Initialize() {
2040   CHECK(!tables_initialized_);
2041 
2042   InitializeInvokeHandlers();
2043   InitializeJNIHandlers();
2044 
2045   tables_initialized_ = true;
2046 }
2047 
Invoke(Thread * self,const CodeItemDataAccessor & accessor,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)2048 void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
2049                               ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
2050   // In a runtime that's not started we intercept certain methods to avoid complicated dependency
2051   // problems in core libraries.
2052   CHECK(tables_initialized_);
2053 
2054   std::string name(ArtMethod::PrettyMethod(shadow_frame->GetMethod()));
2055   const auto& iter = invoke_handlers_.find(name);
2056   if (iter != invoke_handlers_.end()) {
2057     // Clear out the result in case it's not zeroed out.
2058     result->SetL(nullptr);
2059 
2060     // Push the shadow frame. This is so the failing method can be seen in abort dumps.
2061     self->PushShadowFrame(shadow_frame);
2062 
2063     (*iter->second)(self, shadow_frame, result, arg_offset);
2064 
2065     self->PopShadowFrame();
2066   } else {
2067     // Not special, continue with regular interpreter execution.
2068     ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
2069   }
2070 }
2071 
2072 // Hand select a number of methods to be run in a not yet started runtime without using JNI.
Jni(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2073 void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
2074                            uint32_t* args, JValue* result) {
2075   std::string name(ArtMethod::PrettyMethod(method));
2076   const auto& iter = jni_handlers_.find(name);
2077   if (iter != jni_handlers_.end()) {
2078     // Clear out the result in case it's not zeroed out.
2079     result->SetL(nullptr);
2080     (*iter->second)(self, method, receiver, args, result);
2081   } else if (Runtime::Current()->IsActiveTransaction()) {
2082     AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
2083                       name.c_str());
2084   } else {
2085     LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
2086         "non-transactional runtime";
2087   }
2088 }
2089 
2090 }  // namespace interpreter
2091 }  // namespace art
2092