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