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