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