blob: 831c1ddafc092ac6ca422a46bc368cbd47902ef0 [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) {
1067 if (CheckCallers(shadow_frame, { "sun.misc.FloatingDecimal$BinaryToASCIIBuffer "
1068 "sun.misc.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1069 result->SetL(CreateInstanceOf(self, "Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;"));
1070 } 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,
1080 { "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
Paul Duffin7ec95c52018-08-01 15:09:37 +01001081 "java.lang.String, long, java.security.AccessControlContext)",
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)" })) {
1087 // Whitelist LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
1088 // 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()",
1116 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
Paul Duffin7ec95c52018-08-01 15:09:37 +01001117 "java.lang.String, long, java.security.AccessControlContext)",
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)" })) {
1123 // Whitelist reading the state of the "main" thread when creating another (unstarted) thread
1124 // 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) {
1458 // Argument 0 is the Unsafe instance, skip.
1459 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1460 if (obj == nullptr) {
1461 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1462 return;
1463 }
1464 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1465 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1466 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001467 bool success;
1468 // Check whether we're in a transaction, call accordingly.
1469 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001470 if (!CheckWriteConstraint(self, obj)) {
1471 DCHECK(self->IsExceptionPending());
1472 return;
1473 }
Andreas Gampebc4d2182016-02-22 10:03:12 -08001474 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1475 expectedValue,
1476 newValue);
1477 } else {
1478 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1479 expectedValue,
1480 newValue);
1481 }
1482 result->SetZ(success ? 1 : 0);
1483}
1484
1485void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1486 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1487 // Argument 0 is the Unsafe instance, skip.
1488 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1489 if (obj == nullptr) {
1490 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1491 return;
1492 }
1493 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1494 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001495 mirror::Object* new_value = shadow_frame->GetVRegReference(arg_offset + 5);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001496
1497 // Must use non transactional mode.
1498 if (kUseReadBarrier) {
1499 // Need to make sure the reference stored in the field is a to-space one before attempting the
1500 // CAS or the CAS could fail incorrectly.
1501 mirror::HeapReference<mirror::Object>* field_addr =
1502 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1503 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001504 ReadBarrier::Barrier<
1505 mirror::Object,
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001506 /* kIsVolatile= */ false,
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001507 kWithReadBarrier,
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001508 /* kAlwaysUpdateField= */ true>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001509 obj,
1510 MemberOffset(offset),
1511 field_addr);
1512 }
1513 bool success;
1514 // Check whether we're in a transaction, call accordingly.
1515 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001516 if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, new_value)) {
1517 DCHECK(self->IsExceptionPending());
1518 return;
1519 }
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001520 success = obj->CasFieldObject<true>(MemberOffset(offset),
1521 expected_value,
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001522 new_value,
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001523 CASMode::kStrong,
1524 std::memory_order_seq_cst);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001525 } else {
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001526 success = obj->CasFieldObject<false>(MemberOffset(offset),
1527 expected_value,
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001528 new_value,
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001529 CASMode::kStrong,
1530 std::memory_order_seq_cst);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001531 }
1532 result->SetZ(success ? 1 : 0);
1533}
1534
1535void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1536 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001537 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001538 // Argument 0 is the Unsafe instance, skip.
1539 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1540 if (obj == nullptr) {
1541 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1542 return;
1543 }
1544 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
Vladimir Markodfc0de72019-04-01 10:57:55 +01001545 ObjPtr<mirror::Object> value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
Andreas Gampebc4d2182016-02-22 10:03:12 -08001546 result->SetL(value);
1547}
1548
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001549void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1550 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001551 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001552 // Argument 0 is the Unsafe instance, skip.
1553 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1554 if (obj == nullptr) {
1555 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1556 return;
1557 }
1558 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1559 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1560 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001561 if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, value)) {
1562 DCHECK(self->IsExceptionPending());
1563 return;
1564 }
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001565 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1566 } else {
1567 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1568 }
1569}
1570
Andreas Gampebc4d2182016-02-22 10:03:12 -08001571void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1572 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001573 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001574 // Argument 0 is the Unsafe instance, skip.
1575 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1576 if (obj == nullptr) {
1577 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1578 return;
1579 }
1580 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001581 mirror::Object* new_value = shadow_frame->GetVRegReference(arg_offset + 4);
Orion Hodson27b96762018-03-13 16:06:57 +00001582 std::atomic_thread_fence(std::memory_order_release);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001583 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001584 if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, new_value)) {
1585 DCHECK(self->IsExceptionPending());
1586 return;
1587 }
1588 obj->SetFieldObject<true>(MemberOffset(offset), new_value);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001589 } else {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001590 obj->SetFieldObject<false>(MemberOffset(offset), new_value);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001591 }
1592}
1593
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001594// A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1595// of correctly handling the corner cases.
1596void UnstartedRuntime::UnstartedIntegerParseInt(
1597 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001598 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001599 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1600 if (obj == nullptr) {
1601 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1602 return;
1603 }
1604
1605 std::string string_value = obj->AsString()->ToModifiedUtf8();
1606 if (string_value.empty()) {
1607 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1608 return;
1609 }
1610
1611 const char* c_str = string_value.c_str();
1612 char *end;
1613 // Can we set errno to 0? Is this always a variable, and not a macro?
1614 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1615 int64_t l = strtol(c_str, &end, 10);
1616
1617 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1618 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1619 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1620 return;
1621 }
1622 if (l == 0) {
1623 // Check whether the string wasn't exactly zero.
1624 if (string_value != "0") {
1625 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1626 return;
1627 }
1628 } else if (*end != '\0') {
1629 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1630 return;
1631 }
1632
1633 result->SetI(static_cast<int32_t>(l));
1634}
1635
1636// A cutout for Long.parseLong.
1637//
1638// Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1639// well.
1640void UnstartedRuntime::UnstartedLongParseLong(
1641 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001642 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001643 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1644 if (obj == nullptr) {
1645 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1646 return;
1647 }
1648
1649 std::string string_value = obj->AsString()->ToModifiedUtf8();
1650 if (string_value.empty()) {
1651 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1652 return;
1653 }
1654
1655 const char* c_str = string_value.c_str();
1656 char *end;
1657 // Can we set errno to 0? Is this always a variable, and not a macro?
1658 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1659 int64_t l = strtol(c_str, &end, 10);
1660
1661 // Note: comparing against int32_t min/max is intentional here.
1662 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1663 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1664 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1665 return;
1666 }
1667 if (l == 0) {
1668 // Check whether the string wasn't exactly zero.
1669 if (string_value != "0") {
1670 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1671 return;
1672 }
1673 } else if (*end != '\0') {
1674 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1675 return;
1676 }
1677
1678 result->SetJ(l);
1679}
1680
Andreas Gampe715fdc22016-04-18 17:07:30 -07001681void UnstartedRuntime::UnstartedMethodInvoke(
1682 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001683 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe715fdc22016-04-18 17:07:30 -07001684 JNIEnvExt* env = self->GetJniEnv();
1685 ScopedObjectAccessUnchecked soa(self);
1686
Mathieu Chartier8778c522016-10-04 19:06:30 -07001687 ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001688 ScopedLocalRef<jobject> java_method(env,
Roland Levillain5e8d5f02016-10-18 18:03:43 +01001689 java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001690
Mathieu Chartier8778c522016-10-04 19:06:30 -07001691 ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001692 ScopedLocalRef<jobject> java_receiver(env,
1693 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1694
Mathieu Chartier8778c522016-10-04 19:06:30 -07001695 ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001696 ScopedLocalRef<jobject> java_args(env,
1697 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1698
liulvpingfff1d8f2020-12-21 09:43:37 +08001699 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Andreas Gampe715fdc22016-04-18 17:07:30 -07001700 ScopedLocalRef<jobject> result_jobj(env,
liulvpingfff1d8f2020-12-21 09:43:37 +08001701 (pointer_size == PointerSize::k64)
1702 ? InvokeMethod<PointerSize::k64>(soa,
1703 java_method.get(),
1704 java_receiver.get(),
1705 java_args.get())
1706 : InvokeMethod<PointerSize::k32>(soa,
1707 java_method.get(),
1708 java_receiver.get(),
1709 java_args.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001710
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001711 result->SetL(self->DecodeJObject(result_jobj.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001712
1713 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1714 // InvocationTargetExceptions.
1715 if (self->IsExceptionPending()) {
1716 AbortTransactionOrFail(self, "Failed Method.invoke");
1717 }
1718}
1719
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001720void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1721 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1722 REQUIRES_SHARED(Locks::mutator_lock_) {
1723 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1724 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1725}
Andreas Gampebc4d2182016-02-22 10:03:12 -08001726
Orion Hodson43f0cdb2017-10-10 14:47:32 +01001727// Checks whether the runtime is s64-bit. This is needed for the clinit of
1728// java.lang.invoke.VarHandle clinit. The clinit determines sets of
1729// available VarHandle accessors and these differ based on machine
1730// word size.
1731void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1732 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1733 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1734 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1735 jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1736 result->SetZ(is64bit);
1737}
1738
Mathieu Chartiere401d142015-04-22 13:56:20 -07001739void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
Vladimir Marko78baed52018-10-11 10:44:58 +01001740 Thread* self,
1741 ArtMethod* method ATTRIBUTE_UNUSED,
1742 mirror::Object* receiver ATTRIBUTE_UNUSED,
1743 uint32_t* args,
1744 JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001745 int32_t length = args[1];
1746 DCHECK_GE(length, 0);
Vladimir Marko78baed52018-10-11 10:44:58 +01001747 ObjPtr<mirror::Object> element_class = reinterpret_cast32<mirror::Object*>(args[0])->AsClass();
1748 if (element_class == nullptr) {
1749 AbortTransactionOrFail(self, "VMRuntime.newUnpaddedArray with null element_class.");
1750 return;
1751 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001752 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001753 ObjPtr<mirror::Class> array_class =
Vladimir Marko78baed52018-10-11 10:44:58 +01001754 runtime->GetClassLinker()->FindArrayClass(self, element_class->AsClass());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001755 DCHECK(array_class != nullptr);
1756 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Vladimir Marko9b81ac32019-05-16 16:47:08 +01001757 result->SetL(mirror::Array::Alloc</*kIsInstrumented=*/ true, /*kFillUsable=*/ true>(
1758 self, array_class, length, array_class->GetComponentSizeShift(), allocator));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001759}
1760
Mathieu Chartiere401d142015-04-22 13:56:20 -07001761void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1762 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1763 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001764 result->SetL(nullptr);
1765}
1766
Mathieu Chartiere401d142015-04-22 13:56:20 -07001767void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1768 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1769 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001770 NthCallerVisitor visitor(self, 3);
1771 visitor.WalkStack();
1772 if (visitor.caller != nullptr) {
1773 result->SetL(visitor.caller->GetDeclaringClass());
1774 }
1775}
1776
Mathieu Chartiere401d142015-04-22 13:56:20 -07001777void UnstartedRuntime::UnstartedJNIMathLog(
1778 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1779 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001780 JValue value;
1781 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1782 result->SetD(log(value.GetD()));
1783}
1784
Mathieu Chartiere401d142015-04-22 13:56:20 -07001785void UnstartedRuntime::UnstartedJNIMathExp(
1786 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1787 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001788 JValue value;
1789 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1790 result->SetD(exp(value.GetD()));
1791}
1792
Andreas Gampebc4d2182016-02-22 10:03:12 -08001793void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1794 Thread* self ATTRIBUTE_UNUSED,
1795 ArtMethod* method ATTRIBUTE_UNUSED,
1796 mirror::Object* receiver ATTRIBUTE_UNUSED,
1797 uint32_t* args ATTRIBUTE_UNUSED,
1798 JValue* result) {
1799 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1800 ? 0
1801 : 1);
1802}
1803
Mathieu Chartiere401d142015-04-22 13:56:20 -07001804void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1805 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1806 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001807 StackHandleScope<1> hs(self);
1808 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1809}
1810
Andreas Gampebc4d2182016-02-22 10:03:12 -08001811void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1812 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1813 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1814 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1815 result->SetD(bit_cast<double>(long_input));
1816}
1817
Mathieu Chartiere401d142015-04-22 13:56:20 -07001818void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1819 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1820 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001821 result->SetI(args[0]);
1822}
1823
Mathieu Chartiere401d142015-04-22 13:56:20 -07001824void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1825 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1826 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001827 result->SetI(args[0]);
1828}
1829
Mathieu Chartiere401d142015-04-22 13:56:20 -07001830void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1831 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1832 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Vladimir Marko3068d582019-05-28 16:39:29 +01001833 StackHandleScope<1> hs(self);
1834 Handle<mirror::Object> h_receiver = hs.NewHandle(receiver);
1835 result->SetL(mirror::Object::Clone(h_receiver, self));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001836}
1837
Mathieu Chartiere401d142015-04-22 13:56:20 -07001838void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1839 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1840 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001841 receiver->NotifyAll(self);
1842}
1843
Vladimir Marko78baed52018-10-11 10:44:58 +01001844void UnstartedRuntime::UnstartedJNIStringCompareTo(Thread* self,
1845 ArtMethod* method ATTRIBUTE_UNUSED,
1846 mirror::Object* receiver,
1847 uint32_t* args,
1848 JValue* result) {
1849 ObjPtr<mirror::Object> rhs = reinterpret_cast32<mirror::Object*>(args[0]);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001850 if (rhs == nullptr) {
Vladimir Marko78baed52018-10-11 10:44:58 +01001851 AbortTransactionOrFail(self, "String.compareTo with null object.");
1852 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001853 }
Vladimir Marko78baed52018-10-11 10:44:58 +01001854 result->SetI(receiver->AsString()->CompareTo(rhs->AsString()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001855}
1856
Mathieu Chartiere401d142015-04-22 13:56:20 -07001857void UnstartedRuntime::UnstartedJNIStringIntern(
1858 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1859 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001860 result->SetL(receiver->AsString()->Intern());
1861}
1862
Mathieu Chartiere401d142015-04-22 13:56:20 -07001863void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1864 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1865 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001866 StackHandleScope<2> hs(self);
1867 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1868 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1869 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1870}
1871
Mathieu Chartiere401d142015-04-22 13:56:20 -07001872void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1873 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1874 uint32_t* args, JValue* result) {
Andreas Gampee598e042015-04-10 14:57:10 -07001875 int32_t length = static_cast<int32_t>(args[1]);
1876 if (length < 0) {
1877 ThrowNegativeArraySizeException(length);
1878 return;
1879 }
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001880 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
Andreas Gampee598e042015-04-10 14:57:10 -07001881 Runtime* runtime = Runtime::Current();
1882 ClassLinker* class_linker = runtime->GetClassLinker();
Vladimir Markobcf17522018-06-01 13:14:32 +01001883 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, element_class);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001884 if (UNLIKELY(array_class == nullptr)) {
Andreas Gampee598e042015-04-10 14:57:10 -07001885 CHECK(self->IsExceptionPending());
1886 return;
1887 }
1888 DCHECK(array_class->IsObjectArrayClass());
Vladimir Markobcf17522018-06-01 13:14:32 +01001889 ObjPtr<mirror::Array> new_array = mirror::ObjectArray<mirror::Object>::Alloc(
Andreas Gampee598e042015-04-10 14:57:10 -07001890 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1891 result->SetL(new_array);
1892}
1893
Mathieu Chartiere401d142015-04-22 13:56:20 -07001894void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1895 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1896 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001897 ScopedObjectAccessUnchecked soa(self);
Vladimir Markoec7b1942021-03-24 15:46:11 +00001898 ScopedLocalRef<jobject> stack_trace(self->GetJniEnv(), self->CreateInternalStackTrace(soa));
1899 result->SetL(soa.Decode<mirror::Object>(stack_trace.get()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001900}
1901
Mathieu Chartiere401d142015-04-22 13:56:20 -07001902void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
Vladimir Marko78baed52018-10-11 10:44:58 +01001903 Thread* self,
1904 ArtMethod* method ATTRIBUTE_UNUSED,
1905 mirror::Object* receiver ATTRIBUTE_UNUSED,
1906 uint32_t* args,
1907 JValue* result) {
1908 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1909 if (obj == nullptr) {
1910 AbortTransactionOrFail(self, "Unsafe.compareAndSwapInt with null object.");
1911 return;
1912 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001913 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1914 jint expectedValue = args[3];
1915 jint newValue = args[4];
1916 bool success;
1917 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001918 if (!CheckWriteConstraint(self, obj)) {
1919 DCHECK(self->IsExceptionPending());
1920 return;
1921 }
Mathieu Chartier42c2e502018-06-19 12:30:56 -07001922 success = obj->CasField32<true>(MemberOffset(offset),
1923 expectedValue,
1924 newValue,
1925 CASMode::kStrong,
1926 std::memory_order_seq_cst);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001927 } else {
Mathieu Chartier42c2e502018-06-19 12:30:56 -07001928 success = obj->CasField32<false>(MemberOffset(offset),
1929 expectedValue,
1930 newValue,
1931 CASMode::kStrong,
1932 std::memory_order_seq_cst);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001933 }
1934 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1935}
1936
Vladimir Marko78baed52018-10-11 10:44:58 +01001937void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(Thread* self,
1938 ArtMethod* method ATTRIBUTE_UNUSED,
1939 mirror::Object* receiver ATTRIBUTE_UNUSED,
1940 uint32_t* args,
1941 JValue* result) {
1942 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
Narayan Kamath34a316f2016-03-30 13:11:18 +01001943 if (obj == nullptr) {
Vladimir Marko78baed52018-10-11 10:44:58 +01001944 AbortTransactionOrFail(self, "Unsafe.compareAndSwapIntVolatile with null object.");
Narayan Kamath34a316f2016-03-30 13:11:18 +01001945 return;
1946 }
1947
1948 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1949 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1950}
1951
Vladimir Marko78baed52018-10-11 10:44:58 +01001952void UnstartedRuntime::UnstartedJNIUnsafePutObject(Thread* self,
1953 ArtMethod* method ATTRIBUTE_UNUSED,
1954 mirror::Object* receiver ATTRIBUTE_UNUSED,
1955 uint32_t* args,
1956 JValue* result ATTRIBUTE_UNUSED) {
1957 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1958 if (obj == nullptr) {
1959 AbortTransactionOrFail(self, "Unsafe.putObject with null object.");
1960 return;
1961 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001962 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001963 ObjPtr<mirror::Object> new_value = reinterpret_cast32<mirror::Object*>(args[3]);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001964 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001965 if (!CheckWriteConstraint(self, obj) || !CheckWriteValueConstraint(self, new_value)) {
1966 DCHECK(self->IsExceptionPending());
1967 return;
1968 }
1969 obj->SetFieldObject<true>(MemberOffset(offset), new_value);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001970 } else {
Vladimir Marko4d7b6892020-01-16 17:06:35 +00001971 obj->SetFieldObject<false>(MemberOffset(offset), new_value);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001972 }
1973}
1974
Andreas Gampe799681b2015-05-15 19:24:12 -07001975void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
Vladimir Marko78baed52018-10-11 10:44:58 +01001976 Thread* self,
1977 ArtMethod* method ATTRIBUTE_UNUSED,
1978 mirror::Object* receiver ATTRIBUTE_UNUSED,
1979 uint32_t* args,
1980 JValue* result) {
1981 ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
1982 if (component == nullptr) {
1983 AbortTransactionOrFail(self, "Unsafe.getArrayBaseOffsetForComponentType with null component.");
1984 return;
1985 }
1986 Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001987 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1988}
1989
Andreas Gampe799681b2015-05-15 19:24:12 -07001990void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
Vladimir Marko78baed52018-10-11 10:44:58 +01001991 Thread* self,
1992 ArtMethod* method ATTRIBUTE_UNUSED,
1993 mirror::Object* receiver ATTRIBUTE_UNUSED,
1994 uint32_t* args,
1995 JValue* result) {
1996 ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
1997 if (component == nullptr) {
1998 AbortTransactionOrFail(self, "Unsafe.getArrayIndexScaleForComponentType with null component.");
1999 return;
2000 }
2001 Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002002 result->SetI(Primitive::ComponentSize(primitive_type));
2003}
2004
Sorin Basca47349d22021-06-16 13:45:49 +00002005void UnstartedRuntime::UnstartedJNIFieldGetArtField(
2006 Thread* self ATTRIBUTE_UNUSED,
2007 ArtMethod* method ATTRIBUTE_UNUSED,
2008 mirror::Object* receiver,
2009 uint32_t* args ATTRIBUTE_UNUSED,
2010 JValue* result) {
2011 ObjPtr<mirror::Field> field = ObjPtr<mirror::Field>::DownCast(receiver);
2012 ArtField* art_field = field->GetArtField();
2013 result->SetJ(reinterpret_cast<int64_t>(art_field));
2014}
2015
2016void UnstartedRuntime::UnstartedJNIFieldGetNameInternal(
2017 Thread* self ATTRIBUTE_UNUSED,
2018 ArtMethod* method ATTRIBUTE_UNUSED,
2019 mirror::Object* receiver,
2020 uint32_t* args ATTRIBUTE_UNUSED,
2021 JValue* result) {
2022 ObjPtr<mirror::Field> field = ObjPtr<mirror::Field>::DownCast(receiver);
2023 ArtField* art_field = field->GetArtField();
2024 result->SetL(art_field->ResolveNameString());
2025}
2026
Andreas Gampec55bb392018-09-21 00:02:02 +00002027using InvokeHandler = void(*)(Thread* self,
2028 ShadowFrame* shadow_frame,
2029 JValue* result,
2030 size_t arg_size);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002031
Andreas Gampec55bb392018-09-21 00:02:02 +00002032using JNIHandler = void(*)(Thread* self,
2033 ArtMethod* method,
2034 mirror::Object* receiver,
2035 uint32_t* args,
2036 JValue* result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002037
Vladimir Marko83881482021-01-07 10:59:54 +00002038#define ONE_PLUS(ShortNameIgnored, DescriptorIgnored, NameIgnored, SignatureIgnored) 1 +
2039static constexpr size_t kInvokeHandlersSize = UNSTARTED_RUNTIME_DIRECT_LIST(ONE_PLUS) 0;
2040static constexpr size_t kJniHandlersSize = UNSTARTED_RUNTIME_JNI_LIST(ONE_PLUS) 0;
2041#undef ONE_PLUS
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002042
Vladimir Marko83881482021-01-07 10:59:54 +00002043// The actual value of `kMinLoadFactor` is irrelevant because the HashMap<>s below
2044// are never resized, but we still need to pass a reasonable value to the constructor.
2045static constexpr double kMinLoadFactor = 0.5;
2046static constexpr double kMaxLoadFactor = 0.7;
2047
2048constexpr size_t BufferSize(size_t size) {
2049 // Note: ceil() is not suitable for constexpr, so cast to size_t and adjust by 1 if needed.
2050 const size_t estimate = static_cast<size_t>(size / kMaxLoadFactor);
2051 return static_cast<size_t>(estimate * kMaxLoadFactor) == size ? estimate : estimate + 1u;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002052}
2053
Vladimir Marko83881482021-01-07 10:59:54 +00002054static constexpr size_t kInvokeHandlersBufferSize = BufferSize(kInvokeHandlersSize);
2055static_assert(
2056 static_cast<size_t>(kInvokeHandlersBufferSize * kMaxLoadFactor) == kInvokeHandlersSize);
2057static constexpr size_t kJniHandlersBufferSize = BufferSize(kJniHandlersSize);
2058static_assert(static_cast<size_t>(kJniHandlersBufferSize * kMaxLoadFactor) == kJniHandlersSize);
2059
2060static bool tables_initialized_ = false;
2061static std::pair<ArtMethod*, InvokeHandler> kInvokeHandlersBuffer[kInvokeHandlersBufferSize];
2062static HashMap<ArtMethod*, InvokeHandler> invoke_handlers_(
2063 kMinLoadFactor, kMaxLoadFactor, kInvokeHandlersBuffer, kInvokeHandlersBufferSize);
2064static std::pair<ArtMethod*, JNIHandler> kJniHandlersBuffer[kJniHandlersBufferSize];
2065static HashMap<ArtMethod*, JNIHandler> jni_handlers_(
2066 kMinLoadFactor, kMaxLoadFactor, kJniHandlersBuffer, kJniHandlersBufferSize);
2067
2068static ArtMethod* FindMethod(Thread* self,
2069 ClassLinker* class_linker,
2070 const char* descriptor,
2071 std::string_view name,
2072 std::string_view signature) REQUIRES_SHARED(Locks::mutator_lock_) {
2073 ObjPtr<mirror::Class> klass = class_linker->FindSystemClass(self, descriptor);
2074 DCHECK(klass != nullptr) << descriptor;
2075 ArtMethod* method = klass->FindClassMethod(name, signature, class_linker->GetImagePointerSize());
2076 DCHECK(method != nullptr) << descriptor << "." << name << signature;
2077 return method;
2078}
2079
2080void UnstartedRuntime::InitializeInvokeHandlers(Thread* self) {
2081 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2082#define UNSTARTED_DIRECT(ShortName, Descriptor, Name, Signature) \
2083 { \
2084 ArtMethod* method = FindMethod(self, class_linker, Descriptor, Name, Signature); \
2085 invoke_handlers_.insert(std::make_pair(method, & UnstartedRuntime::Unstarted ## ShortName)); \
2086 }
2087 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
2088#undef UNSTARTED_DIRECT
2089 DCHECK_EQ(invoke_handlers_.NumBuckets(), kInvokeHandlersBufferSize);
2090}
2091
2092void UnstartedRuntime::InitializeJNIHandlers(Thread* self) {
2093 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2094#define UNSTARTED_JNI(ShortName, Descriptor, Name, Signature) \
2095 { \
2096 ArtMethod* method = FindMethod(self, class_linker, Descriptor, Name, Signature); \
2097 jni_handlers_.insert(std::make_pair(method, & UnstartedRuntime::UnstartedJNI ## ShortName)); \
2098 }
Andreas Gampe799681b2015-05-15 19:24:12 -07002099 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
Andreas Gampe799681b2015-05-15 19:24:12 -07002100#undef UNSTARTED_JNI
Vladimir Marko83881482021-01-07 10:59:54 +00002101 DCHECK_EQ(jni_handlers_.NumBuckets(), kJniHandlersBufferSize);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002102}
2103
Andreas Gampe799681b2015-05-15 19:24:12 -07002104void UnstartedRuntime::Initialize() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002105 CHECK(!tables_initialized_);
2106
Vladimir Marko83881482021-01-07 10:59:54 +00002107 ScopedObjectAccess soa(Thread::Current());
2108 InitializeInvokeHandlers(soa.Self());
2109 InitializeJNIHandlers(soa.Self());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002110
2111 tables_initialized_ = true;
2112}
2113
Vladimir Marko83881482021-01-07 10:59:54 +00002114void UnstartedRuntime::Reinitialize() {
2115 CHECK(tables_initialized_);
2116
2117 // Note: HashSet::clear() abandons the pre-allocated storage which we need to keep.
2118 while (!invoke_handlers_.empty()) {
2119 invoke_handlers_.erase(invoke_handlers_.begin());
2120 }
2121 while (!jni_handlers_.empty()) {
2122 jni_handlers_.erase(jni_handlers_.begin());
2123 }
2124
2125 tables_initialized_ = false;
2126 Initialize();
2127}
2128
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002129void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
Andreas Gampe799681b2015-05-15 19:24:12 -07002130 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002131 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
2132 // problems in core libraries.
2133 CHECK(tables_initialized_);
2134
Vladimir Marko83881482021-01-07 10:59:54 +00002135 const auto& iter = invoke_handlers_.find(shadow_frame->GetMethod());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002136 if (iter != invoke_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07002137 // Clear out the result in case it's not zeroed out.
Yi Kong4b22b342018-08-02 14:43:21 -07002138 result->SetL(nullptr);
Andreas Gampe715fdc22016-04-18 17:07:30 -07002139
2140 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
2141 self->PushShadowFrame(shadow_frame);
2142
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002143 (*iter->second)(self, shadow_frame, result, arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07002144
2145 self->PopShadowFrame();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002146 } else {
2147 // Not special, continue with regular interpreter execution.
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002148 ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002149 }
2150}
2151
2152// 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 -07002153void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe799681b2015-05-15 19:24:12 -07002154 uint32_t* args, JValue* result) {
Vladimir Marko83881482021-01-07 10:59:54 +00002155 const auto& iter = jni_handlers_.find(method);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002156 if (iter != jni_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07002157 // Clear out the result in case it's not zeroed out.
Yi Kong4b22b342018-08-02 14:43:21 -07002158 result->SetL(nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002159 (*iter->second)(self, method, receiver, args, result);
2160 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02002161 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
Vladimir Marko83881482021-01-07 10:59:54 +00002162 ArtMethod::PrettyMethod(method).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002163 } else {
David Sehr709b0702016-10-13 09:12:37 -07002164 LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002165 "non-transactional runtime";
2166 }
2167}
2168
2169} // namespace interpreter
2170} // namespace art