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