blob: 0568bfc8702944ab43ffe453259c1cbe1a430a97 [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#include <unordered_map>
28
Andreas Gampe57943812017-12-06 21:39:13 -080029#include <android-base/logging.h>
30#include <android-base/stringprintf.h>
Andreas Gampeaacc25d2015-04-01 14:49:06 -070031
Mathieu Chartiere401d142015-04-22 13:56:20 -070032#include "art_method-inl.h"
Andreas Gampebc4d2182016-02-22 10:03:12 -080033#include "base/casts.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070034#include "base/enums.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 Gampe2969bcd2015-03-09 12:57:41 -070049#include "mirror/class.h"
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070050#include "mirror/field-inl.h"
Narayan Kamath14832ef2016-08-05 11:44:32 +010051#include "mirror/method.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070052#include "mirror/object-inl.h"
Andreas Gampe52ecb652018-10-24 15:18:21 -070053#include "mirror/object_array-alloc-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070054#include "mirror/object_array-inl.h"
55#include "mirror/string-inl.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070056#include "nativehelper/scoped_local_ref.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070057#include "nth_caller_visitor.h"
Andreas Gampe715fdc22016-04-18 17:07:30 -070058#include "reflection.h"
Andreas Gampe513061a2017-06-01 09:17:34 -070059#include "thread-inl.h"
Sebastien Hertz2fd7e692015-04-02 11:11:19 +020060#include "transaction.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070061#include "well_known_classes.h"
62
63namespace art {
64namespace interpreter {
65
Andreas Gampe46ee31b2016-12-14 10:11:49 -080066using android::base::StringAppendV;
67using android::base::StringPrintf;
68
Andreas Gampe068b0c02015-03-11 12:44:47 -070069static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
Sebastien Hertz45b15972015-04-03 16:07:05 +020070 __attribute__((__format__(__printf__, 2, 3)))
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070071 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertz45b15972015-04-03 16:07:05 +020072
73static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
Andreas Gampe068b0c02015-03-11 12:44:47 -070074 va_list args;
Andreas Gampe068b0c02015-03-11 12:44:47 -070075 if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +020076 va_start(args, fmt);
77 AbortTransactionV(self, fmt, args);
Andreas Gampe068b0c02015-03-11 12:44:47 -070078 va_end(args);
79 } else {
Sebastien Hertz45b15972015-04-03 16:07:05 +020080 va_start(args, fmt);
81 std::string msg;
82 StringAppendV(&msg, fmt, args);
83 va_end(args);
84 LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
Andreas Gampe068b0c02015-03-11 12:44:47 -070085 UNREACHABLE();
86 }
87}
88
Andreas Gampe8ce9c302016-04-15 21:24:28 -070089// Restricted support for character upper case / lower case. Only support ASCII, where
90// it's easy. Abort the transaction otherwise.
91static void CharacterLowerUpper(Thread* self,
92 ShadowFrame* shadow_frame,
93 JValue* result,
94 size_t arg_offset,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070095 bool to_lower_case) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8ce9c302016-04-15 21:24:28 -070096 uint32_t int_value = static_cast<uint32_t>(shadow_frame->GetVReg(arg_offset));
97
98 // Only ASCII (7-bit).
99 if (!isascii(int_value)) {
100 AbortTransactionOrFail(self,
101 "Only support ASCII characters for toLowerCase/toUpperCase: %u",
102 int_value);
103 return;
104 }
105
106 std::locale c_locale("C");
107 char char_value = static_cast<char>(int_value);
108
109 if (to_lower_case) {
110 result->SetI(std::tolower(char_value, c_locale));
111 } else {
112 result->SetI(std::toupper(char_value, c_locale));
113 }
114}
115
116void UnstartedRuntime::UnstartedCharacterToLowerCase(
117 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
118 CharacterLowerUpper(self, shadow_frame, result, arg_offset, true);
119}
120
121void UnstartedRuntime::UnstartedCharacterToUpperCase(
122 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
123 CharacterLowerUpper(self, shadow_frame, result, arg_offset, false);
124}
125
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700126// Helper function to deal with class loading in an unstarted runtime.
127static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
128 Handle<mirror::ClassLoader> class_loader, JValue* result,
129 const std::string& method_name, bool initialize_class,
130 bool abort_if_not_found)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700131 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampefa4333d2017-02-14 11:10:34 -0800132 CHECK(className != nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700133 std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
134 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
135
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100136 ObjPtr<mirror::Class> found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700137 if (found == nullptr && abort_if_not_found) {
138 if (!self->IsExceptionPending()) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700139 AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
David Sehr709b0702016-10-13 09:12:37 -0700140 method_name.c_str(),
141 PrettyDescriptor(descriptor.c_str()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700142 }
143 return;
144 }
145 if (found != nullptr && initialize_class) {
146 StackHandleScope<1> hs(self);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100147 HandleWrapperObjPtr<mirror::Class> h_class = hs.NewHandleWrapper(&found);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700148 if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
149 CHECK(self->IsExceptionPending());
150 return;
151 }
152 }
153 result->SetL(found);
154}
155
156// Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
157// rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
158// ClassNotFoundException), so need to do the same. The only exception is if the exception is
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200159// actually the transaction abort exception. This must not be wrapped, as it signals an
160// initialization abort.
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700161static void CheckExceptionGenerateClassNotFound(Thread* self)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700162 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700163 if (self->IsExceptionPending()) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200164 // If it is not the transaction abort exception, wrap it.
David Sehr709b0702016-10-13 09:12:37 -0700165 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200166 if (type != Transaction::kAbortExceptionDescriptor) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700167 self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
168 "ClassNotFoundException");
169 }
170 }
171}
172
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700173static mirror::String* GetClassName(Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700174 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700175 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
176 if (param == nullptr) {
177 AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
178 return nullptr;
179 }
180 return param->AsString();
181}
182
David Brazdila02cb112018-01-31 11:36:39 +0000183template<typename T>
184static ALWAYS_INLINE bool ShouldBlockAccessToMember(T* member, ShadowFrame* frame)
185 REQUIRES_SHARED(Locks::mutator_lock_) {
Narayan Kamathf5f1f802018-04-03 15:23:46 +0100186 // All uses in this file are from reflection
187 constexpr hiddenapi::AccessMethod access_method = hiddenapi::kReflection;
188 return hiddenapi::GetMemberAction(
David Brazdil8ce3bfa2018-03-12 18:01:18 +0000189 member,
190 frame->GetMethod()->GetDeclaringClass()->GetClassLoader(),
David Brazdil8e1a7cb2018-03-27 08:14:25 +0000191 frame->GetMethod()->GetDeclaringClass()->GetDexCache(),
Narayan Kamathf5f1f802018-04-03 15:23:46 +0100192 access_method) == hiddenapi::kDeny;
David Brazdila02cb112018-01-31 11:36:39 +0000193}
194
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800195void UnstartedRuntime::UnstartedClassForNameCommon(Thread* self,
196 ShadowFrame* shadow_frame,
197 JValue* result,
198 size_t arg_offset,
199 bool long_form,
200 const char* caller) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700201 mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
202 if (class_name == nullptr) {
203 return;
204 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800205 bool initialize_class;
206 mirror::ClassLoader* class_loader;
207 if (long_form) {
208 initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
209 class_loader = down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
210 } else {
211 initialize_class = true;
212 // TODO: This is really only correct for the boot classpath, and for robustness we should
213 // check the caller.
214 class_loader = nullptr;
215 }
216
217 ScopedObjectAccessUnchecked soa(self);
218 if (class_loader != nullptr && !ClassLinker::IsBootClassLoader(soa, class_loader)) {
219 AbortTransactionOrFail(self,
220 "Only the boot classloader is supported: %s",
221 mirror::Object::PrettyTypeOf(class_loader).c_str());
222 return;
223 }
224
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700225 StackHandleScope<1> hs(self);
226 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800227 UnstartedRuntimeFindClass(self,
228 h_class_name,
229 ScopedNullHandle<mirror::ClassLoader>(),
230 result,
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800231 caller,
232 initialize_class,
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800233 false);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700234 CheckExceptionGenerateClassNotFound(self);
235}
236
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800237void UnstartedRuntime::UnstartedClassForName(
238 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
239 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, false, "Class.forName");
240}
241
Andreas Gampe799681b2015-05-15 19:24:12 -0700242void UnstartedRuntime::UnstartedClassForNameLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700243 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800244 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.forName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700245}
246
Vladimir Marko7287c4d2018-02-15 10:41:07 +0000247void UnstartedRuntime::UnstartedClassGetPrimitiveClass(
248 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
249 ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
250 ObjPtr<mirror::Class> klass = mirror::Class::GetPrimitiveClass(class_name);
251 if (UNLIKELY(klass == nullptr)) {
252 DCHECK(self->IsExceptionPending());
253 AbortTransactionOrFail(self,
254 "Class.getPrimitiveClass() failed: %s",
255 self->GetException()->GetDetailMessage()->ToModifiedUtf8().c_str());
256 return;
257 }
258 result->SetL(klass);
259}
260
Andreas Gampe799681b2015-05-15 19:24:12 -0700261void UnstartedRuntime::UnstartedClassClassForName(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700262 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800263 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.classForName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700264}
265
Andreas Gampe799681b2015-05-15 19:24:12 -0700266void UnstartedRuntime::UnstartedClassNewInstance(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700267 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
268 StackHandleScope<2> hs(self); // Class, constructor, object.
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700269 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
270 if (param == nullptr) {
271 AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
272 return;
273 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100274 Handle<mirror::Class> h_klass(hs.NewHandle(param->AsClass()));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700275
276 // Check that it's not null.
Andreas Gampefa4333d2017-02-14 11:10:34 -0800277 if (h_klass == nullptr) {
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700278 AbortTransactionOrFail(self, "Class reference is null for newInstance");
279 return;
280 }
281
282 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
283 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100284 if (h_klass->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200285 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700286 h_klass->PrettyClass().c_str());
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700287 return;
288 }
289 }
290
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700291 // There are two situations in which we'll abort this run.
292 // 1) If the class isn't yet initialized and initialization fails.
293 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
294 // Note that 2) could likely be handled here, but for safety abort the transaction.
295 bool ok = false;
Mathieu Chartiere401d142015-04-22 13:56:20 -0700296 auto* cl = Runtime::Current()->GetClassLinker();
297 if (cl->EnsureInitialized(self, h_klass, true, true)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000298 ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
David Brazdila02cb112018-01-31 11:36:39 +0000299 if (cons != nullptr && ShouldBlockAccessToMember(cons, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000300 cons = nullptr;
301 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700302 if (cons != nullptr) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100303 Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800304 CHECK(h_obj != nullptr); // We don't expect OOM at compile-time.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700305 EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700306 if (!self->IsExceptionPending()) {
307 result->SetL(h_obj.Get());
308 ok = true;
309 }
310 } else {
311 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
312 "Could not find default constructor for '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700313 h_klass->PrettyClass().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700314 }
315 }
316 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700317 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
David Sehr709b0702016-10-13 09:12:37 -0700318 h_klass->PrettyClass().c_str(),
319 mirror::Object::PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700320 }
321}
322
Andreas Gampe799681b2015-05-15 19:24:12 -0700323void UnstartedRuntime::UnstartedClassGetDeclaredField(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700324 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700325 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
326 // going the reflective Dex way.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100327 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
328 ObjPtr<mirror::String> name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700329 ArtField* found = nullptr;
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700330 for (ArtField& field : klass->GetIFields()) {
331 if (name2->Equals(field.GetName())) {
332 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700333 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700334 }
335 }
336 if (found == nullptr) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700337 for (ArtField& field : klass->GetSFields()) {
338 if (name2->Equals(field.GetName())) {
339 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700340 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700341 }
342 }
343 }
David Brazdila02cb112018-01-31 11:36:39 +0000344 if (found != nullptr && ShouldBlockAccessToMember(found, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000345 found = nullptr;
346 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700347 if (found == nullptr) {
348 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
349 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
David Sehr709b0702016-10-13 09:12:37 -0700350 klass->PrettyDescriptor().c_str());
Andreas Gampe068b0c02015-03-11 12:44:47 -0700351 return;
352 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700353 Runtime* runtime = Runtime::Current();
Andreas Gampe542451c2016-07-26 09:02:02 -0700354 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Andreas Gampee01e3642016-07-25 13:06:04 -0700355 mirror::Field* field;
356 if (runtime->IsActiveTransaction()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700357 if (pointer_size == PointerSize::k64) {
358 field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
359 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700360 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700361 field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
362 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700363 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700364 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700365 if (pointer_size == PointerSize::k64) {
366 field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
367 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700368 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700369 field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
370 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700371 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700372 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700373 result->SetL(field);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700374}
375
Andreas Gampebc4d2182016-02-22 10:03:12 -0800376// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
377void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
378 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
379 // Special managed code cut-out to allow method lookup in a un-started runtime.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100380 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
Andreas Gampebc4d2182016-02-22 10:03:12 -0800381 if (klass == nullptr) {
382 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
383 return;
384 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100385 ObjPtr<mirror::String> name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
386 ObjPtr<mirror::ObjectArray<mirror::Class>> args =
Andreas Gampebc4d2182016-02-22 10:03:12 -0800387 shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700388 Runtime* runtime = Runtime::Current();
389 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700390 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700391 ObjPtr<mirror::Method> method;
Andreas Gampee01e3642016-07-25 13:06:04 -0700392 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700393 if (pointer_size == PointerSize::k64) {
394 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
395 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700396 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700397 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
398 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700399 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800400 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700401 if (pointer_size == PointerSize::k64) {
402 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
403 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700404 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700405 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
406 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700407 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800408 }
David Brazdila02cb112018-01-31 11:36:39 +0000409 if (method != nullptr && ShouldBlockAccessToMember(method->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000410 method = nullptr;
411 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700412 result->SetL(method);
Andreas Gampebc4d2182016-02-22 10:03:12 -0800413}
414
Andreas Gampe6039e562016-04-05 18:18:43 -0700415// Special managed code cut-out to allow constructor lookup in a un-started runtime.
416void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
417 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100418 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
Andreas Gampe6039e562016-04-05 18:18:43 -0700419 if (klass == nullptr) {
420 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
421 return;
422 }
423 mirror::ObjectArray<mirror::Class>* args =
424 shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700425 Runtime* runtime = Runtime::Current();
426 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700427 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700428 ObjPtr<mirror::Constructor> constructor;
Andreas Gampee01e3642016-07-25 13:06:04 -0700429 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700430 if (pointer_size == PointerSize::k64) {
431 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
432 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700433 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700434 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
435 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700436 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700437 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700438 if (pointer_size == PointerSize::k64) {
439 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
440 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700441 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700442 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
443 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700444 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700445 }
David Brazdil5a61bb72018-01-19 16:59:46 +0000446 if (constructor != nullptr &&
David Brazdila02cb112018-01-31 11:36:39 +0000447 ShouldBlockAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000448 constructor = nullptr;
449 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700450 result->SetL(constructor);
Andreas Gampe6039e562016-04-05 18:18:43 -0700451}
452
Andreas Gampeae78c262017-02-01 20:40:44 -0800453void UnstartedRuntime::UnstartedClassGetDeclaringClass(
454 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
455 StackHandleScope<1> hs(self);
456 Handle<mirror::Class> klass(hs.NewHandle(
457 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
458 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
459 result->SetL(nullptr);
460 return;
461 }
462 // Return null for anonymous classes.
463 JValue is_anon_result;
464 UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
465 if (is_anon_result.GetZ() != 0) {
466 result->SetL(nullptr);
467 return;
468 }
469 result->SetL(annotations::GetDeclaringClass(klass));
470}
471
Andreas Gampe633750c2016-02-19 10:49:50 -0800472void UnstartedRuntime::UnstartedClassGetEnclosingClass(
473 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
474 StackHandleScope<1> hs(self);
475 Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
476 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
477 result->SetL(nullptr);
478 }
David Sehr9323e6e2016-09-13 08:58:35 -0700479 result->SetL(annotations::GetEnclosingClass(klass));
Andreas Gampe633750c2016-02-19 10:49:50 -0800480}
481
Andreas Gampe715fdc22016-04-18 17:07:30 -0700482void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
483 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
484 StackHandleScope<1> hs(self);
485 Handle<mirror::Class> klass(hs.NewHandle(
486 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
487 const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
488 result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
489}
490
Andreas Gampe9486a162017-02-16 15:17:47 -0800491void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
492 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
493 StackHandleScope<1> hs(self);
494 Handle<mirror::Class> klass(hs.NewHandle(
495 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
496
497 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
498 result->SetL(nullptr);
499 return;
500 }
501
502 result->SetL(annotations::GetSignatureAnnotationForClass(klass));
503}
504
Andreas Gampeae78c262017-02-01 20:40:44 -0800505void UnstartedRuntime::UnstartedClassIsAnonymousClass(
506 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
507 StackHandleScope<1> hs(self);
508 Handle<mirror::Class> klass(hs.NewHandle(
509 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
510 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
511 result->SetZ(false);
512 return;
513 }
Vladimir Marko2d3065e2018-05-22 13:56:09 +0100514 ObjPtr<mirror::String> class_name = nullptr;
Andreas Gampeae78c262017-02-01 20:40:44 -0800515 if (!annotations::GetInnerClass(klass, &class_name)) {
516 result->SetZ(false);
517 return;
518 }
519 result->SetZ(class_name == nullptr);
520}
521
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100522static MemMap FindAndExtractEntry(const std::string& jar_file,
523 const char* entry_name,
524 size_t* size,
525 std::string* error_msg) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700526 CHECK(size != nullptr);
527
528 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
529 if (zip_archive == nullptr) {
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100530 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700531 }
532 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
533 if (zip_entry == nullptr) {
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100534 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700535 }
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100536 MemMap tmp_map = zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg);
537 if (!tmp_map.IsValid()) {
538 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700539 }
540
541 // OK, from here everything seems fine.
542 *size = zip_entry->GetUncompressedLength();
543 return tmp_map;
544}
545
546static void GetResourceAsStream(Thread* self,
547 ShadowFrame* shadow_frame,
548 JValue* result,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700549 size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700550 mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
551 if (resource_obj == nullptr) {
552 AbortTransactionOrFail(self, "null name for getResourceAsStream");
553 return;
554 }
555 CHECK(resource_obj->IsString());
556 mirror::String* resource_name = resource_obj->AsString();
557
558 std::string resource_name_str = resource_name->ToModifiedUtf8();
559 if (resource_name_str.empty() || resource_name_str == "/") {
560 AbortTransactionOrFail(self,
561 "Unsupported name %s for getResourceAsStream",
562 resource_name_str.c_str());
563 return;
564 }
565 const char* resource_cstr = resource_name_str.c_str();
566 if (resource_cstr[0] == '/') {
567 resource_cstr++;
568 }
569
570 Runtime* runtime = Runtime::Current();
571
572 std::vector<std::string> split;
573 Split(runtime->GetBootClassPathString(), ':', &split);
574 if (split.empty()) {
575 AbortTransactionOrFail(self,
576 "Boot classpath not set or split error:: %s",
577 runtime->GetBootClassPathString().c_str());
578 return;
579 }
580
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100581 MemMap mem_map;
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700582 size_t map_size;
583 std::string last_error_msg; // Only store the last message (we could concatenate).
584
585 for (const std::string& jar_file : split) {
586 mem_map = FindAndExtractEntry(jar_file, resource_cstr, &map_size, &last_error_msg);
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100587 if (mem_map.IsValid()) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700588 break;
589 }
590 }
591
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100592 if (!mem_map.IsValid()) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700593 // Didn't find it. There's a good chance this will be the same at runtime, but still
594 // conservatively abort the transaction here.
595 AbortTransactionOrFail(self,
596 "Could not find resource %s. Last error was %s.",
597 resource_name_str.c_str(),
598 last_error_msg.c_str());
599 return;
600 }
601
602 StackHandleScope<3> hs(self);
603
604 // Create byte array for content.
605 Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800606 if (h_array == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700607 AbortTransactionOrFail(self, "Could not find/create byte array class");
608 return;
609 }
610 // Copy in content.
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100611 memcpy(h_array->GetData(), mem_map.Begin(), map_size);
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700612 // Be proactive releasing memory.
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100613 mem_map.Reset();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700614
615 // Create a ByteArrayInputStream.
616 Handle<mirror::Class> h_class(hs.NewHandle(
617 runtime->GetClassLinker()->FindClass(self,
618 "Ljava/io/ByteArrayInputStream;",
619 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800620 if (h_class == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700621 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
622 return;
623 }
624 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
625 AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
626 return;
627 }
628
629 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800630 if (h_obj == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700631 AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
632 return;
633 }
634
635 auto* cl = Runtime::Current()->GetClassLinker();
Vladimir Markoba118822017-06-12 15:41:56 +0100636 ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700637 if (constructor == nullptr) {
638 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
639 return;
640 }
641
642 uint32_t args[1];
Vladimir Marko78baed52018-10-11 10:44:58 +0100643 args[0] = reinterpret_cast32<uint32_t>(h_array.Get());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700644 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
645
646 if (self->IsExceptionPending()) {
647 AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
648 return;
649 }
650
651 result->SetL(h_obj.Get());
652}
653
654void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
655 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
656 {
657 mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
658 CHECK(this_obj != nullptr);
659 CHECK(this_obj->IsClassLoader());
660
661 StackHandleScope<1> hs(self);
662 Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
663
664 if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
665 this_classloader_class.Get()) {
666 AbortTransactionOrFail(self,
David Sehr709b0702016-10-13 09:12:37 -0700667 "Unsupported classloader type %s for getResourceAsStream",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700668 mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700669 return;
670 }
671 }
672
673 GetResourceAsStream(self, shadow_frame, result, arg_offset);
674}
675
Andreas Gampe85bef7e2017-02-16 18:13:26 -0800676void UnstartedRuntime::UnstartedConstructorNewInstance0(
677 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
678 // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
679 StackHandleScope<4> hs(self);
680 Handle<mirror::Constructor> m = hs.NewHandle(
681 reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
682 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
683 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
684 shadow_frame->GetVRegReference(arg_offset + 1)));
685 Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
686 if (UNLIKELY(c->IsAbstract())) {
687 AbortTransactionOrFail(self, "Cannot handle abstract classes");
688 return;
689 }
690 // Verify that we can access the class.
691 if (!m->IsAccessible() && !c->IsPublic()) {
692 // Go 2 frames back, this method is always called from newInstance0, which is called from
693 // Constructor.newInstance(Object... args).
694 ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
695 // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
696 // access checks anyways. TODO: Investigate if this the correct behavior.
697 if (caller != nullptr && !caller->CanAccess(c.Get())) {
698 AbortTransactionOrFail(self, "Cannot access class");
699 return;
700 }
701 }
702 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
703 DCHECK(self->IsExceptionPending());
704 return;
705 }
706 if (c->IsClassClass()) {
707 AbortTransactionOrFail(self, "new Class() is not supported");
708 return;
709 }
710
711 // String constructor is replaced by a StringFactory method in InvokeMethod.
712 if (c->IsStringClass()) {
713 // We don't support strings.
714 AbortTransactionOrFail(self, "String construction is not supported");
715 return;
716 }
717
718 Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
719 if (receiver == nullptr) {
720 AbortTransactionOrFail(self, "Could not allocate");
721 return;
722 }
723
724 // It's easier to use reflection to make the call, than create the uint32_t array.
725 {
726 ScopedObjectAccessUnchecked soa(self);
727 ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
728 soa.AddLocalReference<jobject>(m.Get()));
729 ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
730 soa.AddLocalReference<jobject>(receiver.Get()));
731 ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
732 soa.AddLocalReference<jobject>(args.Get()));
733 InvokeMethod(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
734 }
735 if (self->IsExceptionPending()) {
736 AbortTransactionOrFail(self, "Failed running constructor");
737 } else {
738 result->SetL(receiver.Get());
739 }
740}
741
Andreas Gampe799681b2015-05-15 19:24:12 -0700742void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700743 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700744 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
745 mirror::ClassLoader* class_loader =
746 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
747 StackHandleScope<2> hs(self);
748 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
749 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
750 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
751 "VMClassLoader.findLoadedClass", false, false);
752 // This might have an error pending. But semantics are to just return null.
753 if (self->IsExceptionPending()) {
754 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
David Sehr709b0702016-10-13 09:12:37 -0700755 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700756 if (type != "java.lang.InternalError") {
757 self->ClearException();
758 }
759 }
760}
761
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700762// Arraycopy emulation.
763// Note: we can't use any fast copy functions, as they are not available under transaction.
764
765template <typename T>
766static void PrimitiveArrayCopy(Thread* self,
767 mirror::Array* src_array, int32_t src_pos,
768 mirror::Array* dst_array, int32_t dst_pos,
769 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700770 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700771 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700772 AbortTransactionOrFail(self,
773 "Types mismatched in arraycopy: %s vs %s.",
774 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700775 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700776 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700777 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700778 return;
779 }
780 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
781 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
782 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
783 if (copy_forward) {
784 for (int32_t i = 0; i < length; ++i) {
785 dst->Set(dst_pos + i, src->Get(src_pos + i));
786 }
787 } else {
788 for (int32_t i = 1; i <= length; ++i) {
789 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
790 }
791 }
792}
793
Andreas Gampe799681b2015-05-15 19:24:12 -0700794void UnstartedRuntime::UnstartedSystemArraycopy(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700795 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700796 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700797 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
798 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700799 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700800
Andreas Gampe85a098a2016-03-31 13:30:53 -0700801 mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
802 mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
803 // Null checking. For simplicity, abort transaction.
804 if (src_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700805 AbortTransactionOrFail(self, "src is null in arraycopy.");
806 return;
807 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700808 if (dst_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700809 AbortTransactionOrFail(self, "dst is null in arraycopy.");
810 return;
811 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700812 // Test for arrayness. Throw ArrayStoreException.
813 if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
814 self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
815 return;
816 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700817
Andreas Gampe85a098a2016-03-31 13:30:53 -0700818 mirror::Array* src_array = src_obj->AsArray();
819 mirror::Array* dst_array = dst_obj->AsArray();
820
821 // Bounds checking. Throw IndexOutOfBoundsException.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700822 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
823 UNLIKELY(src_pos > src_array->GetLength() - length) ||
824 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700825 self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700826 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
827 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
828 length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700829 return;
830 }
831
832 // 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
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700849 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
850 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
851 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 }
1244 mirror::Array* array = obj->AsArray();
1245
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));
1258 mirror::ByteArray* byte_array = array->AsByteArray();
1259 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);
1295 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1296 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);
1316 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1317 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();
1351 result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator));
1352}
1353
1354// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001355void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001356 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root57f91e82015-05-14 15:58:17 -07001357 mirror::String* to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1358 if (to_copy == nullptr) {
1359 AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1360 return;
1361 }
1362 StackHandleScope<1> hs(self);
1363 Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1364 Runtime* runtime = Runtime::Current();
1365 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1366 result->SetL(mirror::String::AllocFromString<true>(self, h_string->GetLength(), h_string, 0,
1367 allocator));
1368}
1369
Andreas Gampe799681b2015-05-15 19:24:12 -07001370void UnstartedRuntime::UnstartedStringFastSubstring(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001371 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001372 jint start = shadow_frame->GetVReg(arg_offset + 1);
1373 jint length = shadow_frame->GetVReg(arg_offset + 2);
Kenny Root57f91e82015-05-14 15:58:17 -07001374 DCHECK_GE(start, 0);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001375 DCHECK_GE(length, 0);
1376 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001377 Handle<mirror::String> h_string(
1378 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
Kenny Root57f91e82015-05-14 15:58:17 -07001379 DCHECK_LE(start, h_string->GetLength());
1380 DCHECK_LE(start + length, h_string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001381 Runtime* runtime = Runtime::Current();
1382 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1383 result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator));
1384}
1385
Kenny Root57f91e82015-05-14 15:58:17 -07001386// This allows getting the char array for new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001387void UnstartedRuntime::UnstartedStringToCharArray(
Kenny Root57f91e82015-05-14 15:58:17 -07001388 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001389 REQUIRES_SHARED(Locks::mutator_lock_) {
Kenny Root57f91e82015-05-14 15:58:17 -07001390 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1391 if (string == nullptr) {
1392 AbortTransactionOrFail(self, "String.charAt with null object");
1393 return;
1394 }
1395 result->SetL(string->ToCharArray(self));
1396}
1397
Andreas Gampebc4d2182016-02-22 10:03:12 -08001398// This allows statically initializing ConcurrentHashMap and SynchronousQueue.
1399void UnstartedRuntime::UnstartedReferenceGetReferent(
1400 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001401 ObjPtr<mirror::Reference> const ref = down_cast<mirror::Reference*>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001402 shadow_frame->GetVRegReference(arg_offset));
1403 if (ref == nullptr) {
1404 AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1405 return;
1406 }
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001407 ObjPtr<mirror::Object> const referent =
Andreas Gampebc4d2182016-02-22 10:03:12 -08001408 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1409 result->SetL(referent);
1410}
1411
1412// This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1413// conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1414// where we can predict the behavior (somewhat).
1415// Note: this is required (instead of lazy initialization) as these classes are used in the static
1416// initialization of other classes, so will *use* the value.
1417void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1418 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001419 if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001420 // SynchronousQueue really only separates between single- and multiprocessor case. Return
1421 // 8 as a conservative upper approximation.
1422 result->SetI(8);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001423 } else if (CheckCallers(shadow_frame,
1424 { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001425 // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1426 // a good upper bound.
1427 // TODO: Consider resetting in the zygote?
1428 result->SetI(8);
1429 } else {
1430 // Not supported.
1431 AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1432 }
1433}
1434
1435// This allows accessing ConcurrentHashMap/SynchronousQueue.
1436
1437void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1438 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1439 // Argument 0 is the Unsafe instance, skip.
1440 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1441 if (obj == nullptr) {
1442 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1443 return;
1444 }
1445 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1446 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1447 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001448 bool success;
1449 // Check whether we're in a transaction, call accordingly.
1450 if (Runtime::Current()->IsActiveTransaction()) {
1451 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1452 expectedValue,
1453 newValue);
1454 } else {
1455 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1456 expectedValue,
1457 newValue);
1458 }
1459 result->SetZ(success ? 1 : 0);
1460}
1461
1462void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1463 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1464 // Argument 0 is the Unsafe instance, skip.
1465 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1466 if (obj == nullptr) {
1467 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1468 return;
1469 }
1470 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1471 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1472 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 5);
1473
1474 // Must use non transactional mode.
1475 if (kUseReadBarrier) {
1476 // Need to make sure the reference stored in the field is a to-space one before attempting the
1477 // CAS or the CAS could fail incorrectly.
1478 mirror::HeapReference<mirror::Object>* field_addr =
1479 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1480 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001481 ReadBarrier::Barrier<
1482 mirror::Object,
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001483 /* kIsVolatile= */ false,
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001484 kWithReadBarrier,
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001485 /* kAlwaysUpdateField= */ true>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001486 obj,
1487 MemberOffset(offset),
1488 field_addr);
1489 }
1490 bool success;
1491 // Check whether we're in a transaction, call accordingly.
1492 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001493 success = obj->CasFieldObject<true>(MemberOffset(offset),
1494 expected_value,
1495 newValue,
1496 CASMode::kStrong,
1497 std::memory_order_seq_cst);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001498 } else {
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001499 success = obj->CasFieldObject<false>(MemberOffset(offset),
1500 expected_value,
1501 newValue,
1502 CASMode::kStrong,
1503 std::memory_order_seq_cst);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001504 }
1505 result->SetZ(success ? 1 : 0);
1506}
1507
1508void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1509 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001510 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001511 // Argument 0 is the Unsafe instance, skip.
1512 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1513 if (obj == nullptr) {
1514 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1515 return;
1516 }
1517 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1518 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1519 result->SetL(value);
1520}
1521
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001522void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1523 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001524 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001525 // Argument 0 is the Unsafe instance, skip.
1526 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1527 if (obj == nullptr) {
1528 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1529 return;
1530 }
1531 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1532 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1533 if (Runtime::Current()->IsActiveTransaction()) {
1534 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1535 } else {
1536 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1537 }
1538}
1539
Andreas Gampebc4d2182016-02-22 10:03:12 -08001540void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1541 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001542 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001543 // Argument 0 is the Unsafe instance, skip.
1544 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1545 if (obj == nullptr) {
1546 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1547 return;
1548 }
1549 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1550 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 4);
Orion Hodson27b96762018-03-13 16:06:57 +00001551 std::atomic_thread_fence(std::memory_order_release);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001552 if (Runtime::Current()->IsActiveTransaction()) {
1553 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1554 } else {
1555 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1556 }
1557}
1558
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001559// A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1560// of correctly handling the corner cases.
1561void UnstartedRuntime::UnstartedIntegerParseInt(
1562 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001563 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001564 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1565 if (obj == nullptr) {
1566 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1567 return;
1568 }
1569
1570 std::string string_value = obj->AsString()->ToModifiedUtf8();
1571 if (string_value.empty()) {
1572 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1573 return;
1574 }
1575
1576 const char* c_str = string_value.c_str();
1577 char *end;
1578 // Can we set errno to 0? Is this always a variable, and not a macro?
1579 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1580 int64_t l = strtol(c_str, &end, 10);
1581
1582 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1583 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1584 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1585 return;
1586 }
1587 if (l == 0) {
1588 // Check whether the string wasn't exactly zero.
1589 if (string_value != "0") {
1590 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1591 return;
1592 }
1593 } else if (*end != '\0') {
1594 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1595 return;
1596 }
1597
1598 result->SetI(static_cast<int32_t>(l));
1599}
1600
1601// A cutout for Long.parseLong.
1602//
1603// Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1604// well.
1605void UnstartedRuntime::UnstartedLongParseLong(
1606 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001607 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001608 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1609 if (obj == nullptr) {
1610 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1611 return;
1612 }
1613
1614 std::string string_value = obj->AsString()->ToModifiedUtf8();
1615 if (string_value.empty()) {
1616 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1617 return;
1618 }
1619
1620 const char* c_str = string_value.c_str();
1621 char *end;
1622 // Can we set errno to 0? Is this always a variable, and not a macro?
1623 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1624 int64_t l = strtol(c_str, &end, 10);
1625
1626 // Note: comparing against int32_t min/max is intentional here.
1627 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1628 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1629 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1630 return;
1631 }
1632 if (l == 0) {
1633 // Check whether the string wasn't exactly zero.
1634 if (string_value != "0") {
1635 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1636 return;
1637 }
1638 } else if (*end != '\0') {
1639 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1640 return;
1641 }
1642
1643 result->SetJ(l);
1644}
1645
Andreas Gampe715fdc22016-04-18 17:07:30 -07001646void UnstartedRuntime::UnstartedMethodInvoke(
1647 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001648 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe715fdc22016-04-18 17:07:30 -07001649 JNIEnvExt* env = self->GetJniEnv();
1650 ScopedObjectAccessUnchecked soa(self);
1651
Mathieu Chartier8778c522016-10-04 19:06:30 -07001652 ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001653 ScopedLocalRef<jobject> java_method(env,
Roland Levillain5e8d5f02016-10-18 18:03:43 +01001654 java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001655
Mathieu Chartier8778c522016-10-04 19:06:30 -07001656 ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001657 ScopedLocalRef<jobject> java_receiver(env,
1658 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1659
Mathieu Chartier8778c522016-10-04 19:06:30 -07001660 ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001661 ScopedLocalRef<jobject> java_args(env,
1662 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1663
1664 ScopedLocalRef<jobject> result_jobj(env,
1665 InvokeMethod(soa, java_method.get(), java_receiver.get(), java_args.get()));
1666
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001667 result->SetL(self->DecodeJObject(result_jobj.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001668
1669 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1670 // InvocationTargetExceptions.
1671 if (self->IsExceptionPending()) {
1672 AbortTransactionOrFail(self, "Failed Method.invoke");
1673 }
1674}
1675
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001676void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1677 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1678 REQUIRES_SHARED(Locks::mutator_lock_) {
1679 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1680 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1681}
Andreas Gampebc4d2182016-02-22 10:03:12 -08001682
Orion Hodson43f0cdb2017-10-10 14:47:32 +01001683// Checks whether the runtime is s64-bit. This is needed for the clinit of
1684// java.lang.invoke.VarHandle clinit. The clinit determines sets of
1685// available VarHandle accessors and these differ based on machine
1686// word size.
1687void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1688 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1689 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1690 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1691 jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1692 result->SetZ(is64bit);
1693}
1694
Mathieu Chartiere401d142015-04-22 13:56:20 -07001695void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
Vladimir Marko78baed52018-10-11 10:44:58 +01001696 Thread* self,
1697 ArtMethod* method ATTRIBUTE_UNUSED,
1698 mirror::Object* receiver ATTRIBUTE_UNUSED,
1699 uint32_t* args,
1700 JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001701 int32_t length = args[1];
1702 DCHECK_GE(length, 0);
Vladimir Marko78baed52018-10-11 10:44:58 +01001703 ObjPtr<mirror::Object> element_class = reinterpret_cast32<mirror::Object*>(args[0])->AsClass();
1704 if (element_class == nullptr) {
1705 AbortTransactionOrFail(self, "VMRuntime.newUnpaddedArray with null element_class.");
1706 return;
1707 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001708 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001709 ObjPtr<mirror::Class> array_class =
Vladimir Marko78baed52018-10-11 10:44:58 +01001710 runtime->GetClassLinker()->FindArrayClass(self, element_class->AsClass());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001711 DCHECK(array_class != nullptr);
1712 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001713 result->SetL(mirror::Array::Alloc<true, true>(self,
1714 array_class,
1715 length,
1716 array_class->GetComponentSizeShift(),
1717 allocator));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001718}
1719
Mathieu Chartiere401d142015-04-22 13:56:20 -07001720void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1721 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1722 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001723 result->SetL(nullptr);
1724}
1725
Mathieu Chartiere401d142015-04-22 13:56:20 -07001726void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1727 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1728 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001729 NthCallerVisitor visitor(self, 3);
1730 visitor.WalkStack();
1731 if (visitor.caller != nullptr) {
1732 result->SetL(visitor.caller->GetDeclaringClass());
1733 }
1734}
1735
Mathieu Chartiere401d142015-04-22 13:56:20 -07001736void UnstartedRuntime::UnstartedJNIMathLog(
1737 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1738 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001739 JValue value;
1740 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1741 result->SetD(log(value.GetD()));
1742}
1743
Mathieu Chartiere401d142015-04-22 13:56:20 -07001744void UnstartedRuntime::UnstartedJNIMathExp(
1745 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1746 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001747 JValue value;
1748 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1749 result->SetD(exp(value.GetD()));
1750}
1751
Andreas Gampebc4d2182016-02-22 10:03:12 -08001752void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1753 Thread* self ATTRIBUTE_UNUSED,
1754 ArtMethod* method ATTRIBUTE_UNUSED,
1755 mirror::Object* receiver ATTRIBUTE_UNUSED,
1756 uint32_t* args ATTRIBUTE_UNUSED,
1757 JValue* result) {
1758 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1759 ? 0
1760 : 1);
1761}
1762
Mathieu Chartiere401d142015-04-22 13:56:20 -07001763void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1764 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1765 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001766 StackHandleScope<1> hs(self);
1767 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1768}
1769
Andreas Gampebc4d2182016-02-22 10:03:12 -08001770void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1771 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1772 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1773 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1774 result->SetD(bit_cast<double>(long_input));
1775}
1776
Mathieu Chartiere401d142015-04-22 13:56:20 -07001777void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
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 result->SetI(args[0]);
1781}
1782
Mathieu Chartiere401d142015-04-22 13:56:20 -07001783void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1784 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1785 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001786 result->SetI(args[0]);
1787}
1788
Mathieu Chartiere401d142015-04-22 13:56:20 -07001789void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1790 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1791 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001792 result->SetL(receiver->Clone(self));
1793}
1794
Mathieu Chartiere401d142015-04-22 13:56:20 -07001795void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1796 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1797 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001798 receiver->NotifyAll(self);
1799}
1800
Vladimir Marko78baed52018-10-11 10:44:58 +01001801void UnstartedRuntime::UnstartedJNIStringCompareTo(Thread* self,
1802 ArtMethod* method ATTRIBUTE_UNUSED,
1803 mirror::Object* receiver,
1804 uint32_t* args,
1805 JValue* result) {
1806 ObjPtr<mirror::Object> rhs = reinterpret_cast32<mirror::Object*>(args[0]);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001807 if (rhs == nullptr) {
Vladimir Marko78baed52018-10-11 10:44:58 +01001808 AbortTransactionOrFail(self, "String.compareTo with null object.");
1809 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001810 }
Vladimir Marko78baed52018-10-11 10:44:58 +01001811 result->SetI(receiver->AsString()->CompareTo(rhs->AsString()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001812}
1813
Mathieu Chartiere401d142015-04-22 13:56:20 -07001814void UnstartedRuntime::UnstartedJNIStringIntern(
1815 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1816 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001817 result->SetL(receiver->AsString()->Intern());
1818}
1819
Mathieu Chartiere401d142015-04-22 13:56:20 -07001820void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1821 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1822 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001823 StackHandleScope<2> hs(self);
1824 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1825 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1826 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1827}
1828
Mathieu Chartiere401d142015-04-22 13:56:20 -07001829void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1830 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1831 uint32_t* args, JValue* result) {
Andreas Gampee598e042015-04-10 14:57:10 -07001832 int32_t length = static_cast<int32_t>(args[1]);
1833 if (length < 0) {
1834 ThrowNegativeArraySizeException(length);
1835 return;
1836 }
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001837 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
Andreas Gampee598e042015-04-10 14:57:10 -07001838 Runtime* runtime = Runtime::Current();
1839 ClassLinker* class_linker = runtime->GetClassLinker();
Vladimir Markobcf17522018-06-01 13:14:32 +01001840 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, element_class);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001841 if (UNLIKELY(array_class == nullptr)) {
Andreas Gampee598e042015-04-10 14:57:10 -07001842 CHECK(self->IsExceptionPending());
1843 return;
1844 }
1845 DCHECK(array_class->IsObjectArrayClass());
Vladimir Markobcf17522018-06-01 13:14:32 +01001846 ObjPtr<mirror::Array> new_array = mirror::ObjectArray<mirror::Object>::Alloc(
Andreas Gampee598e042015-04-10 14:57:10 -07001847 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1848 result->SetL(new_array);
1849}
1850
Mathieu Chartiere401d142015-04-22 13:56:20 -07001851void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1852 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1853 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001854 ScopedObjectAccessUnchecked soa(self);
1855 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001856 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<true>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001857 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001858 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<false>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001859 }
1860}
1861
Mathieu Chartiere401d142015-04-22 13:56:20 -07001862void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
1863 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1864 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001865 result->SetZ(JNI_TRUE);
1866}
1867
Mathieu Chartiere401d142015-04-22 13:56:20 -07001868void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
Vladimir Marko78baed52018-10-11 10:44:58 +01001869 Thread* self,
1870 ArtMethod* method ATTRIBUTE_UNUSED,
1871 mirror::Object* receiver ATTRIBUTE_UNUSED,
1872 uint32_t* args,
1873 JValue* result) {
1874 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1875 if (obj == nullptr) {
1876 AbortTransactionOrFail(self, "Unsafe.compareAndSwapInt with null object.");
1877 return;
1878 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001879 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1880 jint expectedValue = args[3];
1881 jint newValue = args[4];
1882 bool success;
1883 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier42c2e502018-06-19 12:30:56 -07001884 success = obj->CasField32<true>(MemberOffset(offset),
1885 expectedValue,
1886 newValue,
1887 CASMode::kStrong,
1888 std::memory_order_seq_cst);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001889 } else {
Mathieu Chartier42c2e502018-06-19 12:30:56 -07001890 success = obj->CasField32<false>(MemberOffset(offset),
1891 expectedValue,
1892 newValue,
1893 CASMode::kStrong,
1894 std::memory_order_seq_cst);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001895 }
1896 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1897}
1898
Vladimir Marko78baed52018-10-11 10:44:58 +01001899void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(Thread* self,
1900 ArtMethod* method ATTRIBUTE_UNUSED,
1901 mirror::Object* receiver ATTRIBUTE_UNUSED,
1902 uint32_t* args,
1903 JValue* result) {
1904 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
Narayan Kamath34a316f2016-03-30 13:11:18 +01001905 if (obj == nullptr) {
Vladimir Marko78baed52018-10-11 10:44:58 +01001906 AbortTransactionOrFail(self, "Unsafe.compareAndSwapIntVolatile with null object.");
Narayan Kamath34a316f2016-03-30 13:11:18 +01001907 return;
1908 }
1909
1910 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1911 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1912}
1913
Vladimir Marko78baed52018-10-11 10:44:58 +01001914void UnstartedRuntime::UnstartedJNIUnsafePutObject(Thread* self,
1915 ArtMethod* method ATTRIBUTE_UNUSED,
1916 mirror::Object* receiver ATTRIBUTE_UNUSED,
1917 uint32_t* args,
1918 JValue* result ATTRIBUTE_UNUSED) {
1919 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1920 if (obj == nullptr) {
1921 AbortTransactionOrFail(self, "Unsafe.putObject with null object.");
1922 return;
1923 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001924 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
Vladimir Marko78baed52018-10-11 10:44:58 +01001925 ObjPtr<mirror::Object> newValue = reinterpret_cast32<mirror::Object*>(args[3]);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001926 if (Runtime::Current()->IsActiveTransaction()) {
1927 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1928 } else {
1929 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1930 }
1931}
1932
Andreas Gampe799681b2015-05-15 19:24:12 -07001933void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
Vladimir Marko78baed52018-10-11 10:44:58 +01001934 Thread* self,
1935 ArtMethod* method ATTRIBUTE_UNUSED,
1936 mirror::Object* receiver ATTRIBUTE_UNUSED,
1937 uint32_t* args,
1938 JValue* result) {
1939 ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
1940 if (component == nullptr) {
1941 AbortTransactionOrFail(self, "Unsafe.getArrayBaseOffsetForComponentType with null component.");
1942 return;
1943 }
1944 Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001945 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1946}
1947
Andreas Gampe799681b2015-05-15 19:24:12 -07001948void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
Vladimir Marko78baed52018-10-11 10:44:58 +01001949 Thread* self,
1950 ArtMethod* method ATTRIBUTE_UNUSED,
1951 mirror::Object* receiver ATTRIBUTE_UNUSED,
1952 uint32_t* args,
1953 JValue* result) {
1954 ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
1955 if (component == nullptr) {
1956 AbortTransactionOrFail(self, "Unsafe.getArrayIndexScaleForComponentType with null component.");
1957 return;
1958 }
1959 Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001960 result->SetI(Primitive::ComponentSize(primitive_type));
1961}
1962
Andreas Gampec55bb392018-09-21 00:02:02 +00001963using InvokeHandler = void(*)(Thread* self,
1964 ShadowFrame* shadow_frame,
1965 JValue* result,
1966 size_t arg_size);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001967
Andreas Gampec55bb392018-09-21 00:02:02 +00001968using JNIHandler = void(*)(Thread* self,
1969 ArtMethod* method,
1970 mirror::Object* receiver,
1971 uint32_t* args,
1972 JValue* result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001973
1974static bool tables_initialized_ = false;
1975static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
1976static std::unordered_map<std::string, JNIHandler> jni_handlers_;
1977
Andreas Gampe799681b2015-05-15 19:24:12 -07001978void UnstartedRuntime::InitializeInvokeHandlers() {
1979#define UNSTARTED_DIRECT(ShortName, Sig) \
1980 invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
1981#include "unstarted_runtime_list.h"
1982 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
1983#undef UNSTARTED_RUNTIME_DIRECT_LIST
1984#undef UNSTARTED_RUNTIME_JNI_LIST
1985#undef UNSTARTED_DIRECT
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001986}
1987
Andreas Gampe799681b2015-05-15 19:24:12 -07001988void UnstartedRuntime::InitializeJNIHandlers() {
1989#define UNSTARTED_JNI(ShortName, Sig) \
1990 jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
1991#include "unstarted_runtime_list.h"
1992 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
1993#undef UNSTARTED_RUNTIME_DIRECT_LIST
1994#undef UNSTARTED_RUNTIME_JNI_LIST
1995#undef UNSTARTED_JNI
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001996}
1997
Andreas Gampe799681b2015-05-15 19:24:12 -07001998void UnstartedRuntime::Initialize() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001999 CHECK(!tables_initialized_);
2000
Andreas Gampe799681b2015-05-15 19:24:12 -07002001 InitializeInvokeHandlers();
2002 InitializeJNIHandlers();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002003
2004 tables_initialized_ = true;
2005}
2006
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002007void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
Andreas Gampe799681b2015-05-15 19:24:12 -07002008 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002009 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
2010 // problems in core libraries.
2011 CHECK(tables_initialized_);
2012
David Sehr709b0702016-10-13 09:12:37 -07002013 std::string name(ArtMethod::PrettyMethod(shadow_frame->GetMethod()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002014 const auto& iter = invoke_handlers_.find(name);
2015 if (iter != invoke_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07002016 // Clear out the result in case it's not zeroed out.
Yi Kong4b22b342018-08-02 14:43:21 -07002017 result->SetL(nullptr);
Andreas Gampe715fdc22016-04-18 17:07:30 -07002018
2019 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
2020 self->PushShadowFrame(shadow_frame);
2021
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002022 (*iter->second)(self, shadow_frame, result, arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07002023
2024 self->PopShadowFrame();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002025 } else {
2026 // Not special, continue with regular interpreter execution.
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002027 ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002028 }
2029}
2030
2031// 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 -07002032void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe799681b2015-05-15 19:24:12 -07002033 uint32_t* args, JValue* result) {
David Sehr709b0702016-10-13 09:12:37 -07002034 std::string name(ArtMethod::PrettyMethod(method));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002035 const auto& iter = jni_handlers_.find(name);
2036 if (iter != jni_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07002037 // Clear out the result in case it's not zeroed out.
Yi Kong4b22b342018-08-02 14:43:21 -07002038 result->SetL(nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002039 (*iter->second)(self, method, receiver, args, result);
2040 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02002041 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
2042 name.c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002043 } else {
David Sehr709b0702016-10-13 09:12:37 -07002044 LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002045 "non-transactional runtime";
2046 }
2047}
2048
2049} // namespace interpreter
2050} // namespace art