blob: b8fb5b8a845e342771df430e62fca6db79a7e99a [file] [log] [blame]
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001/*
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
Andreas Gampe8ce9c302016-04-15 21:24:28 -070019#include <ctype.h>
Andreas Gampe13fc1be2016-04-05 20:14:30 -070020#include <errno.h>
21#include <stdlib.h>
22
Andreas Gampe2969bcd2015-03-09 12:57:41 -070023#include <cmath>
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -080024#include <initializer_list>
Andreas Gampe13fc1be2016-04-05 20:14:30 -070025#include <limits>
Andreas Gampe8ce9c302016-04-15 21:24:28 -070026#include <locale>
Andreas Gampe2969bcd2015-03-09 12:57:41 -070027
Andreas Gampe57943812017-12-06 21:39:13 -080028#include <android-base/logging.h>
29#include <android-base/stringprintf.h>
Andreas Gampeaacc25d2015-04-01 14:49:06 -070030
Mathieu Chartiere401d142015-04-22 13:56:20 -070031#include "art_method-inl.h"
Andreas Gampebc4d2182016-02-22 10:03:12 -080032#include "base/casts.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070033#include "base/enums.h"
Vladimir Marko83881482021-01-07 10:59:54 +000034#include "base/hash_map.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070035#include "base/macros.h"
David Sehrc431b9d2018-03-02 12:01:51 -080036#include "base/quasi_atomic.h"
David Sehr79e26072018-04-06 17:58:50 -070037#include "base/zip_archive.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070038#include "class_linker.h"
39#include "common_throws.h"
David Sehrb2ec9f52018-02-21 13:20:31 -080040#include "dex/descriptors_names.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070041#include "entrypoints/entrypoint_utils-inl.h"
Andreas Gampebc4d2182016-02-22 10:03:12 -080042#include "gc/reference_processor.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070043#include "handle_scope-inl.h"
David Brazdil5a61bb72018-01-19 16:59:46 +000044#include "hidden_api.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070045#include "interpreter/interpreter_common.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070046#include "jvalue-inl.h"
Andreas Gampe8e0f0432018-10-24 13:38:03 -070047#include "mirror/array-alloc-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070048#include "mirror/array-inl.h"
Andreas Gampe70f5fd02018-10-24 19:58:37 -070049#include "mirror/class-alloc-inl.h"
Vladimir Marko0eefb9b2019-03-27 15:04:31 +000050#include "mirror/executable-inl.h"
Vladimir Marko0a6063a2020-05-14 16:39:14 +010051#include "mirror/field.h"
Narayan Kamath14832ef2016-08-05 11:44:32 +010052#include "mirror/method.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070053#include "mirror/object-inl.h"
Andreas Gampe52ecb652018-10-24 15:18:21 -070054#include "mirror/object_array-alloc-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070055#include "mirror/object_array-inl.h"
Andreas Gampefd63bbf2018-10-29 12:55:35 -070056#include "mirror/string-alloc-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070057#include "mirror/string-inl.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070058#include "nativehelper/scoped_local_ref.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070059#include "nth_caller_visitor.h"
Andreas Gampe715fdc22016-04-18 17:07:30 -070060#include "reflection.h"
Andreas Gampe513061a2017-06-01 09:17:34 -070061#include "thread-inl.h"
Sebastien Hertz2fd7e692015-04-02 11:11:19 +020062#include "transaction.h"
Vladimir Marko83881482021-01-07 10:59:54 +000063#include "unstarted_runtime_list.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070064#include "well_known_classes.h"
65
66namespace art {
67namespace interpreter {
68
Andreas Gampe46ee31b2016-12-14 10:11:49 -080069using android::base::StringAppendV;
70using android::base::StringPrintf;
71
Andreas Gampe068b0c02015-03-11 12:44:47 -070072static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
Sebastien Hertz45b15972015-04-03 16:07:05 +020073 __attribute__((__format__(__printf__, 2, 3)))
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070074 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertz45b15972015-04-03 16:07:05 +020075
76static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
Andreas Gampe068b0c02015-03-11 12:44:47 -070077 va_list args;
Andreas Gampe068b0c02015-03-11 12:44:47 -070078 if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +020079 va_start(args, fmt);
80 AbortTransactionV(self, fmt, args);
Andreas Gampe068b0c02015-03-11 12:44:47 -070081 va_end(args);
82 } else {
Sebastien Hertz45b15972015-04-03 16:07:05 +020083 va_start(args, fmt);
84 std::string msg;
85 StringAppendV(&msg, fmt, args);
86 va_end(args);
87 LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
Andreas Gampe068b0c02015-03-11 12:44:47 -070088 UNREACHABLE();
89 }
90}
91
Andreas Gampe8ce9c302016-04-15 21:24:28 -070092// Restricted support for character upper case / lower case. Only support ASCII, where
93// it's easy. Abort the transaction otherwise.
94static void CharacterLowerUpper(Thread* self,
95 ShadowFrame* shadow_frame,
96 JValue* result,
97 size_t arg_offset,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070098 bool to_lower_case) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8ce9c302016-04-15 21:24:28 -070099 uint32_t int_value = static_cast<uint32_t>(shadow_frame->GetVReg(arg_offset));
100
101 // Only ASCII (7-bit).
102 if (!isascii(int_value)) {
103 AbortTransactionOrFail(self,
104 "Only support ASCII characters for toLowerCase/toUpperCase: %u",
105 int_value);
106 return;
107 }
108
109 std::locale c_locale("C");
110 char char_value = static_cast<char>(int_value);
111
112 if (to_lower_case) {
113 result->SetI(std::tolower(char_value, c_locale));
114 } else {
115 result->SetI(std::toupper(char_value, c_locale));
116 }
117}
118
119void UnstartedRuntime::UnstartedCharacterToLowerCase(
120 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
121 CharacterLowerUpper(self, shadow_frame, result, arg_offset, true);
122}
123
124void UnstartedRuntime::UnstartedCharacterToUpperCase(
125 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
126 CharacterLowerUpper(self, shadow_frame, result, arg_offset, false);
127}
128
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700129// Helper function to deal with class loading in an unstarted runtime.
Vladimir Marko0685b982021-03-25 11:59:22 +0000130static void UnstartedRuntimeFindClass(Thread* self,
131 Handle<mirror::String> className,
132 Handle<mirror::ClassLoader> class_loader,
133 JValue* result,
134 bool initialize_class)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700135 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampefa4333d2017-02-14 11:10:34 -0800136 CHECK(className != nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700137 std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
138 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
139
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100140 ObjPtr<mirror::Class> found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700141 if (found != nullptr && initialize_class) {
142 StackHandleScope<1> hs(self);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100143 HandleWrapperObjPtr<mirror::Class> h_class = hs.NewHandleWrapper(&found);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700144 if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
145 CHECK(self->IsExceptionPending());
146 return;
147 }
148 }
149 result->SetL(found);
150}
151
152// Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
153// rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
154// ClassNotFoundException), so need to do the same. The only exception is if the exception is
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200155// actually the transaction abort exception. This must not be wrapped, as it signals an
156// initialization abort.
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700157static void CheckExceptionGenerateClassNotFound(Thread* self)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700158 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700159 if (self->IsExceptionPending()) {
Vladimir Marko0685b982021-03-25 11:59:22 +0000160 Runtime* runtime = Runtime::Current();
161 DCHECK_EQ(runtime->IsTransactionAborted(),
162 self->GetException()->GetClass()->DescriptorEquals(
163 Transaction::kAbortExceptionDescriptor))
164 << self->GetException()->GetClass()->PrettyDescriptor();
165 if (runtime->IsActiveTransaction()) {
166 // The boot class path at run time may contain additional dex files with
167 // the required class definition(s). We cannot throw a normal exception at
168 // compile time because a class initializer could catch it and successfully
169 // initialize a class differently than when executing at run time.
170 // If we're not aborting the transaction yet, abort now. b/183691501
171 if (!runtime->IsTransactionAborted()) {
172 AbortTransactionF(self, "ClassNotFoundException");
173 }
174 } else {
175 // If not in a transaction, it cannot be the transaction abort exception. Wrap it.
176 DCHECK(!runtime->IsTransactionAborted());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700177 self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
178 "ClassNotFoundException");
179 }
180 }
181}
182
Vladimir Marko4617d582019-03-28 13:48:31 +0000183static ObjPtr<mirror::String> GetClassName(Thread* self,
184 ShadowFrame* shadow_frame,
185 size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700186 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700187 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
188 if (param == nullptr) {
189 AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
190 return nullptr;
191 }
192 return param->AsString();
193}
194
David Brazdil4bcd6572019-02-02 20:08:44 +0000195static std::function<hiddenapi::AccessContext()> GetHiddenapiAccessContextFunction(
196 ShadowFrame* frame) {
197 return [=]() REQUIRES_SHARED(Locks::mutator_lock_) {
198 return hiddenapi::AccessContext(frame->GetMethod()->GetDeclaringClass());
199 };
200}
201
David Brazdila02cb112018-01-31 11:36:39 +0000202template<typename T>
David Brazdilf50ac102018-10-17 18:00:06 +0100203static ALWAYS_INLINE bool ShouldDenyAccessToMember(T* member, ShadowFrame* frame)
David Brazdila02cb112018-01-31 11:36:39 +0000204 REQUIRES_SHARED(Locks::mutator_lock_) {
Narayan Kamathf5f1f802018-04-03 15:23:46 +0100205 // All uses in this file are from reflection
David Brazdile7681822018-12-14 16:25:33 +0000206 constexpr hiddenapi::AccessMethod kAccessMethod = hiddenapi::AccessMethod::kReflection;
David Brazdil4bcd6572019-02-02 20:08:44 +0000207 return hiddenapi::ShouldDenyAccessToMember(member,
208 GetHiddenapiAccessContextFunction(frame),
209 kAccessMethod);
David Brazdila02cb112018-01-31 11:36:39 +0000210}
211
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800212void UnstartedRuntime::UnstartedClassForNameCommon(Thread* self,
213 ShadowFrame* shadow_frame,
214 JValue* result,
215 size_t arg_offset,
Vladimir Marko0685b982021-03-25 11:59:22 +0000216 bool long_form) {
Vladimir Marko4617d582019-03-28 13:48:31 +0000217 ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700218 if (class_name == nullptr) {
219 return;
220 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800221 bool initialize_class;
Vladimir Marko4617d582019-03-28 13:48:31 +0000222 ObjPtr<mirror::ClassLoader> class_loader;
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800223 if (long_form) {
224 initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
Vladimir Marko4617d582019-03-28 13:48:31 +0000225 class_loader =
226 ObjPtr<mirror::ClassLoader>::DownCast(shadow_frame->GetVRegReference(arg_offset + 2));
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800227 } else {
228 initialize_class = true;
229 // TODO: This is really only correct for the boot classpath, and for robustness we should
230 // check the caller.
231 class_loader = nullptr;
232 }
233
234 ScopedObjectAccessUnchecked soa(self);
235 if (class_loader != nullptr && !ClassLinker::IsBootClassLoader(soa, class_loader)) {
236 AbortTransactionOrFail(self,
237 "Only the boot classloader is supported: %s",
238 mirror::Object::PrettyTypeOf(class_loader).c_str());
239 return;
240 }
241
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700242 StackHandleScope<1> hs(self);
243 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800244 UnstartedRuntimeFindClass(self,
245 h_class_name,
246 ScopedNullHandle<mirror::ClassLoader>(),
247 result,
Vladimir Marko0685b982021-03-25 11:59:22 +0000248 initialize_class);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700249 CheckExceptionGenerateClassNotFound(self);
250}
251
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800252void UnstartedRuntime::UnstartedClassForName(
253 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Vladimir Marko0685b982021-03-25 11:59:22 +0000254 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, /*long_form=*/ false);
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800255}
256
Andreas Gampe799681b2015-05-15 19:24:12 -0700257void UnstartedRuntime::UnstartedClassForNameLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700258 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Vladimir Marko0685b982021-03-25 11:59:22 +0000259 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, /*long_form=*/ true);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700260}
261
Vladimir Marko7287c4d2018-02-15 10:41:07 +0000262void UnstartedRuntime::UnstartedClassGetPrimitiveClass(
263 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
264 ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
265 ObjPtr<mirror::Class> klass = mirror::Class::GetPrimitiveClass(class_name);
266 if (UNLIKELY(klass == nullptr)) {
267 DCHECK(self->IsExceptionPending());
268 AbortTransactionOrFail(self,
269 "Class.getPrimitiveClass() failed: %s",
270 self->GetException()->GetDetailMessage()->ToModifiedUtf8().c_str());
271 return;
272 }
273 result->SetL(klass);
274}
275
Andreas Gampe799681b2015-05-15 19:24:12 -0700276void UnstartedRuntime::UnstartedClassClassForName(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700277 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Vladimir Marko0685b982021-03-25 11:59:22 +0000278 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, /*long_form=*/ true);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700279}
280
Andreas Gampe799681b2015-05-15 19:24:12 -0700281void UnstartedRuntime::UnstartedClassNewInstance(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700282 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
283 StackHandleScope<2> hs(self); // Class, constructor, object.
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700284 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
285 if (param == nullptr) {
286 AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
287 return;
288 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100289 Handle<mirror::Class> h_klass(hs.NewHandle(param->AsClass()));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700290
291 // Check that it's not null.
Andreas Gampefa4333d2017-02-14 11:10:34 -0800292 if (h_klass == nullptr) {
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700293 AbortTransactionOrFail(self, "Class reference is null for newInstance");
294 return;
295 }
296
297 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
298 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100299 if (h_klass->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200300 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700301 h_klass->PrettyClass().c_str());
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700302 return;
303 }
304 }
305
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700306 // There are two situations in which we'll abort this run.
307 // 1) If the class isn't yet initialized and initialization fails.
308 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
309 // Note that 2) could likely be handled here, but for safety abort the transaction.
310 bool ok = false;
Mathieu Chartiere401d142015-04-22 13:56:20 -0700311 auto* cl = Runtime::Current()->GetClassLinker();
312 if (cl->EnsureInitialized(self, h_klass, true, true)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000313 ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
David Brazdilf50ac102018-10-17 18:00:06 +0100314 if (cons != nullptr && ShouldDenyAccessToMember(cons, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000315 cons = nullptr;
316 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700317 if (cons != nullptr) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100318 Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800319 CHECK(h_obj != nullptr); // We don't expect OOM at compile-time.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700320 EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700321 if (!self->IsExceptionPending()) {
322 result->SetL(h_obj.Get());
323 ok = true;
324 }
325 } else {
326 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
327 "Could not find default constructor for '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700328 h_klass->PrettyClass().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700329 }
330 }
331 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700332 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
David Sehr709b0702016-10-13 09:12:37 -0700333 h_klass->PrettyClass().c_str(),
334 mirror::Object::PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700335 }
336}
337
Andreas Gampe799681b2015-05-15 19:24:12 -0700338void UnstartedRuntime::UnstartedClassGetDeclaredField(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700339 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700340 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
341 // going the reflective Dex way.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100342 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
343 ObjPtr<mirror::String> name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700344 ArtField* found = nullptr;
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700345 for (ArtField& field : klass->GetIFields()) {
346 if (name2->Equals(field.GetName())) {
347 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700348 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700349 }
350 }
351 if (found == nullptr) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700352 for (ArtField& field : klass->GetSFields()) {
353 if (name2->Equals(field.GetName())) {
354 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700355 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700356 }
357 }
358 }
David Brazdilf50ac102018-10-17 18:00:06 +0100359 if (found != nullptr && ShouldDenyAccessToMember(found, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000360 found = nullptr;
361 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700362 if (found == nullptr) {
363 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
364 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
David Sehr709b0702016-10-13 09:12:37 -0700365 klass->PrettyDescriptor().c_str());
Andreas Gampe068b0c02015-03-11 12:44:47 -0700366 return;
367 }
Vladimir Marko0a6063a2020-05-14 16:39:14 +0100368 ObjPtr<mirror::Field> field = mirror::Field::CreateFromArtField(self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700369 result->SetL(field);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700370}
371
Andreas Gampebc4d2182016-02-22 10:03:12 -0800372// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
373void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
374 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
375 // Special managed code cut-out to allow method lookup in a un-started runtime.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100376 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
Andreas Gampebc4d2182016-02-22 10:03:12 -0800377 if (klass == nullptr) {
378 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
379 return;
380 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100381 ObjPtr<mirror::String> name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
382 ObjPtr<mirror::ObjectArray<mirror::Class>> args =
Andreas Gampebc4d2182016-02-22 10:03:12 -0800383 shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
Vladimir Markob6f4c792020-05-04 15:37:29 +0100384 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
David Brazdil4bcd6572019-02-02 20:08:44 +0000385 auto fn_hiddenapi_access_context = GetHiddenapiAccessContextFunction(shadow_frame);
Vladimir Markob6f4c792020-05-04 15:37:29 +0100386 ObjPtr<mirror::Method> method = (pointer_size == PointerSize::k64)
387 ? mirror::Class::GetDeclaredMethodInternal<PointerSize::k64>(
388 self, klass, name, args, fn_hiddenapi_access_context)
389 : mirror::Class::GetDeclaredMethodInternal<PointerSize::k32>(
390 self, klass, name, args, fn_hiddenapi_access_context);
David Brazdilf50ac102018-10-17 18:00:06 +0100391 if (method != nullptr && ShouldDenyAccessToMember(method->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000392 method = nullptr;
393 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700394 result->SetL(method);
Andreas Gampebc4d2182016-02-22 10:03:12 -0800395}
396
Andreas Gampe6039e562016-04-05 18:18:43 -0700397// Special managed code cut-out to allow constructor lookup in a un-started runtime.
398void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
399 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100400 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
Andreas Gampe6039e562016-04-05 18:18:43 -0700401 if (klass == nullptr) {
402 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
403 return;
404 }
Vladimir Marko4617d582019-03-28 13:48:31 +0000405 ObjPtr<mirror::ObjectArray<mirror::Class>> args =
Andreas Gampe6039e562016-04-05 18:18:43 -0700406 shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
Vladimir Markob6f4c792020-05-04 15:37:29 +0100407 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
408 ObjPtr<mirror::Constructor> constructor = (pointer_size == PointerSize::k64)
409 ? mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64>(self, klass, args)
410 : mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32>(self, klass, args);
David Brazdil5a61bb72018-01-19 16:59:46 +0000411 if (constructor != nullptr &&
David Brazdilf50ac102018-10-17 18:00:06 +0100412 ShouldDenyAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000413 constructor = nullptr;
414 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700415 result->SetL(constructor);
Andreas Gampe6039e562016-04-05 18:18:43 -0700416}
417
Andreas Gampeae78c262017-02-01 20:40:44 -0800418void UnstartedRuntime::UnstartedClassGetDeclaringClass(
419 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
420 StackHandleScope<1> hs(self);
421 Handle<mirror::Class> klass(hs.NewHandle(
422 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
423 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
424 result->SetL(nullptr);
425 return;
426 }
427 // Return null for anonymous classes.
428 JValue is_anon_result;
429 UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
430 if (is_anon_result.GetZ() != 0) {
431 result->SetL(nullptr);
432 return;
433 }
434 result->SetL(annotations::GetDeclaringClass(klass));
435}
436
Andreas Gampe633750c2016-02-19 10:49:50 -0800437void UnstartedRuntime::UnstartedClassGetEnclosingClass(
438 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
439 StackHandleScope<1> hs(self);
440 Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
441 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
442 result->SetL(nullptr);
443 }
David Sehr9323e6e2016-09-13 08:58:35 -0700444 result->SetL(annotations::GetEnclosingClass(klass));
Andreas Gampe633750c2016-02-19 10:49:50 -0800445}
446
Andreas Gampe715fdc22016-04-18 17:07:30 -0700447void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
448 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
449 StackHandleScope<1> hs(self);
450 Handle<mirror::Class> klass(hs.NewHandle(
451 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
452 const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
453 result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
454}
455
Andreas Gampe9486a162017-02-16 15:17:47 -0800456void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
457 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
458 StackHandleScope<1> hs(self);
459 Handle<mirror::Class> klass(hs.NewHandle(
460 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
461
462 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
463 result->SetL(nullptr);
464 return;
465 }
466
467 result->SetL(annotations::GetSignatureAnnotationForClass(klass));
468}
469
Andreas Gampeae78c262017-02-01 20:40:44 -0800470void UnstartedRuntime::UnstartedClassIsAnonymousClass(
471 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
472 StackHandleScope<1> hs(self);
473 Handle<mirror::Class> klass(hs.NewHandle(
474 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
475 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
476 result->SetZ(false);
477 return;
478 }
Vladimir Marko2d3065e2018-05-22 13:56:09 +0100479 ObjPtr<mirror::String> class_name = nullptr;
Andreas Gampeae78c262017-02-01 20:40:44 -0800480 if (!annotations::GetInnerClass(klass, &class_name)) {
481 result->SetZ(false);
482 return;
483 }
484 result->SetZ(class_name == nullptr);
485}
486
Victor Hsiehecaf7d12021-06-14 11:09:21 -0700487static MemMap FindAndExtractEntry(const std::string& bcp_jar_file,
Victor Hsieha09d8b72021-05-24 14:21:55 -0700488 int jar_fd,
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100489 const char* entry_name,
490 size_t* size,
491 std::string* error_msg) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700492 CHECK(size != nullptr);
493
Victor Hsieha09d8b72021-05-24 14:21:55 -0700494 std::unique_ptr<ZipArchive> zip_archive;
495 if (jar_fd >= 0) {
Victor Hsiehecaf7d12021-06-14 11:09:21 -0700496 zip_archive.reset(ZipArchive::OpenFromOwnedFd(jar_fd, bcp_jar_file.c_str(), error_msg));
Victor Hsieha09d8b72021-05-24 14:21:55 -0700497 } else {
Victor Hsiehecaf7d12021-06-14 11:09:21 -0700498 zip_archive.reset(ZipArchive::Open(bcp_jar_file.c_str(), error_msg));
Victor Hsieha09d8b72021-05-24 14:21:55 -0700499 }
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700500 if (zip_archive == nullptr) {
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100501 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700502 }
503 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
504 if (zip_entry == nullptr) {
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100505 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700506 }
Victor Hsiehecaf7d12021-06-14 11:09:21 -0700507 MemMap tmp_map = zip_entry->ExtractToMemMap(bcp_jar_file.c_str(), entry_name, error_msg);
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100508 if (!tmp_map.IsValid()) {
509 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700510 }
511
512 // OK, from here everything seems fine.
513 *size = zip_entry->GetUncompressedLength();
514 return tmp_map;
515}
516
517static void GetResourceAsStream(Thread* self,
518 ShadowFrame* shadow_frame,
519 JValue* result,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700520 size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700521 mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
522 if (resource_obj == nullptr) {
523 AbortTransactionOrFail(self, "null name for getResourceAsStream");
524 return;
525 }
526 CHECK(resource_obj->IsString());
Vladimir Marko4617d582019-03-28 13:48:31 +0000527 ObjPtr<mirror::String> resource_name = resource_obj->AsString();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700528
529 std::string resource_name_str = resource_name->ToModifiedUtf8();
530 if (resource_name_str.empty() || resource_name_str == "/") {
531 AbortTransactionOrFail(self,
532 "Unsupported name %s for getResourceAsStream",
533 resource_name_str.c_str());
534 return;
535 }
536 const char* resource_cstr = resource_name_str.c_str();
537 if (resource_cstr[0] == '/') {
538 resource_cstr++;
539 }
540
541 Runtime* runtime = Runtime::Current();
542
Vladimir Marko91f10322018-12-07 18:04:10 +0000543 const std::vector<std::string>& boot_class_path = Runtime::Current()->GetBootClassPath();
544 if (boot_class_path.empty()) {
545 AbortTransactionOrFail(self, "Boot classpath not set");
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700546 return;
547 }
548
Victor Hsieha09d8b72021-05-24 14:21:55 -0700549 const std::vector<int>& boot_class_path_fds = Runtime::Current()->GetBootClassPathFds();
550 DCHECK(boot_class_path_fds.empty() || boot_class_path_fds.size() == boot_class_path.size());
551
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100552 MemMap mem_map;
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700553 size_t map_size;
554 std::string last_error_msg; // Only store the last message (we could concatenate).
555
Victor Hsieha09d8b72021-05-24 14:21:55 -0700556 bool has_bcp_fds = !boot_class_path_fds.empty();
557 for (size_t i = 0; i < boot_class_path.size(); ++i) {
558 const std::string& jar_file = boot_class_path[i];
559 const int jar_fd = has_bcp_fds ? boot_class_path_fds[i] : -1;
560 mem_map = FindAndExtractEntry(jar_file, jar_fd, resource_cstr, &map_size, &last_error_msg);
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100561 if (mem_map.IsValid()) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700562 break;
563 }
564 }
565
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100566 if (!mem_map.IsValid()) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700567 // Didn't find it. There's a good chance this will be the same at runtime, but still
568 // conservatively abort the transaction here.
569 AbortTransactionOrFail(self,
570 "Could not find resource %s. Last error was %s.",
571 resource_name_str.c_str(),
572 last_error_msg.c_str());
573 return;
574 }
575
576 StackHandleScope<3> hs(self);
577
578 // Create byte array for content.
579 Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800580 if (h_array == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700581 AbortTransactionOrFail(self, "Could not find/create byte array class");
582 return;
583 }
584 // Copy in content.
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100585 memcpy(h_array->GetData(), mem_map.Begin(), map_size);
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700586 // Be proactive releasing memory.
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100587 mem_map.Reset();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700588
589 // Create a ByteArrayInputStream.
590 Handle<mirror::Class> h_class(hs.NewHandle(
591 runtime->GetClassLinker()->FindClass(self,
592 "Ljava/io/ByteArrayInputStream;",
593 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800594 if (h_class == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700595 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
596 return;
597 }
598 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
599 AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
600 return;
601 }
602
603 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800604 if (h_obj == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700605 AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
606 return;
607 }
608
609 auto* cl = Runtime::Current()->GetClassLinker();
Vladimir Markoba118822017-06-12 15:41:56 +0100610 ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700611 if (constructor == nullptr) {
612 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
613 return;
614 }
615
616 uint32_t args[1];
Vladimir Marko78baed52018-10-11 10:44:58 +0100617 args[0] = reinterpret_cast32<uint32_t>(h_array.Get());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700618 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
619
620 if (self->IsExceptionPending()) {
621 AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
622 return;
623 }
624
625 result->SetL(h_obj.Get());
626}
627
628void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
629 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
630 {
631 mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
632 CHECK(this_obj != nullptr);
633 CHECK(this_obj->IsClassLoader());
634
635 StackHandleScope<1> hs(self);
636 Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
637
638 if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
639 this_classloader_class.Get()) {
640 AbortTransactionOrFail(self,
David Sehr709b0702016-10-13 09:12:37 -0700641 "Unsupported classloader type %s for getResourceAsStream",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700642 mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700643 return;
644 }
645 }
646
647 GetResourceAsStream(self, shadow_frame, result, arg_offset);
648}
649
Andreas Gampe85bef7e2017-02-16 18:13:26 -0800650void UnstartedRuntime::UnstartedConstructorNewInstance0(
651 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
652 // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
653 StackHandleScope<4> hs(self);
654 Handle<mirror::Constructor> m = hs.NewHandle(
655 reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
656 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
657 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
658 shadow_frame->GetVRegReference(arg_offset + 1)));
659 Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
660 if (UNLIKELY(c->IsAbstract())) {
661 AbortTransactionOrFail(self, "Cannot handle abstract classes");
662 return;
663 }
664 // Verify that we can access the class.
665 if (!m->IsAccessible() && !c->IsPublic()) {
666 // Go 2 frames back, this method is always called from newInstance0, which is called from
667 // Constructor.newInstance(Object... args).
668 ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
669 // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
670 // access checks anyways. TODO: Investigate if this the correct behavior.
671 if (caller != nullptr && !caller->CanAccess(c.Get())) {
672 AbortTransactionOrFail(self, "Cannot access class");
673 return;
674 }
675 }
676 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
677 DCHECK(self->IsExceptionPending());
678 return;
679 }
680 if (c->IsClassClass()) {
681 AbortTransactionOrFail(self, "new Class() is not supported");
682 return;
683 }
684
685 // String constructor is replaced by a StringFactory method in InvokeMethod.
686 if (c->IsStringClass()) {
687 // We don't support strings.
688 AbortTransactionOrFail(self, "String construction is not supported");
689 return;
690 }
691
692 Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
693 if (receiver == nullptr) {
694 AbortTransactionOrFail(self, "Could not allocate");
695 return;
696 }
697
698 // It's easier to use reflection to make the call, than create the uint32_t array.
699 {
700 ScopedObjectAccessUnchecked soa(self);
701 ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
702 soa.AddLocalReference<jobject>(m.Get()));
703 ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
704 soa.AddLocalReference<jobject>(receiver.Get()));
705 ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
706 soa.AddLocalReference<jobject>(args.Get()));
liulvpingfff1d8f2020-12-21 09:43:37 +0800707 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
708 if (pointer_size == PointerSize::k64) {
709 InvokeMethod<PointerSize::k64>(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
710 } else {
711 InvokeMethod<PointerSize::k32>(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
712 }
Andreas Gampe85bef7e2017-02-16 18:13:26 -0800713 }
714 if (self->IsExceptionPending()) {
715 AbortTransactionOrFail(self, "Failed running constructor");
716 } else {
717 result->SetL(receiver.Get());
718 }
719}
720
Andreas Gampe799681b2015-05-15 19:24:12 -0700721void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700722 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Vladimir Marko4617d582019-03-28 13:48:31 +0000723 ObjPtr<mirror::String> class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
724 ObjPtr<mirror::ClassLoader> class_loader =
725 ObjPtr<mirror::ClassLoader>::DownCast(shadow_frame->GetVRegReference(arg_offset));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700726 StackHandleScope<2> hs(self);
727 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
728 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
Vladimir Marko0685b982021-03-25 11:59:22 +0000729 UnstartedRuntimeFindClass(self,
730 h_class_name,
731 h_class_loader,
732 result,
733 /*initialize_class=*/ false);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700734 // This might have an error pending. But semantics are to just return null.
735 if (self->IsExceptionPending()) {
Vladimir Marko0685b982021-03-25 11:59:22 +0000736 Runtime* runtime = Runtime::Current();
737 DCHECK_EQ(runtime->IsTransactionAborted(),
738 self->GetException()->GetClass()->DescriptorEquals(
739 Transaction::kAbortExceptionDescriptor))
740 << self->GetException()->GetClass()->PrettyDescriptor();
741 if (runtime->IsActiveTransaction()) {
742 // If we're not aborting the transaction yet, abort now. b/183691501
743 // See CheckExceptionGenerateClassNotFound() for more detailed explanation.
744 if (!runtime->IsTransactionAborted()) {
745 AbortTransactionF(self, "ClassNotFoundException");
746 }
747 } else {
748 // If not in a transaction, it cannot be the transaction abort exception. Clear it.
749 DCHECK(!runtime->IsTransactionAborted());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700750 self->ClearException();
751 }
752 }
753}
754
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700755// Arraycopy emulation.
756// Note: we can't use any fast copy functions, as they are not available under transaction.
757
758template <typename T>
759static void PrimitiveArrayCopy(Thread* self,
Vladimir Marko4617d582019-03-28 13:48:31 +0000760 ObjPtr<mirror::Array> src_array,
761 int32_t src_pos,
762 ObjPtr<mirror::Array> dst_array,
763 int32_t dst_pos,
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700764 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700765 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700766 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700767 AbortTransactionOrFail(self,
768 "Types mismatched in arraycopy: %s vs %s.",
769 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700770 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700771 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700772 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700773 return;
774 }
Vladimir Marko4617d582019-03-28 13:48:31 +0000775 ObjPtr<mirror::PrimitiveArray<T>> src = ObjPtr<mirror::PrimitiveArray<T>>::DownCast(src_array);
776 ObjPtr<mirror::PrimitiveArray<T>> dst = ObjPtr<mirror::PrimitiveArray<T>>::DownCast(dst_array);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700777 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
778 if (copy_forward) {
779 for (int32_t i = 0; i < length; ++i) {
780 dst->Set(dst_pos + i, src->Get(src_pos + i));
781 }
782 } else {
783 for (int32_t i = 1; i <= length; ++i) {
784 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
785 }
786 }
787}
788
Andreas Gampe799681b2015-05-15 19:24:12 -0700789void UnstartedRuntime::UnstartedSystemArraycopy(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700790 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700791 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700792 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
793 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700794 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700795
Andreas Gampe85a098a2016-03-31 13:30:53 -0700796 mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
797 mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
798 // Null checking. For simplicity, abort transaction.
799 if (src_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700800 AbortTransactionOrFail(self, "src is null in arraycopy.");
801 return;
802 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700803 if (dst_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700804 AbortTransactionOrFail(self, "dst is null in arraycopy.");
805 return;
806 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700807 // Test for arrayness. Throw ArrayStoreException.
808 if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
809 self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
810 return;
811 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700812
Vladimir Marko4617d582019-03-28 13:48:31 +0000813 ObjPtr<mirror::Array> src_array = src_obj->AsArray();
814 ObjPtr<mirror::Array> dst_array = dst_obj->AsArray();
Andreas Gampe85a098a2016-03-31 13:30:53 -0700815
816 // Bounds checking. Throw IndexOutOfBoundsException.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700817 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
818 UNLIKELY(src_pos > src_array->GetLength() - length) ||
819 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700820 self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700821 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
822 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
823 length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700824 return;
825 }
826
Vladimir Marko4d7b6892020-01-16 17:06:35 +0000827 if (Runtime::Current()->IsActiveTransaction() && !CheckWriteConstraint(self, dst_obj)) {
828 DCHECK(self->IsExceptionPending());
829 return;
830 }
831
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700832 // Type checking.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100833 ObjPtr<mirror::Class> src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700834 GetComponentType();
835
836 if (!src_type->IsPrimitive()) {
837 // Check that the second type is not primitive.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100838 ObjPtr<mirror::Class> trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700839 GetComponentType();
840 if (trg_type->IsPrimitiveInt()) {
841 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700842 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700843 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700844 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700845 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700846 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700847 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700848
Vladimir Marko4617d582019-03-28 13:48:31 +0000849 ObjPtr<mirror::ObjectArray<mirror::Object>> src = src_array->AsObjectArray<mirror::Object>();
850 ObjPtr<mirror::ObjectArray<mirror::Object>> dst = dst_array->AsObjectArray<mirror::Object>();
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700851 if (src == dst) {
852 // Can overlap, but not have type mismatches.
Andreas Gampe85a098a2016-03-31 13:30:53 -0700853 // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700854 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
855 if (copy_forward) {
856 for (int32_t i = 0; i < length; ++i) {
857 dst->Set(dst_pos + i, src->Get(src_pos + i));
858 }
859 } else {
860 for (int32_t i = 1; i <= length; ++i) {
861 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
862 }
863 }
864 } else {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700865 // We're being lazy here. Optimally this could be a memcpy (if component types are
866 // assignable), but the ObjectArray implementation doesn't support transactions. The
867 // checking version, however, does.
868 if (Runtime::Current()->IsActiveTransaction()) {
869 dst->AssignableCheckingMemcpy<true>(
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700870 dst_pos, src, src_pos, length, /* throw_exception= */ true);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700871 } else {
872 dst->AssignableCheckingMemcpy<false>(
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700873 dst_pos, src, src_pos, length, /* throw_exception= */ true);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700874 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700875 }
Andreas Gampe5c9af612016-04-05 14:16:10 -0700876 } else if (src_type->IsPrimitiveByte()) {
877 PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700878 } else if (src_type->IsPrimitiveChar()) {
879 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
880 } else if (src_type->IsPrimitiveInt()) {
881 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700882 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700883 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700884 src_type->PrettyDescriptor().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700885 }
886}
887
Andreas Gampe5c9af612016-04-05 14:16:10 -0700888void UnstartedRuntime::UnstartedSystemArraycopyByte(
889 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
890 // Just forward.
891 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
892}
893
Andreas Gampe799681b2015-05-15 19:24:12 -0700894void UnstartedRuntime::UnstartedSystemArraycopyChar(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700895 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700896 // Just forward.
897 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
898}
899
900void UnstartedRuntime::UnstartedSystemArraycopyInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700901 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700902 // Just forward.
903 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
904}
905
Narayan Kamath34a316f2016-03-30 13:11:18 +0100906void UnstartedRuntime::UnstartedSystemGetSecurityManager(
907 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
908 JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
909 result->SetL(nullptr);
910}
911
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700912static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
913
914static void GetSystemProperty(Thread* self,
915 ShadowFrame* shadow_frame,
916 JValue* result,
917 size_t arg_offset,
918 bool is_default_version)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700919 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700920 StackHandleScope<4> hs(self);
921 Handle<mirror::String> h_key(
922 hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800923 if (h_key == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700924 AbortTransactionOrFail(self, "getProperty key was null");
925 return;
926 }
927
928 // This is overall inefficient, but reflecting the values here is not great, either. So
929 // for simplicity, and with the assumption that the number of getProperty calls is not
930 // too great, just iterate each time.
931
932 // Get the storage class.
933 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
934 Handle<mirror::Class> h_props_class(hs.NewHandle(
935 class_linker->FindClass(self,
936 "Ljava/lang/AndroidHardcodedSystemProperties;",
937 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800938 if (h_props_class == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700939 AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
940 return;
941 }
942 if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
943 AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
944 return;
945 }
946
947 // Get the storage array.
948 ArtField* static_properties =
949 h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
950 "[[Ljava/lang/String;");
951 if (static_properties == nullptr) {
952 AbortTransactionOrFail(self,
953 "Could not find %s field",
954 kAndroidHardcodedSystemPropertiesFieldName);
955 return;
956 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700957 ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
958 Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
959 props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800960 if (h_2string_array == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700961 AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
962 return;
963 }
964
965 // Iterate over it.
966 const int32_t prop_count = h_2string_array->GetLength();
967 // Use the third handle as mutable.
968 MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
969 hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
970 for (int32_t i = 0; i < prop_count; ++i) {
971 h_string_array.Assign(h_2string_array->Get(i));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800972 if (h_string_array == nullptr ||
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700973 h_string_array->GetLength() != 2 ||
974 h_string_array->Get(0) == nullptr) {
975 AbortTransactionOrFail(self,
976 "Unexpected content of %s",
977 kAndroidHardcodedSystemPropertiesFieldName);
978 return;
979 }
980 if (h_key->Equals(h_string_array->Get(0))) {
981 // Found a value.
982 if (h_string_array->Get(1) == nullptr && is_default_version) {
983 // Null is being delegated to the default map, and then resolved to the given default value.
984 // As there's no default map, return the given value.
985 result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
986 } else {
987 result->SetL(h_string_array->Get(1));
988 }
989 return;
990 }
991 }
992
993 // Key is not supported.
994 AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
995}
996
997void UnstartedRuntime::UnstartedSystemGetProperty(
998 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
999 GetSystemProperty(self, shadow_frame, result, arg_offset, false);
1000}
1001
1002void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
1003 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1004 GetSystemProperty(self, shadow_frame, result, arg_offset, true);
1005}
1006
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001007static std::string GetImmediateCaller(ShadowFrame* shadow_frame)
1008 REQUIRES_SHARED(Locks::mutator_lock_) {
1009 if (shadow_frame->GetLink() == nullptr) {
1010 return "<no caller>";
1011 }
1012 return ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1013}
1014
1015static bool CheckCallers(ShadowFrame* shadow_frame,
1016 std::initializer_list<std::string> allowed_call_stack)
1017 REQUIRES_SHARED(Locks::mutator_lock_) {
1018 for (const std::string& allowed_caller : allowed_call_stack) {
1019 if (shadow_frame->GetLink() == nullptr) {
1020 return false;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001021 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001022
1023 std::string found_caller = ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1024 if (allowed_caller != found_caller) {
1025 return false;
1026 }
1027
1028 shadow_frame = shadow_frame->GetLink();
1029 }
1030 return true;
1031}
1032
1033static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_descriptor)
1034 REQUIRES_SHARED(Locks::mutator_lock_) {
1035 // Find the requested class.
1036 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1037 ObjPtr<mirror::Class> klass =
1038 class_linker->FindClass(self, class_descriptor, ScopedNullHandle<mirror::ClassLoader>());
1039 if (klass == nullptr) {
1040 AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
1041 return nullptr;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001042 }
1043
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001044 StackHandleScope<2> hs(self);
1045 Handle<mirror::Class> h_class(hs.NewHandle(klass));
1046 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001047 if (h_obj != nullptr) {
Vladimir Markoba118822017-06-12 15:41:56 +01001048 ArtMethod* init_method = h_class->FindConstructor("()V", class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001049 if (init_method == nullptr) {
1050 AbortTransactionOrFail(self, "Could not find <init> for %s", class_descriptor);
1051 return nullptr;
1052 } else {
1053 JValue invoke_result;
1054 EnterInterpreterFromInvoke(self, init_method, h_obj.Get(), nullptr, nullptr);
1055 if (!self->IsExceptionPending()) {
1056 return h_obj.Get();
1057 }
1058 AbortTransactionOrFail(self, "Could not run <init> for %s", class_descriptor);
1059 }
1060 }
1061 AbortTransactionOrFail(self, "Could not allocate instance of %s", class_descriptor);
1062 return nullptr;
1063}
1064
1065void UnstartedRuntime::UnstartedThreadLocalGet(
1066 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
Nikita Iashchenkob05bf892021-09-06 23:48:36 +01001067 if (CheckCallers(shadow_frame, { "jdk.internal.math.FloatingDecimal$BinaryToASCIIBuffer "
1068 "jdk.internal.math.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1069 result->SetL(CreateInstanceOf(self, "Ljdk/internal/math/FloatingDecimal$BinaryToASCIIBuffer;"));
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001070 } else {
1071 AbortTransactionOrFail(self,
1072 "ThreadLocal.get() does not support %s",
1073 GetImmediateCaller(shadow_frame).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001074 }
1075}
1076
Andreas Gampebad529d2017-02-13 18:52:10 -08001077void UnstartedRuntime::UnstartedThreadCurrentThread(
1078 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1079 if (CheckCallers(shadow_frame,
Nikita Iashchenko236f7bf2021-09-15 17:36:39 +01001080 { "void java.lang.Thread.<init>(java.lang.ThreadGroup, java.lang.Runnable, "
1081 "java.lang.String, long, java.security.AccessControlContext, boolean)",
1082 "void java.lang.Thread.<init>(java.lang.ThreadGroup, java.lang.Runnable, "
Andreas Gampebad529d2017-02-13 18:52:10 -08001083 "java.lang.String, long)",
1084 "void java.lang.Thread.<init>()",
1085 "void java.util.logging.LogManager$Cleaner.<init>("
1086 "java.util.logging.LogManager)" })) {
Orion Hodson611d71c2021-08-27 17:00:10 +01001087 // Allow list LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
Andreas Gampebad529d2017-02-13 18:52:10 -08001088 // Thread constructor only asks for the current thread to set up defaults and add the
1089 // thread as unstarted to the ThreadGroup. A faked-up main thread peer is good enough for
1090 // these purposes.
1091 Runtime::Current()->InitThreadGroups(self);
1092 jobject main_peer =
1093 self->CreateCompileTimePeer(self->GetJniEnv(),
1094 "main",
1095 false,
1096 Runtime::Current()->GetMainThreadGroup());
1097 if (main_peer == nullptr) {
1098 AbortTransactionOrFail(self, "Failed allocating peer");
1099 return;
1100 }
1101
1102 result->SetL(self->DecodeJObject(main_peer));
1103 self->GetJniEnv()->DeleteLocalRef(main_peer);
1104 } else {
1105 AbortTransactionOrFail(self,
1106 "Thread.currentThread() does not support %s",
1107 GetImmediateCaller(shadow_frame).c_str());
1108 }
1109}
1110
1111void UnstartedRuntime::UnstartedThreadGetNativeState(
1112 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1113 if (CheckCallers(shadow_frame,
1114 { "java.lang.Thread$State java.lang.Thread.getState()",
1115 "java.lang.ThreadGroup java.lang.Thread.getThreadGroup()",
Nikita Iashchenko236f7bf2021-09-15 17:36:39 +01001116 "void java.lang.Thread.<init>(java.lang.ThreadGroup, java.lang.Runnable, "
1117 "java.lang.String, long, java.security.AccessControlContext, boolean)",
1118 "void java.lang.Thread.<init>(java.lang.ThreadGroup, java.lang.Runnable, "
Andreas Gampebad529d2017-02-13 18:52:10 -08001119 "java.lang.String, long)",
1120 "void java.lang.Thread.<init>()",
1121 "void java.util.logging.LogManager$Cleaner.<init>("
1122 "java.util.logging.LogManager)" })) {
Orion Hodson611d71c2021-08-27 17:00:10 +01001123 // Allow list reading the state of the "main" thread when creating another (unstarted) thread
Andreas Gampebad529d2017-02-13 18:52:10 -08001124 // for LogManager. Report the thread as "new" (it really only counts that it isn't terminated).
1125 constexpr int32_t kJavaRunnable = 1;
1126 result->SetI(kJavaRunnable);
1127 } else {
1128 AbortTransactionOrFail(self,
1129 "Thread.getNativeState() does not support %s",
1130 GetImmediateCaller(shadow_frame).c_str());
1131 }
1132}
1133
Sergio Giro83261202016-04-11 20:49:20 +01001134void UnstartedRuntime::UnstartedMathCeil(
1135 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001136 result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
Sergio Giro83261202016-04-11 20:49:20 +01001137}
1138
1139void UnstartedRuntime::UnstartedMathFloor(
1140 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001141 result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001142}
1143
Andreas Gampeb8a00f92016-04-18 20:51:13 -07001144void UnstartedRuntime::UnstartedMathSin(
1145 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1146 result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
1147}
1148
1149void UnstartedRuntime::UnstartedMathCos(
1150 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1151 result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
1152}
1153
1154void UnstartedRuntime::UnstartedMathPow(
1155 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1156 result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
1157 shadow_frame->GetVRegDouble(arg_offset + 2)));
1158}
1159
Andreas Gampe799681b2015-05-15 19:24:12 -07001160void UnstartedRuntime::UnstartedObjectHashCode(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001161 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001162 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1163 result->SetI(obj->IdentityHashCode());
1164}
1165
Andreas Gampe799681b2015-05-15 19:24:12 -07001166void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
Andreas Gampedd9d0552015-03-09 12:57:41 -07001167 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001168 double in = shadow_frame->GetVRegDouble(arg_offset);
Roland Levillainda4d79b2015-03-24 14:36:11 +00001169 result->SetJ(bit_cast<int64_t, double>(in));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001170}
1171
Andreas Gampedd9d0552015-03-09 12:57:41 -07001172static void UnstartedMemoryPeek(
1173 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1174 int64_t address = shadow_frame->GetVRegLong(arg_offset);
1175 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
1176 // aborting the transaction.
1177
1178 switch (type) {
1179 case Primitive::kPrimByte: {
1180 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
1181 return;
1182 }
1183
1184 case Primitive::kPrimShort: {
Andreas Gampec55bb392018-09-21 00:02:02 +00001185 using unaligned_short __attribute__((__aligned__(1))) = int16_t;
Andreas Gampe799681b2015-05-15 19:24:12 -07001186 result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001187 return;
1188 }
1189
1190 case Primitive::kPrimInt: {
Andreas Gampec55bb392018-09-21 00:02:02 +00001191 using unaligned_int __attribute__((__aligned__(1))) = int32_t;
Andreas Gampe799681b2015-05-15 19:24:12 -07001192 result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001193 return;
1194 }
1195
1196 case Primitive::kPrimLong: {
Andreas Gampec55bb392018-09-21 00:02:02 +00001197 using unaligned_long __attribute__((__aligned__(1))) = int64_t;
Andreas Gampe799681b2015-05-15 19:24:12 -07001198 result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001199 return;
1200 }
1201
1202 case Primitive::kPrimBoolean:
1203 case Primitive::kPrimChar:
1204 case Primitive::kPrimFloat:
1205 case Primitive::kPrimDouble:
1206 case Primitive::kPrimVoid:
1207 case Primitive::kPrimNot:
1208 LOG(FATAL) << "Not in the Memory API: " << type;
1209 UNREACHABLE();
1210 }
1211 LOG(FATAL) << "Should not reach here";
1212 UNREACHABLE();
1213}
1214
Andreas Gampe799681b2015-05-15 19:24:12 -07001215void UnstartedRuntime::UnstartedMemoryPeekByte(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001216 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001217 UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
1218}
1219
1220void UnstartedRuntime::UnstartedMemoryPeekShort(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001221 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001222 UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
1223}
1224
1225void UnstartedRuntime::UnstartedMemoryPeekInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001226 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001227 UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
1228}
1229
1230void UnstartedRuntime::UnstartedMemoryPeekLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001231 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001232 UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001233}
1234
1235static void UnstartedMemoryPeekArray(
1236 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001237 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampedd9d0552015-03-09 12:57:41 -07001238 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1239 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1240 if (obj == nullptr) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001241 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
Andreas Gampedd9d0552015-03-09 12:57:41 -07001242 return;
1243 }
Vladimir Marko4617d582019-03-28 13:48:31 +00001244 ObjPtr<mirror::Array> array = obj->AsArray();
Andreas Gampedd9d0552015-03-09 12:57:41 -07001245
1246 int offset = shadow_frame->GetVReg(arg_offset + 3);
1247 int count = shadow_frame->GetVReg(arg_offset + 4);
1248 if (offset < 0 || offset + count > array->GetLength()) {
1249 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
1250 offset, count, array->GetLength()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001251 Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
Andreas Gampedd9d0552015-03-09 12:57:41 -07001252 return;
1253 }
1254
1255 switch (type) {
1256 case Primitive::kPrimByte: {
1257 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
Vladimir Marko4617d582019-03-28 13:48:31 +00001258 ObjPtr<mirror::ByteArray> byte_array = array->AsByteArray();
Andreas Gampedd9d0552015-03-09 12:57:41 -07001259 for (int32_t i = 0; i < count; ++i, ++address) {
1260 byte_array->SetWithoutChecks<true>(i + offset, *address);
1261 }
1262 return;
1263 }
1264
1265 case Primitive::kPrimShort:
1266 case Primitive::kPrimInt:
1267 case Primitive::kPrimLong:
1268 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1269 UNREACHABLE();
1270
1271 case Primitive::kPrimBoolean:
1272 case Primitive::kPrimChar:
1273 case Primitive::kPrimFloat:
1274 case Primitive::kPrimDouble:
1275 case Primitive::kPrimVoid:
1276 case Primitive::kPrimNot:
1277 LOG(FATAL) << "Not in the Memory API: " << type;
1278 UNREACHABLE();
1279 }
1280 LOG(FATAL) << "Should not reach here";
1281 UNREACHABLE();
1282}
1283
Andreas Gampe799681b2015-05-15 19:24:12 -07001284void UnstartedRuntime::UnstartedMemoryPeekByteArray(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001285 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001286 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001287}
1288
Kenny Root1c9e61c2015-05-14 15:58:17 -07001289// This allows reading the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001290void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001291 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001292 jint start = shadow_frame->GetVReg(arg_offset + 1);
1293 jint end = shadow_frame->GetVReg(arg_offset + 2);
1294 jint index = shadow_frame->GetVReg(arg_offset + 4);
Vladimir Marko4617d582019-03-28 13:48:31 +00001295 ObjPtr<mirror::String> string = shadow_frame->GetVRegReference(arg_offset)->AsString();
Kenny Root1c9e61c2015-05-14 15:58:17 -07001296 if (string == nullptr) {
1297 AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1298 return;
1299 }
Kenny Root57f91e82015-05-14 15:58:17 -07001300 DCHECK_GE(start, 0);
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001301 DCHECK_LE(start, end);
1302 DCHECK_LE(end, string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001303 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001304 Handle<mirror::CharArray> h_char_array(
1305 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001306 DCHECK_GE(index, 0);
Kenny Root57f91e82015-05-14 15:58:17 -07001307 DCHECK_LE(index, h_char_array->GetLength());
1308 DCHECK_LE(end - start, h_char_array->GetLength() - index);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001309 string->GetChars(start, end, h_char_array, index);
1310}
1311
1312// This allows reading chars from the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001313void UnstartedRuntime::UnstartedStringCharAt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001314 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001315 jint index = shadow_frame->GetVReg(arg_offset + 1);
Vladimir Marko4617d582019-03-28 13:48:31 +00001316 ObjPtr<mirror::String> string = shadow_frame->GetVRegReference(arg_offset)->AsString();
Kenny Root1c9e61c2015-05-14 15:58:17 -07001317 if (string == nullptr) {
1318 AbortTransactionOrFail(self, "String.charAt with null object");
1319 return;
1320 }
1321 result->SetC(string->CharAt(index));
1322}
1323
Vladimir Marko92907f32017-02-20 14:08:30 +00001324// This allows creating String objects with replaced characters during compilation.
1325// String.doReplace(char, char) is called from String.replace(char, char) when there is a match.
1326void UnstartedRuntime::UnstartedStringDoReplace(
1327 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1328 jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
1329 jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001330 StackHandleScope<1> hs(self);
1331 Handle<mirror::String> string =
1332 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
Kenny Root57f91e82015-05-14 15:58:17 -07001333 if (string == nullptr) {
Vladimir Marko92907f32017-02-20 14:08:30 +00001334 AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
Kenny Root57f91e82015-05-14 15:58:17 -07001335 return;
1336 }
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001337 result->SetL(mirror::String::DoReplace(self, string, old_c, new_c));
Kenny Root57f91e82015-05-14 15:58:17 -07001338}
1339
Kenny Root1c9e61c2015-05-14 15:58:17 -07001340// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001341void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001342 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001343 jint offset = shadow_frame->GetVReg(arg_offset);
1344 jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1345 DCHECK_GE(char_count, 0);
1346 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001347 Handle<mirror::CharArray> h_char_array(
1348 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
Kenny Root1c9e61c2015-05-14 15:58:17 -07001349 Runtime* runtime = Runtime::Current();
1350 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Vladimir Marko9b81ac32019-05-16 16:47:08 +01001351 result->SetL(
1352 mirror::String::AllocFromCharArray(self, char_count, h_char_array, offset, allocator));
Kenny Root1c9e61c2015-05-14 15:58:17 -07001353}
1354
1355// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001356void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001357 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Vladimir Marko4617d582019-03-28 13:48:31 +00001358 ObjPtr<mirror::String> to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
Kenny Root57f91e82015-05-14 15:58:17 -07001359 if (to_copy == nullptr) {
1360 AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1361 return;
1362 }
1363 StackHandleScope<1> hs(self);
1364 Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1365 Runtime* runtime = Runtime::Current();
1366 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Vladimir Marko9b81ac32019-05-16 16:47:08 +01001367 result->SetL(
1368 mirror::String::AllocFromString(self, h_string->GetLength(), h_string, 0, allocator));
Kenny Root57f91e82015-05-14 15:58:17 -07001369}
1370
Andreas Gampe799681b2015-05-15 19:24:12 -07001371void UnstartedRuntime::UnstartedStringFastSubstring(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001372 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001373 jint start = shadow_frame->GetVReg(arg_offset + 1);
1374 jint length = shadow_frame->GetVReg(arg_offset + 2);
Kenny Root57f91e82015-05-14 15:58:17 -07001375 DCHECK_GE(start, 0);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001376 DCHECK_GE(length, 0);
1377 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001378 Handle<mirror::String> h_string(
1379 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
Kenny Root57f91e82015-05-14 15:58:17 -07001380 DCHECK_LE(start, h_string->GetLength());
1381 DCHECK_LE(start + length, h_string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001382 Runtime* runtime = Runtime::Current();
1383 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Vladimir Marko9b81ac32019-05-16 16:47:08 +01001384 result->SetL(mirror::String::AllocFromString(self, length, h_string, start, allocator));
Kenny Root1c9e61c2015-05-14 15:58:17 -07001385}
1386
Kenny Root57f91e82015-05-14 15:58:17 -07001387// This allows getting the char array for new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001388void UnstartedRuntime::UnstartedStringToCharArray(
Kenny Root57f91e82015-05-14 15:58:17 -07001389 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001390 REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Marko3068d582019-05-28 16:39:29 +01001391 StackHandleScope<1> hs(self);
1392 Handle<mirror::String> string =
1393 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
Kenny Root57f91e82015-05-14 15:58:17 -07001394 if (string == nullptr) {
1395 AbortTransactionOrFail(self, "String.charAt with null object");
1396 return;
1397 }
Vladimir Marko3068d582019-05-28 16:39:29 +01001398 result->SetL(mirror::String::ToCharArray(string, self));
Kenny Root57f91e82015-05-14 15:58:17 -07001399}
1400
Andreas Gampebc4d2182016-02-22 10:03:12 -08001401// This allows statically initializing ConcurrentHashMap and SynchronousQueue.
1402void UnstartedRuntime::UnstartedReferenceGetReferent(
1403 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Vladimir Markoec389672021-01-14 10:58:31 +00001404 const ObjPtr<mirror::Reference> ref = ObjPtr<mirror::Reference>::DownCast(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001405 shadow_frame->GetVRegReference(arg_offset));
1406 if (ref == nullptr) {
1407 AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1408 return;
1409 }
Vladimir Marko0984e482019-03-27 16:41:41 +00001410 const ObjPtr<mirror::Object> referent =
Andreas Gampebc4d2182016-02-22 10:03:12 -08001411 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1412 result->SetL(referent);
1413}
1414
Vladimir Markoec389672021-01-14 10:58:31 +00001415void UnstartedRuntime::UnstartedReferenceRefersTo(
1416 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1417 // Use the naive implementation that may block and needlessly extend the lifetime
1418 // of the referenced object.
1419 const ObjPtr<mirror::Reference> ref = ObjPtr<mirror::Reference>::DownCast(
1420 shadow_frame->GetVRegReference(arg_offset));
1421 if (ref == nullptr) {
1422 AbortTransactionOrFail(self, "Reference.refersTo() with null object");
1423 return;
1424 }
1425 const ObjPtr<mirror::Object> referent =
1426 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1427 const ObjPtr<mirror::Object> o = shadow_frame->GetVRegReference(arg_offset + 1);
1428 result->SetZ(o == referent);
1429}
1430
Andreas Gampebc4d2182016-02-22 10:03:12 -08001431// This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1432// conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1433// where we can predict the behavior (somewhat).
1434// Note: this is required (instead of lazy initialization) as these classes are used in the static
1435// initialization of other classes, so will *use* the value.
1436void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1437 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001438 if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001439 // SynchronousQueue really only separates between single- and multiprocessor case. Return
1440 // 8 as a conservative upper approximation.
1441 result->SetI(8);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001442 } else if (CheckCallers(shadow_frame,
1443 { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001444 // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1445 // a good upper bound.
1446 // TODO: Consider resetting in the zygote?
1447 result->SetI(8);
1448 } else {
1449 // Not supported.
1450 AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1451 }
1452}
1453
1454// This allows accessing ConcurrentHashMap/SynchronousQueue.
1455
1456void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1457 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Sorin Basca2f01e8e2021-06-18 06:44:07 +00001458 UnstartedJdkUnsafeCompareAndSwapLong(self, shadow_frame, result, arg_offset);
1459}
1460
1461void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1462 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1463 UnstartedJdkUnsafeCompareAndSwapObject(self, shadow_frame, result, arg_offset);
1464}
1465
1466void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1467 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1468 REQUIRES_SHARED(Locks::mutator_lock_) {
1469 UnstartedJdkUnsafeGetObjectVolatile(self, shadow_frame, result, arg_offset);
1470}
1471
1472void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1473 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1474 REQUIRES_SHARED(Locks::mutator_lock_) {
1475 UnstartedJdkUnsafePutObjectVolatile(self, shadow_frame, result, arg_offset);
1476}
1477
1478void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1479 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1480 REQUIRES_SHARED(Locks::mutator_lock_) {
1481 UnstartedJdkUnsafePutOrderedObject(self, shadow_frame, result, arg_offset);
1482}
1483
1484void UnstartedRuntime::UnstartedJdkUnsafeCompareAndSwapLong(
1485 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001486 // Argument 0 is the Unsafe instance, skip.
1487 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1488 if (obj == nullptr) {
1489 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1490 return;
1491 }
1492 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1493 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1494 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001495 bool success;
1496 // Check whether we're in a transaction, call accordingly.
1497 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001498 if (!CheckWriteConstraint(self, obj)) {
1499 DCHECK(self->IsExceptionPending());
1500 return;
1501 }
Andreas Gampebc4d2182016-02-22 10:03:12 -08001502 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1503 expectedValue,
1504 newValue);
1505 } else {
1506 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1507 expectedValue,
1508 newValue);
1509 }
1510 result->SetZ(success ? 1 : 0);
1511}
1512
Sorin Basca2f01e8e2021-06-18 06:44:07 +00001513void UnstartedRuntime::UnstartedJdkUnsafeCompareAndSwapObject(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001514 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1515 // Argument 0 is the Unsafe instance, skip.
1516 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1517 if (obj == nullptr) {
1518 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1519 return;
1520 }
1521 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1522 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001523 mirror::Object* new_value = shadow_frame->GetVRegReference(arg_offset + 5);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001524
1525 // Must use non transactional mode.
1526 if (kUseReadBarrier) {
1527 // Need to make sure the reference stored in the field is a to-space one before attempting the
1528 // CAS or the CAS could fail incorrectly.
1529 mirror::HeapReference<mirror::Object>* field_addr =
1530 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1531 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001532 ReadBarrier::Barrier<
1533 mirror::Object,
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001534 /* kIsVolatile= */ false,
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001535 kWithReadBarrier,
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001536 /* kAlwaysUpdateField= */ true>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001537 obj,
1538 MemberOffset(offset),
1539 field_addr);
1540 }
1541 bool success;
1542 // Check whether we're in a transaction, call accordingly.
1543 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001544 if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, new_value)) {
1545 DCHECK(self->IsExceptionPending());
1546 return;
1547 }
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001548 success = obj->CasFieldObject<true>(MemberOffset(offset),
1549 expected_value,
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001550 new_value,
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001551 CASMode::kStrong,
1552 std::memory_order_seq_cst);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001553 } else {
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001554 success = obj->CasFieldObject<false>(MemberOffset(offset),
1555 expected_value,
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001556 new_value,
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001557 CASMode::kStrong,
1558 std::memory_order_seq_cst);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001559 }
1560 result->SetZ(success ? 1 : 0);
1561}
1562
Sorin Basca2f01e8e2021-06-18 06:44:07 +00001563void UnstartedRuntime::UnstartedJdkUnsafeGetObjectVolatile(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001564 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001565 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001566 // Argument 0 is the Unsafe instance, skip.
1567 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1568 if (obj == nullptr) {
1569 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1570 return;
1571 }
1572 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
Vladimir Markodfc0de72019-04-01 10:57:55 +01001573 ObjPtr<mirror::Object> value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
Andreas Gampebc4d2182016-02-22 10:03:12 -08001574 result->SetL(value);
1575}
1576
Sorin Basca2f01e8e2021-06-18 06:44:07 +00001577void UnstartedRuntime::UnstartedJdkUnsafePutObjectVolatile(
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001578 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001579 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001580 // Argument 0 is the Unsafe instance, skip.
1581 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1582 if (obj == nullptr) {
1583 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1584 return;
1585 }
1586 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1587 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1588 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001589 if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, value)) {
1590 DCHECK(self->IsExceptionPending());
1591 return;
1592 }
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001593 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1594 } else {
1595 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1596 }
1597}
1598
Sorin Basca2f01e8e2021-06-18 06:44:07 +00001599void UnstartedRuntime::UnstartedJdkUnsafePutOrderedObject(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001600 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001601 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001602 // Argument 0 is the Unsafe instance, skip.
1603 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1604 if (obj == nullptr) {
1605 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1606 return;
1607 }
1608 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001609 mirror::Object* new_value = shadow_frame->GetVRegReference(arg_offset + 4);
Orion Hodson27b96762018-03-13 16:06:57 +00001610 std::atomic_thread_fence(std::memory_order_release);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001611 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001612 if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, new_value)) {
1613 DCHECK(self->IsExceptionPending());
1614 return;
1615 }
1616 obj->SetFieldObject<true>(MemberOffset(offset), new_value);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001617 } else {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001618 obj->SetFieldObject<false>(MemberOffset(offset), new_value);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001619 }
1620}
1621
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001622// A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1623// of correctly handling the corner cases.
1624void UnstartedRuntime::UnstartedIntegerParseInt(
1625 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001626 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001627 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1628 if (obj == nullptr) {
1629 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1630 return;
1631 }
1632
1633 std::string string_value = obj->AsString()->ToModifiedUtf8();
1634 if (string_value.empty()) {
1635 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1636 return;
1637 }
1638
1639 const char* c_str = string_value.c_str();
1640 char *end;
1641 // Can we set errno to 0? Is this always a variable, and not a macro?
1642 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1643 int64_t l = strtol(c_str, &end, 10);
1644
1645 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1646 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1647 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1648 return;
1649 }
1650 if (l == 0) {
1651 // Check whether the string wasn't exactly zero.
1652 if (string_value != "0") {
1653 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1654 return;
1655 }
1656 } else if (*end != '\0') {
1657 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1658 return;
1659 }
1660
1661 result->SetI(static_cast<int32_t>(l));
1662}
1663
1664// A cutout for Long.parseLong.
1665//
1666// Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1667// well.
1668void UnstartedRuntime::UnstartedLongParseLong(
1669 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001670 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001671 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1672 if (obj == nullptr) {
1673 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1674 return;
1675 }
1676
1677 std::string string_value = obj->AsString()->ToModifiedUtf8();
1678 if (string_value.empty()) {
1679 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1680 return;
1681 }
1682
1683 const char* c_str = string_value.c_str();
1684 char *end;
1685 // Can we set errno to 0? Is this always a variable, and not a macro?
1686 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1687 int64_t l = strtol(c_str, &end, 10);
1688
1689 // Note: comparing against int32_t min/max is intentional here.
1690 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1691 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1692 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1693 return;
1694 }
1695 if (l == 0) {
1696 // Check whether the string wasn't exactly zero.
1697 if (string_value != "0") {
1698 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1699 return;
1700 }
1701 } else if (*end != '\0') {
1702 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1703 return;
1704 }
1705
1706 result->SetJ(l);
1707}
1708
Andreas Gampe715fdc22016-04-18 17:07:30 -07001709void UnstartedRuntime::UnstartedMethodInvoke(
1710 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001711 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe715fdc22016-04-18 17:07:30 -07001712 JNIEnvExt* env = self->GetJniEnv();
1713 ScopedObjectAccessUnchecked soa(self);
1714
Mathieu Chartier8778c522016-10-04 19:06:30 -07001715 ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001716 ScopedLocalRef<jobject> java_method(env,
Roland Levillain5e8d5f02016-10-18 18:03:43 +01001717 java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001718
Mathieu Chartier8778c522016-10-04 19:06:30 -07001719 ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001720 ScopedLocalRef<jobject> java_receiver(env,
1721 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1722
Mathieu Chartier8778c522016-10-04 19:06:30 -07001723 ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001724 ScopedLocalRef<jobject> java_args(env,
1725 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1726
liulvpingfff1d8f2020-12-21 09:43:37 +08001727 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Andreas Gampe715fdc22016-04-18 17:07:30 -07001728 ScopedLocalRef<jobject> result_jobj(env,
liulvpingfff1d8f2020-12-21 09:43:37 +08001729 (pointer_size == PointerSize::k64)
1730 ? InvokeMethod<PointerSize::k64>(soa,
1731 java_method.get(),
1732 java_receiver.get(),
1733 java_args.get())
1734 : InvokeMethod<PointerSize::k32>(soa,
1735 java_method.get(),
1736 java_receiver.get(),
1737 java_args.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001738
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001739 result->SetL(self->DecodeJObject(result_jobj.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001740
1741 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1742 // InvocationTargetExceptions.
1743 if (self->IsExceptionPending()) {
1744 AbortTransactionOrFail(self, "Failed Method.invoke");
1745 }
1746}
1747
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001748void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1749 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1750 REQUIRES_SHARED(Locks::mutator_lock_) {
1751 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1752 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1753}
Andreas Gampebc4d2182016-02-22 10:03:12 -08001754
Orion Hodson43f0cdb2017-10-10 14:47:32 +01001755// Checks whether the runtime is s64-bit. This is needed for the clinit of
1756// java.lang.invoke.VarHandle clinit. The clinit determines sets of
1757// available VarHandle accessors and these differ based on machine
1758// word size.
1759void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1760 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1761 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1762 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1763 jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1764 result->SetZ(is64bit);
1765}
1766
Mathieu Chartiere401d142015-04-22 13:56:20 -07001767void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
Vladimir Marko78baed52018-10-11 10:44:58 +01001768 Thread* self,
1769 ArtMethod* method ATTRIBUTE_UNUSED,
1770 mirror::Object* receiver ATTRIBUTE_UNUSED,
1771 uint32_t* args,
1772 JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001773 int32_t length = args[1];
1774 DCHECK_GE(length, 0);
Vladimir Marko78baed52018-10-11 10:44:58 +01001775 ObjPtr<mirror::Object> element_class = reinterpret_cast32<mirror::Object*>(args[0])->AsClass();
1776 if (element_class == nullptr) {
1777 AbortTransactionOrFail(self, "VMRuntime.newUnpaddedArray with null element_class.");
1778 return;
1779 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001780 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001781 ObjPtr<mirror::Class> array_class =
Vladimir Marko78baed52018-10-11 10:44:58 +01001782 runtime->GetClassLinker()->FindArrayClass(self, element_class->AsClass());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001783 DCHECK(array_class != nullptr);
1784 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Vladimir Marko9b81ac32019-05-16 16:47:08 +01001785 result->SetL(mirror::Array::Alloc</*kIsInstrumented=*/ true, /*kFillUsable=*/ true>(
1786 self, array_class, length, array_class->GetComponentSizeShift(), allocator));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001787}
1788
Mathieu Chartiere401d142015-04-22 13:56:20 -07001789void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1790 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1791 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001792 result->SetL(nullptr);
1793}
1794
Mathieu Chartiere401d142015-04-22 13:56:20 -07001795void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1796 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1797 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001798 NthCallerVisitor visitor(self, 3);
1799 visitor.WalkStack();
1800 if (visitor.caller != nullptr) {
1801 result->SetL(visitor.caller->GetDeclaringClass());
1802 }
1803}
1804
Mathieu Chartiere401d142015-04-22 13:56:20 -07001805void UnstartedRuntime::UnstartedJNIMathLog(
1806 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1807 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001808 JValue value;
1809 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1810 result->SetD(log(value.GetD()));
1811}
1812
Mathieu Chartiere401d142015-04-22 13:56:20 -07001813void UnstartedRuntime::UnstartedJNIMathExp(
1814 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1815 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001816 JValue value;
1817 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1818 result->SetD(exp(value.GetD()));
1819}
1820
Andreas Gampebc4d2182016-02-22 10:03:12 -08001821void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1822 Thread* self ATTRIBUTE_UNUSED,
1823 ArtMethod* method ATTRIBUTE_UNUSED,
1824 mirror::Object* receiver ATTRIBUTE_UNUSED,
1825 uint32_t* args ATTRIBUTE_UNUSED,
1826 JValue* result) {
1827 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1828 ? 0
1829 : 1);
1830}
1831
Mathieu Chartiere401d142015-04-22 13:56:20 -07001832void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1833 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1834 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001835 StackHandleScope<1> hs(self);
1836 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1837}
1838
Andreas Gampebc4d2182016-02-22 10:03:12 -08001839void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1840 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1841 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1842 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1843 result->SetD(bit_cast<double>(long_input));
1844}
1845
Mathieu Chartiere401d142015-04-22 13:56:20 -07001846void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1847 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1848 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001849 result->SetI(args[0]);
1850}
1851
Mathieu Chartiere401d142015-04-22 13:56:20 -07001852void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1853 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1854 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001855 result->SetI(args[0]);
1856}
1857
Mathieu Chartiere401d142015-04-22 13:56:20 -07001858void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1859 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1860 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Vladimir Marko3068d582019-05-28 16:39:29 +01001861 StackHandleScope<1> hs(self);
1862 Handle<mirror::Object> h_receiver = hs.NewHandle(receiver);
1863 result->SetL(mirror::Object::Clone(h_receiver, self));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001864}
1865
Mathieu Chartiere401d142015-04-22 13:56:20 -07001866void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1867 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1868 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001869 receiver->NotifyAll(self);
1870}
1871
Vladimir Marko78baed52018-10-11 10:44:58 +01001872void UnstartedRuntime::UnstartedJNIStringCompareTo(Thread* self,
1873 ArtMethod* method ATTRIBUTE_UNUSED,
1874 mirror::Object* receiver,
1875 uint32_t* args,
1876 JValue* result) {
1877 ObjPtr<mirror::Object> rhs = reinterpret_cast32<mirror::Object*>(args[0]);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001878 if (rhs == nullptr) {
Vladimir Marko78baed52018-10-11 10:44:58 +01001879 AbortTransactionOrFail(self, "String.compareTo with null object.");
1880 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001881 }
Vladimir Marko78baed52018-10-11 10:44:58 +01001882 result->SetI(receiver->AsString()->CompareTo(rhs->AsString()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001883}
1884
Mathieu Chartiere401d142015-04-22 13:56:20 -07001885void UnstartedRuntime::UnstartedJNIStringIntern(
1886 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1887 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001888 result->SetL(receiver->AsString()->Intern());
1889}
1890
Mathieu Chartiere401d142015-04-22 13:56:20 -07001891void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1892 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1893 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001894 StackHandleScope<2> hs(self);
1895 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1896 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1897 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1898}
1899
Mathieu Chartiere401d142015-04-22 13:56:20 -07001900void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1901 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1902 uint32_t* args, JValue* result) {
Andreas Gampee598e042015-04-10 14:57:10 -07001903 int32_t length = static_cast<int32_t>(args[1]);
1904 if (length < 0) {
1905 ThrowNegativeArraySizeException(length);
1906 return;
1907 }
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001908 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
Andreas Gampee598e042015-04-10 14:57:10 -07001909 Runtime* runtime = Runtime::Current();
1910 ClassLinker* class_linker = runtime->GetClassLinker();
Vladimir Markobcf17522018-06-01 13:14:32 +01001911 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, element_class);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001912 if (UNLIKELY(array_class == nullptr)) {
Andreas Gampee598e042015-04-10 14:57:10 -07001913 CHECK(self->IsExceptionPending());
1914 return;
1915 }
1916 DCHECK(array_class->IsObjectArrayClass());
Vladimir Markobcf17522018-06-01 13:14:32 +01001917 ObjPtr<mirror::Array> new_array = mirror::ObjectArray<mirror::Object>::Alloc(
Andreas Gampee598e042015-04-10 14:57:10 -07001918 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1919 result->SetL(new_array);
1920}
1921
Mathieu Chartiere401d142015-04-22 13:56:20 -07001922void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1923 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1924 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001925 ScopedObjectAccessUnchecked soa(self);
Vladimir Markoec7b1942021-03-24 15:46:11 +00001926 ScopedLocalRef<jobject> stack_trace(self->GetJniEnv(), self->CreateInternalStackTrace(soa));
1927 result->SetL(soa.Decode<mirror::Object>(stack_trace.get()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001928}
1929
Mathieu Chartiere401d142015-04-22 13:56:20 -07001930void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
Vladimir Marko78baed52018-10-11 10:44:58 +01001931 Thread* self,
Sorin Basca2f01e8e2021-06-18 06:44:07 +00001932 ArtMethod* method,
1933 mirror::Object* receiver,
1934 uint32_t* args,
1935 JValue* result) {
1936 UnstartedJNIJdkUnsafeCompareAndSwapInt(self, method, receiver, args, result);
1937}
1938
1939void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(Thread* self,
1940 ArtMethod* method,
1941 mirror::Object* receiver,
1942 uint32_t* args,
1943 JValue* result) {
1944 UnstartedJNIJdkUnsafeGetIntVolatile(self, method, receiver, args, result);
1945}
1946
1947void UnstartedRuntime::UnstartedJNIUnsafePutObject(Thread* self,
1948 ArtMethod* method,
1949 mirror::Object* receiver,
1950 uint32_t* args,
1951 JValue* result) {
1952 UnstartedJNIJdkUnsafePutObject(self, method, receiver, args, result);
1953}
1954
1955void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
1956 Thread* self,
1957 ArtMethod* method,
1958 mirror::Object* receiver,
1959 uint32_t* args,
1960 JValue* result) {
1961 UnstartedJNIJdkUnsafeGetArrayBaseOffsetForComponentType(self, method, receiver, args, result);
1962}
1963
1964void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
1965 Thread* self,
1966 ArtMethod* method,
1967 mirror::Object* receiver,
1968 uint32_t* args,
1969 JValue* result) {
1970 UnstartedJNIJdkUnsafeGetArrayIndexScaleForComponentType(self, method, receiver, args, result);
1971}
1972
1973
1974void UnstartedRuntime::UnstartedJNIJdkUnsafeCompareAndSwapInt(
1975 Thread* self,
Vladimir Marko78baed52018-10-11 10:44:58 +01001976 ArtMethod* method ATTRIBUTE_UNUSED,
1977 mirror::Object* receiver ATTRIBUTE_UNUSED,
1978 uint32_t* args,
1979 JValue* result) {
1980 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1981 if (obj == nullptr) {
1982 AbortTransactionOrFail(self, "Unsafe.compareAndSwapInt with null object.");
1983 return;
1984 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001985 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1986 jint expectedValue = args[3];
1987 jint newValue = args[4];
1988 bool success;
1989 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001990 if (!CheckWriteConstraint(self, obj)) {
1991 DCHECK(self->IsExceptionPending());
1992 return;
1993 }
Mathieu Chartier42c2e502018-06-19 12:30:56 -07001994 success = obj->CasField32<true>(MemberOffset(offset),
1995 expectedValue,
1996 newValue,
1997 CASMode::kStrong,
1998 std::memory_order_seq_cst);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001999 } else {
Mathieu Chartier42c2e502018-06-19 12:30:56 -07002000 success = obj->CasField32<false>(MemberOffset(offset),
2001 expectedValue,
2002 newValue,
2003 CASMode::kStrong,
2004 std::memory_order_seq_cst);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002005 }
2006 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
2007}
2008
Sorin Basca2f01e8e2021-06-18 06:44:07 +00002009void UnstartedRuntime::UnstartedJNIJdkUnsafeGetIntVolatile(Thread* self,
Vladimir Marko78baed52018-10-11 10:44:58 +01002010 ArtMethod* method ATTRIBUTE_UNUSED,
2011 mirror::Object* receiver ATTRIBUTE_UNUSED,
2012 uint32_t* args,
2013 JValue* result) {
2014 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
Narayan Kamath34a316f2016-03-30 13:11:18 +01002015 if (obj == nullptr) {
Vladimir Marko78baed52018-10-11 10:44:58 +01002016 AbortTransactionOrFail(self, "Unsafe.compareAndSwapIntVolatile with null object.");
Narayan Kamath34a316f2016-03-30 13:11:18 +01002017 return;
2018 }
2019
2020 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
2021 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
2022}
2023
Sorin Basca2f01e8e2021-06-18 06:44:07 +00002024void UnstartedRuntime::UnstartedJNIJdkUnsafePutObject(Thread* self,
Vladimir Marko78baed52018-10-11 10:44:58 +01002025 ArtMethod* method ATTRIBUTE_UNUSED,
2026 mirror::Object* receiver ATTRIBUTE_UNUSED,
2027 uint32_t* args,
2028 JValue* result ATTRIBUTE_UNUSED) {
2029 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
2030 if (obj == nullptr) {
2031 AbortTransactionOrFail(self, "Unsafe.putObject with null object.");
2032 return;
2033 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002034 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
Vladimir Marko4d7b6892020-01-16 17:06:35 +00002035 ObjPtr<mirror::Object> new_value = reinterpret_cast32<mirror::Object*>(args[3]);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002036 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00002037 if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, new_value)) {
2038 DCHECK(self->IsExceptionPending());
2039 return;
2040 }
2041 obj->SetFieldObject<true>(MemberOffset(offset), new_value);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002042 } else {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00002043 obj->SetFieldObject<false>(MemberOffset(offset), new_value);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002044 }
2045}
2046
Sorin Basca2f01e8e2021-06-18 06:44:07 +00002047void UnstartedRuntime::UnstartedJNIJdkUnsafeGetArrayBaseOffsetForComponentType(
Vladimir Marko78baed52018-10-11 10:44:58 +01002048 Thread* self,
2049 ArtMethod* method ATTRIBUTE_UNUSED,
2050 mirror::Object* receiver ATTRIBUTE_UNUSED,
2051 uint32_t* args,
2052 JValue* result) {
2053 ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
2054 if (component == nullptr) {
2055 AbortTransactionOrFail(self, "Unsafe.getArrayBaseOffsetForComponentType with null component.");
2056 return;
2057 }
2058 Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002059 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
2060}
2061
Sorin Basca2f01e8e2021-06-18 06:44:07 +00002062void UnstartedRuntime::UnstartedJNIJdkUnsafeGetArrayIndexScaleForComponentType(
Vladimir Marko78baed52018-10-11 10:44:58 +01002063 Thread* self,
2064 ArtMethod* method ATTRIBUTE_UNUSED,
2065 mirror::Object* receiver ATTRIBUTE_UNUSED,
2066 uint32_t* args,
2067 JValue* result) {
2068 ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
2069 if (component == nullptr) {
2070 AbortTransactionOrFail(self, "Unsafe.getArrayIndexScaleForComponentType with null component.");
2071 return;
2072 }
2073 Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002074 result->SetI(Primitive::ComponentSize(primitive_type));
2075}
2076
Sorin Basca47349d22021-06-16 13:45:49 +00002077void UnstartedRuntime::UnstartedJNIFieldGetArtField(
2078 Thread* self ATTRIBUTE_UNUSED,
2079 ArtMethod* method ATTRIBUTE_UNUSED,
2080 mirror::Object* receiver,
2081 uint32_t* args ATTRIBUTE_UNUSED,
2082 JValue* result) {
2083 ObjPtr<mirror::Field> field = ObjPtr<mirror::Field>::DownCast(receiver);
2084 ArtField* art_field = field->GetArtField();
2085 result->SetJ(reinterpret_cast<int64_t>(art_field));
2086}
2087
2088void UnstartedRuntime::UnstartedJNIFieldGetNameInternal(
2089 Thread* self ATTRIBUTE_UNUSED,
2090 ArtMethod* method ATTRIBUTE_UNUSED,
2091 mirror::Object* receiver,
2092 uint32_t* args ATTRIBUTE_UNUSED,
2093 JValue* result) {
2094 ObjPtr<mirror::Field> field = ObjPtr<mirror::Field>::DownCast(receiver);
2095 ArtField* art_field = field->GetArtField();
2096 result->SetL(art_field->ResolveNameString());
2097}
2098
Andreas Gampec55bb392018-09-21 00:02:02 +00002099using InvokeHandler = void(*)(Thread* self,
2100 ShadowFrame* shadow_frame,
2101 JValue* result,
2102 size_t arg_size);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002103
Andreas Gampec55bb392018-09-21 00:02:02 +00002104using JNIHandler = void(*)(Thread* self,
2105 ArtMethod* method,
2106 mirror::Object* receiver,
2107 uint32_t* args,
2108 JValue* result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002109
Vladimir Marko83881482021-01-07 10:59:54 +00002110#define ONE_PLUS(ShortNameIgnored, DescriptorIgnored, NameIgnored, SignatureIgnored) 1 +
2111static constexpr size_t kInvokeHandlersSize = UNSTARTED_RUNTIME_DIRECT_LIST(ONE_PLUS) 0;
2112static constexpr size_t kJniHandlersSize = UNSTARTED_RUNTIME_JNI_LIST(ONE_PLUS) 0;
2113#undef ONE_PLUS
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002114
Vladimir Marko83881482021-01-07 10:59:54 +00002115// The actual value of `kMinLoadFactor` is irrelevant because the HashMap<>s below
2116// are never resized, but we still need to pass a reasonable value to the constructor.
2117static constexpr double kMinLoadFactor = 0.5;
2118static constexpr double kMaxLoadFactor = 0.7;
2119
2120constexpr size_t BufferSize(size_t size) {
2121 // Note: ceil() is not suitable for constexpr, so cast to size_t and adjust by 1 if needed.
2122 const size_t estimate = static_cast<size_t>(size / kMaxLoadFactor);
2123 return static_cast<size_t>(estimate * kMaxLoadFactor) == size ? estimate : estimate + 1u;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002124}
2125
Vladimir Marko83881482021-01-07 10:59:54 +00002126static constexpr size_t kInvokeHandlersBufferSize = BufferSize(kInvokeHandlersSize);
2127static_assert(
2128 static_cast<size_t>(kInvokeHandlersBufferSize * kMaxLoadFactor) == kInvokeHandlersSize);
2129static constexpr size_t kJniHandlersBufferSize = BufferSize(kJniHandlersSize);
2130static_assert(static_cast<size_t>(kJniHandlersBufferSize * kMaxLoadFactor) == kJniHandlersSize);
2131
2132static bool tables_initialized_ = false;
2133static std::pair<ArtMethod*, InvokeHandler> kInvokeHandlersBuffer[kInvokeHandlersBufferSize];
2134static HashMap<ArtMethod*, InvokeHandler> invoke_handlers_(
2135 kMinLoadFactor, kMaxLoadFactor, kInvokeHandlersBuffer, kInvokeHandlersBufferSize);
2136static std::pair<ArtMethod*, JNIHandler> kJniHandlersBuffer[kJniHandlersBufferSize];
2137static HashMap<ArtMethod*, JNIHandler> jni_handlers_(
2138 kMinLoadFactor, kMaxLoadFactor, kJniHandlersBuffer, kJniHandlersBufferSize);
2139
2140static ArtMethod* FindMethod(Thread* self,
2141 ClassLinker* class_linker,
2142 const char* descriptor,
2143 std::string_view name,
2144 std::string_view signature) REQUIRES_SHARED(Locks::mutator_lock_) {
2145 ObjPtr<mirror::Class> klass = class_linker->FindSystemClass(self, descriptor);
2146 DCHECK(klass != nullptr) << descriptor;
2147 ArtMethod* method = klass->FindClassMethod(name, signature, class_linker->GetImagePointerSize());
2148 DCHECK(method != nullptr) << descriptor << "." << name << signature;
2149 return method;
2150}
2151
2152void UnstartedRuntime::InitializeInvokeHandlers(Thread* self) {
2153 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2154#define UNSTARTED_DIRECT(ShortName, Descriptor, Name, Signature) \
2155 { \
2156 ArtMethod* method = FindMethod(self, class_linker, Descriptor, Name, Signature); \
2157 invoke_handlers_.insert(std::make_pair(method, & UnstartedRuntime::Unstarted ## ShortName)); \
2158 }
2159 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
2160#undef UNSTARTED_DIRECT
2161 DCHECK_EQ(invoke_handlers_.NumBuckets(), kInvokeHandlersBufferSize);
2162}
2163
2164void UnstartedRuntime::InitializeJNIHandlers(Thread* self) {
2165 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2166#define UNSTARTED_JNI(ShortName, Descriptor, Name, Signature) \
2167 { \
2168 ArtMethod* method = FindMethod(self, class_linker, Descriptor, Name, Signature); \
2169 jni_handlers_.insert(std::make_pair(method, & UnstartedRuntime::UnstartedJNI ## ShortName)); \
2170 }
Andreas Gampe799681b2015-05-15 19:24:12 -07002171 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
Andreas Gampe799681b2015-05-15 19:24:12 -07002172#undef UNSTARTED_JNI
Vladimir Marko83881482021-01-07 10:59:54 +00002173 DCHECK_EQ(jni_handlers_.NumBuckets(), kJniHandlersBufferSize);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002174}
2175
Andreas Gampe799681b2015-05-15 19:24:12 -07002176void UnstartedRuntime::Initialize() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002177 CHECK(!tables_initialized_);
2178
Vladimir Marko83881482021-01-07 10:59:54 +00002179 ScopedObjectAccess soa(Thread::Current());
2180 InitializeInvokeHandlers(soa.Self());
2181 InitializeJNIHandlers(soa.Self());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002182
2183 tables_initialized_ = true;
2184}
2185
Vladimir Marko83881482021-01-07 10:59:54 +00002186void UnstartedRuntime::Reinitialize() {
2187 CHECK(tables_initialized_);
2188
2189 // Note: HashSet::clear() abandons the pre-allocated storage which we need to keep.
2190 while (!invoke_handlers_.empty()) {
2191 invoke_handlers_.erase(invoke_handlers_.begin());
2192 }
2193 while (!jni_handlers_.empty()) {
2194 jni_handlers_.erase(jni_handlers_.begin());
2195 }
2196
2197 tables_initialized_ = false;
2198 Initialize();
2199}
2200
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002201void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
Andreas Gampe799681b2015-05-15 19:24:12 -07002202 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002203 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
2204 // problems in core libraries.
2205 CHECK(tables_initialized_);
2206
Vladimir Marko83881482021-01-07 10:59:54 +00002207 const auto& iter = invoke_handlers_.find(shadow_frame->GetMethod());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002208 if (iter != invoke_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07002209 // Clear out the result in case it's not zeroed out.
Yi Kong4b22b342018-08-02 14:43:21 -07002210 result->SetL(nullptr);
Andreas Gampe715fdc22016-04-18 17:07:30 -07002211
2212 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
2213 self->PushShadowFrame(shadow_frame);
2214
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002215 (*iter->second)(self, shadow_frame, result, arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07002216
2217 self->PopShadowFrame();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002218 } else {
2219 // Not special, continue with regular interpreter execution.
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002220 ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002221 }
2222}
2223
2224// Hand select a number of methods to be run in a not yet started runtime without using JNI.
Mathieu Chartiere401d142015-04-22 13:56:20 -07002225void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe799681b2015-05-15 19:24:12 -07002226 uint32_t* args, JValue* result) {
Vladimir Marko83881482021-01-07 10:59:54 +00002227 const auto& iter = jni_handlers_.find(method);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002228 if (iter != jni_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07002229 // Clear out the result in case it's not zeroed out.
Yi Kong4b22b342018-08-02 14:43:21 -07002230 result->SetL(nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002231 (*iter->second)(self, method, receiver, args, result);
2232 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02002233 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
Vladimir Marko83881482021-01-07 10:59:54 +00002234 ArtMethod::PrettyMethod(method).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002235 } else {
David Sehr709b0702016-10-13 09:12:37 -07002236 LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002237 "non-transactional runtime";
2238 }
2239}
2240
2241} // namespace interpreter
2242} // namespace art