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