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