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