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