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