blob: 9bc2179b6307d76f42ea89c8c28c97878a367e2c [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 Gampe70f5fd02018-10-24 19:58:37 -070049#include "mirror/class-alloc-inl.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"
Andreas Gampefd63bbf2018-10-29 12:55:35 -070055#include "mirror/string-alloc-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070056#include "mirror/string-inl.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070057#include "nativehelper/scoped_local_ref.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070058#include "nth_caller_visitor.h"
Andreas Gampe715fdc22016-04-18 17:07:30 -070059#include "reflection.h"
Andreas Gampe513061a2017-06-01 09:17:34 -070060#include "thread-inl.h"
Sebastien Hertz2fd7e692015-04-02 11:11:19 +020061#include "transaction.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070062#include "well_known_classes.h"
63
64namespace art {
65namespace interpreter {
66
Andreas Gampe46ee31b2016-12-14 10:11:49 -080067using android::base::StringAppendV;
68using android::base::StringPrintf;
69
Andreas Gampe068b0c02015-03-11 12:44:47 -070070static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
Sebastien Hertz45b15972015-04-03 16:07:05 +020071 __attribute__((__format__(__printf__, 2, 3)))
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070072 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertz45b15972015-04-03 16:07:05 +020073
74static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
Andreas Gampe068b0c02015-03-11 12:44:47 -070075 va_list args;
Andreas Gampe068b0c02015-03-11 12:44:47 -070076 if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +020077 va_start(args, fmt);
78 AbortTransactionV(self, fmt, args);
Andreas Gampe068b0c02015-03-11 12:44:47 -070079 va_end(args);
80 } else {
Sebastien Hertz45b15972015-04-03 16:07:05 +020081 va_start(args, fmt);
82 std::string msg;
83 StringAppendV(&msg, fmt, args);
84 va_end(args);
85 LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
Andreas Gampe068b0c02015-03-11 12:44:47 -070086 UNREACHABLE();
87 }
88}
89
Andreas Gampe8ce9c302016-04-15 21:24:28 -070090// Restricted support for character upper case / lower case. Only support ASCII, where
91// it's easy. Abort the transaction otherwise.
92static void CharacterLowerUpper(Thread* self,
93 ShadowFrame* shadow_frame,
94 JValue* result,
95 size_t arg_offset,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070096 bool to_lower_case) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8ce9c302016-04-15 21:24:28 -070097 uint32_t int_value = static_cast<uint32_t>(shadow_frame->GetVReg(arg_offset));
98
99 // Only ASCII (7-bit).
100 if (!isascii(int_value)) {
101 AbortTransactionOrFail(self,
102 "Only support ASCII characters for toLowerCase/toUpperCase: %u",
103 int_value);
104 return;
105 }
106
107 std::locale c_locale("C");
108 char char_value = static_cast<char>(int_value);
109
110 if (to_lower_case) {
111 result->SetI(std::tolower(char_value, c_locale));
112 } else {
113 result->SetI(std::toupper(char_value, c_locale));
114 }
115}
116
117void UnstartedRuntime::UnstartedCharacterToLowerCase(
118 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
119 CharacterLowerUpper(self, shadow_frame, result, arg_offset, true);
120}
121
122void UnstartedRuntime::UnstartedCharacterToUpperCase(
123 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
124 CharacterLowerUpper(self, shadow_frame, result, arg_offset, false);
125}
126
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700127// Helper function to deal with class loading in an unstarted runtime.
128static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
129 Handle<mirror::ClassLoader> class_loader, JValue* result,
130 const std::string& method_name, bool initialize_class,
131 bool abort_if_not_found)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700132 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampefa4333d2017-02-14 11:10:34 -0800133 CHECK(className != nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700134 std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
135 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
136
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100137 ObjPtr<mirror::Class> found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700138 if (found == nullptr && abort_if_not_found) {
139 if (!self->IsExceptionPending()) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700140 AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
David Sehr709b0702016-10-13 09:12:37 -0700141 method_name.c_str(),
142 PrettyDescriptor(descriptor.c_str()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700143 }
144 return;
145 }
146 if (found != nullptr && initialize_class) {
147 StackHandleScope<1> hs(self);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100148 HandleWrapperObjPtr<mirror::Class> h_class = hs.NewHandleWrapper(&found);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700149 if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
150 CHECK(self->IsExceptionPending());
151 return;
152 }
153 }
154 result->SetL(found);
155}
156
157// Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
158// rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
159// ClassNotFoundException), so need to do the same. The only exception is if the exception is
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200160// actually the transaction abort exception. This must not be wrapped, as it signals an
161// initialization abort.
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700162static void CheckExceptionGenerateClassNotFound(Thread* self)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700163 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700164 if (self->IsExceptionPending()) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200165 // If it is not the transaction abort exception, wrap it.
David Sehr709b0702016-10-13 09:12:37 -0700166 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200167 if (type != Transaction::kAbortExceptionDescriptor) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700168 self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
169 "ClassNotFoundException");
170 }
171 }
172}
173
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700174static mirror::String* GetClassName(Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700175 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700176 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
177 if (param == nullptr) {
178 AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
179 return nullptr;
180 }
181 return param->AsString();
182}
183
David Brazdila02cb112018-01-31 11:36:39 +0000184template<typename T>
185static ALWAYS_INLINE bool ShouldBlockAccessToMember(T* member, ShadowFrame* frame)
186 REQUIRES_SHARED(Locks::mutator_lock_) {
Narayan Kamathf5f1f802018-04-03 15:23:46 +0100187 // All uses in this file are from reflection
188 constexpr hiddenapi::AccessMethod access_method = hiddenapi::kReflection;
189 return hiddenapi::GetMemberAction(
David Brazdil8ce3bfa2018-03-12 18:01:18 +0000190 member,
191 frame->GetMethod()->GetDeclaringClass()->GetClassLoader(),
David Brazdil8e1a7cb2018-03-27 08:14:25 +0000192 frame->GetMethod()->GetDeclaringClass()->GetDexCache(),
Narayan Kamathf5f1f802018-04-03 15:23:46 +0100193 access_method) == hiddenapi::kDeny;
David Brazdila02cb112018-01-31 11:36:39 +0000194}
195
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800196void UnstartedRuntime::UnstartedClassForNameCommon(Thread* self,
197 ShadowFrame* shadow_frame,
198 JValue* result,
199 size_t arg_offset,
200 bool long_form,
201 const char* caller) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700202 mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
203 if (class_name == nullptr) {
204 return;
205 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800206 bool initialize_class;
207 mirror::ClassLoader* class_loader;
208 if (long_form) {
209 initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
210 class_loader = down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
211 } else {
212 initialize_class = true;
213 // TODO: This is really only correct for the boot classpath, and for robustness we should
214 // check the caller.
215 class_loader = nullptr;
216 }
217
218 ScopedObjectAccessUnchecked soa(self);
219 if (class_loader != nullptr && !ClassLinker::IsBootClassLoader(soa, class_loader)) {
220 AbortTransactionOrFail(self,
221 "Only the boot classloader is supported: %s",
222 mirror::Object::PrettyTypeOf(class_loader).c_str());
223 return;
224 }
225
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700226 StackHandleScope<1> hs(self);
227 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800228 UnstartedRuntimeFindClass(self,
229 h_class_name,
230 ScopedNullHandle<mirror::ClassLoader>(),
231 result,
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800232 caller,
233 initialize_class,
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800234 false);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700235 CheckExceptionGenerateClassNotFound(self);
236}
237
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800238void UnstartedRuntime::UnstartedClassForName(
239 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
240 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, false, "Class.forName");
241}
242
Andreas Gampe799681b2015-05-15 19:24:12 -0700243void UnstartedRuntime::UnstartedClassForNameLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700244 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800245 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.forName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700246}
247
Vladimir Marko7287c4d2018-02-15 10:41:07 +0000248void UnstartedRuntime::UnstartedClassGetPrimitiveClass(
249 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
250 ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
251 ObjPtr<mirror::Class> klass = mirror::Class::GetPrimitiveClass(class_name);
252 if (UNLIKELY(klass == nullptr)) {
253 DCHECK(self->IsExceptionPending());
254 AbortTransactionOrFail(self,
255 "Class.getPrimitiveClass() failed: %s",
256 self->GetException()->GetDetailMessage()->ToModifiedUtf8().c_str());
257 return;
258 }
259 result->SetL(klass);
260}
261
Andreas Gampe799681b2015-05-15 19:24:12 -0700262void UnstartedRuntime::UnstartedClassClassForName(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700263 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800264 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.classForName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700265}
266
Andreas Gampe799681b2015-05-15 19:24:12 -0700267void UnstartedRuntime::UnstartedClassNewInstance(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700268 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
269 StackHandleScope<2> hs(self); // Class, constructor, object.
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700270 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
271 if (param == nullptr) {
272 AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
273 return;
274 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100275 Handle<mirror::Class> h_klass(hs.NewHandle(param->AsClass()));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700276
277 // Check that it's not null.
Andreas Gampefa4333d2017-02-14 11:10:34 -0800278 if (h_klass == nullptr) {
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700279 AbortTransactionOrFail(self, "Class reference is null for newInstance");
280 return;
281 }
282
283 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
284 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100285 if (h_klass->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200286 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700287 h_klass->PrettyClass().c_str());
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700288 return;
289 }
290 }
291
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700292 // There are two situations in which we'll abort this run.
293 // 1) If the class isn't yet initialized and initialization fails.
294 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
295 // Note that 2) could likely be handled here, but for safety abort the transaction.
296 bool ok = false;
Mathieu Chartiere401d142015-04-22 13:56:20 -0700297 auto* cl = Runtime::Current()->GetClassLinker();
298 if (cl->EnsureInitialized(self, h_klass, true, true)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000299 ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
David Brazdila02cb112018-01-31 11:36:39 +0000300 if (cons != nullptr && ShouldBlockAccessToMember(cons, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000301 cons = nullptr;
302 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700303 if (cons != nullptr) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100304 Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800305 CHECK(h_obj != nullptr); // We don't expect OOM at compile-time.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700306 EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700307 if (!self->IsExceptionPending()) {
308 result->SetL(h_obj.Get());
309 ok = true;
310 }
311 } else {
312 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
313 "Could not find default constructor for '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700314 h_klass->PrettyClass().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700315 }
316 }
317 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700318 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
David Sehr709b0702016-10-13 09:12:37 -0700319 h_klass->PrettyClass().c_str(),
320 mirror::Object::PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700321 }
322}
323
Andreas Gampe799681b2015-05-15 19:24:12 -0700324void UnstartedRuntime::UnstartedClassGetDeclaredField(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700325 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700326 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
327 // going the reflective Dex way.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100328 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
329 ObjPtr<mirror::String> name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700330 ArtField* found = nullptr;
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700331 for (ArtField& field : klass->GetIFields()) {
332 if (name2->Equals(field.GetName())) {
333 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700334 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700335 }
336 }
337 if (found == nullptr) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700338 for (ArtField& field : klass->GetSFields()) {
339 if (name2->Equals(field.GetName())) {
340 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700341 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700342 }
343 }
344 }
David Brazdila02cb112018-01-31 11:36:39 +0000345 if (found != nullptr && ShouldBlockAccessToMember(found, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000346 found = nullptr;
347 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700348 if (found == nullptr) {
349 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
350 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
David Sehr709b0702016-10-13 09:12:37 -0700351 klass->PrettyDescriptor().c_str());
Andreas Gampe068b0c02015-03-11 12:44:47 -0700352 return;
353 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700354 Runtime* runtime = Runtime::Current();
Andreas Gampe542451c2016-07-26 09:02:02 -0700355 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Andreas Gampee01e3642016-07-25 13:06:04 -0700356 mirror::Field* field;
357 if (runtime->IsActiveTransaction()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700358 if (pointer_size == PointerSize::k64) {
359 field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
360 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700361 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700362 field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
363 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700364 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700365 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700366 if (pointer_size == PointerSize::k64) {
367 field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
368 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700369 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700370 field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
371 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700372 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700373 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700374 result->SetL(field);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700375}
376
Andreas Gampebc4d2182016-02-22 10:03:12 -0800377// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
378void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
379 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
380 // Special managed code cut-out to allow method lookup in a un-started runtime.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100381 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
Andreas Gampebc4d2182016-02-22 10:03:12 -0800382 if (klass == nullptr) {
383 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
384 return;
385 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100386 ObjPtr<mirror::String> name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
387 ObjPtr<mirror::ObjectArray<mirror::Class>> args =
Andreas Gampebc4d2182016-02-22 10:03:12 -0800388 shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700389 Runtime* runtime = Runtime::Current();
390 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700391 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700392 ObjPtr<mirror::Method> method;
Andreas Gampee01e3642016-07-25 13:06:04 -0700393 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700394 if (pointer_size == PointerSize::k64) {
395 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
396 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700397 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700398 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
399 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700400 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800401 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700402 if (pointer_size == PointerSize::k64) {
403 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
404 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700405 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700406 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
407 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700408 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800409 }
David Brazdila02cb112018-01-31 11:36:39 +0000410 if (method != nullptr && ShouldBlockAccessToMember(method->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000411 method = nullptr;
412 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700413 result->SetL(method);
Andreas Gampebc4d2182016-02-22 10:03:12 -0800414}
415
Andreas Gampe6039e562016-04-05 18:18:43 -0700416// Special managed code cut-out to allow constructor lookup in a un-started runtime.
417void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
418 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100419 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
Andreas Gampe6039e562016-04-05 18:18:43 -0700420 if (klass == nullptr) {
421 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
422 return;
423 }
424 mirror::ObjectArray<mirror::Class>* args =
425 shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700426 Runtime* runtime = Runtime::Current();
427 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700428 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700429 ObjPtr<mirror::Constructor> constructor;
Andreas Gampee01e3642016-07-25 13:06:04 -0700430 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700431 if (pointer_size == PointerSize::k64) {
432 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
433 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700434 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700435 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
436 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700437 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700438 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700439 if (pointer_size == PointerSize::k64) {
440 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
441 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700442 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700443 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
444 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700445 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700446 }
David Brazdil5a61bb72018-01-19 16:59:46 +0000447 if (constructor != nullptr &&
David Brazdila02cb112018-01-31 11:36:39 +0000448 ShouldBlockAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000449 constructor = nullptr;
450 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700451 result->SetL(constructor);
Andreas Gampe6039e562016-04-05 18:18:43 -0700452}
453
Andreas Gampeae78c262017-02-01 20:40:44 -0800454void UnstartedRuntime::UnstartedClassGetDeclaringClass(
455 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
456 StackHandleScope<1> hs(self);
457 Handle<mirror::Class> klass(hs.NewHandle(
458 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
459 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
460 result->SetL(nullptr);
461 return;
462 }
463 // Return null for anonymous classes.
464 JValue is_anon_result;
465 UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
466 if (is_anon_result.GetZ() != 0) {
467 result->SetL(nullptr);
468 return;
469 }
470 result->SetL(annotations::GetDeclaringClass(klass));
471}
472
Andreas Gampe633750c2016-02-19 10:49:50 -0800473void UnstartedRuntime::UnstartedClassGetEnclosingClass(
474 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
475 StackHandleScope<1> hs(self);
476 Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
477 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
478 result->SetL(nullptr);
479 }
David Sehr9323e6e2016-09-13 08:58:35 -0700480 result->SetL(annotations::GetEnclosingClass(klass));
Andreas Gampe633750c2016-02-19 10:49:50 -0800481}
482
Andreas Gampe715fdc22016-04-18 17:07:30 -0700483void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
484 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
485 StackHandleScope<1> hs(self);
486 Handle<mirror::Class> klass(hs.NewHandle(
487 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
488 const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
489 result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
490}
491
Andreas Gampe9486a162017-02-16 15:17:47 -0800492void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
493 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
494 StackHandleScope<1> hs(self);
495 Handle<mirror::Class> klass(hs.NewHandle(
496 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
497
498 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
499 result->SetL(nullptr);
500 return;
501 }
502
503 result->SetL(annotations::GetSignatureAnnotationForClass(klass));
504}
505
Andreas Gampeae78c262017-02-01 20:40:44 -0800506void UnstartedRuntime::UnstartedClassIsAnonymousClass(
507 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
508 StackHandleScope<1> hs(self);
509 Handle<mirror::Class> klass(hs.NewHandle(
510 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
511 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
512 result->SetZ(false);
513 return;
514 }
Vladimir Marko2d3065e2018-05-22 13:56:09 +0100515 ObjPtr<mirror::String> class_name = nullptr;
Andreas Gampeae78c262017-02-01 20:40:44 -0800516 if (!annotations::GetInnerClass(klass, &class_name)) {
517 result->SetZ(false);
518 return;
519 }
520 result->SetZ(class_name == nullptr);
521}
522
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100523static MemMap FindAndExtractEntry(const std::string& jar_file,
524 const char* entry_name,
525 size_t* size,
526 std::string* error_msg) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700527 CHECK(size != nullptr);
528
529 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
530 if (zip_archive == nullptr) {
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100531 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700532 }
533 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
534 if (zip_entry == nullptr) {
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100535 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700536 }
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100537 MemMap tmp_map = zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg);
538 if (!tmp_map.IsValid()) {
539 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700540 }
541
542 // OK, from here everything seems fine.
543 *size = zip_entry->GetUncompressedLength();
544 return tmp_map;
545}
546
547static void GetResourceAsStream(Thread* self,
548 ShadowFrame* shadow_frame,
549 JValue* result,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700550 size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700551 mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
552 if (resource_obj == nullptr) {
553 AbortTransactionOrFail(self, "null name for getResourceAsStream");
554 return;
555 }
556 CHECK(resource_obj->IsString());
557 mirror::String* resource_name = resource_obj->AsString();
558
559 std::string resource_name_str = resource_name->ToModifiedUtf8();
560 if (resource_name_str.empty() || resource_name_str == "/") {
561 AbortTransactionOrFail(self,
562 "Unsupported name %s for getResourceAsStream",
563 resource_name_str.c_str());
564 return;
565 }
566 const char* resource_cstr = resource_name_str.c_str();
567 if (resource_cstr[0] == '/') {
568 resource_cstr++;
569 }
570
571 Runtime* runtime = Runtime::Current();
572
573 std::vector<std::string> split;
574 Split(runtime->GetBootClassPathString(), ':', &split);
575 if (split.empty()) {
576 AbortTransactionOrFail(self,
577 "Boot classpath not set or split error:: %s",
578 runtime->GetBootClassPathString().c_str());
579 return;
580 }
581
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100582 MemMap mem_map;
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700583 size_t map_size;
584 std::string last_error_msg; // Only store the last message (we could concatenate).
585
586 for (const std::string& jar_file : split) {
587 mem_map = FindAndExtractEntry(jar_file, resource_cstr, &map_size, &last_error_msg);
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100588 if (mem_map.IsValid()) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700589 break;
590 }
591 }
592
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100593 if (!mem_map.IsValid()) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700594 // Didn't find it. There's a good chance this will be the same at runtime, but still
595 // conservatively abort the transaction here.
596 AbortTransactionOrFail(self,
597 "Could not find resource %s. Last error was %s.",
598 resource_name_str.c_str(),
599 last_error_msg.c_str());
600 return;
601 }
602
603 StackHandleScope<3> hs(self);
604
605 // Create byte array for content.
606 Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800607 if (h_array == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700608 AbortTransactionOrFail(self, "Could not find/create byte array class");
609 return;
610 }
611 // Copy in content.
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100612 memcpy(h_array->GetData(), mem_map.Begin(), map_size);
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700613 // Be proactive releasing memory.
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100614 mem_map.Reset();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700615
616 // Create a ByteArrayInputStream.
617 Handle<mirror::Class> h_class(hs.NewHandle(
618 runtime->GetClassLinker()->FindClass(self,
619 "Ljava/io/ByteArrayInputStream;",
620 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800621 if (h_class == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700622 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
623 return;
624 }
625 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
626 AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
627 return;
628 }
629
630 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800631 if (h_obj == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700632 AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
633 return;
634 }
635
636 auto* cl = Runtime::Current()->GetClassLinker();
Vladimir Markoba118822017-06-12 15:41:56 +0100637 ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700638 if (constructor == nullptr) {
639 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
640 return;
641 }
642
643 uint32_t args[1];
Vladimir Marko78baed52018-10-11 10:44:58 +0100644 args[0] = reinterpret_cast32<uint32_t>(h_array.Get());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700645 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
646
647 if (self->IsExceptionPending()) {
648 AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
649 return;
650 }
651
652 result->SetL(h_obj.Get());
653}
654
655void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
656 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
657 {
658 mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
659 CHECK(this_obj != nullptr);
660 CHECK(this_obj->IsClassLoader());
661
662 StackHandleScope<1> hs(self);
663 Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
664
665 if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
666 this_classloader_class.Get()) {
667 AbortTransactionOrFail(self,
David Sehr709b0702016-10-13 09:12:37 -0700668 "Unsupported classloader type %s for getResourceAsStream",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700669 mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700670 return;
671 }
672 }
673
674 GetResourceAsStream(self, shadow_frame, result, arg_offset);
675}
676
Andreas Gampe85bef7e2017-02-16 18:13:26 -0800677void UnstartedRuntime::UnstartedConstructorNewInstance0(
678 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
679 // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
680 StackHandleScope<4> hs(self);
681 Handle<mirror::Constructor> m = hs.NewHandle(
682 reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
683 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
684 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
685 shadow_frame->GetVRegReference(arg_offset + 1)));
686 Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
687 if (UNLIKELY(c->IsAbstract())) {
688 AbortTransactionOrFail(self, "Cannot handle abstract classes");
689 return;
690 }
691 // Verify that we can access the class.
692 if (!m->IsAccessible() && !c->IsPublic()) {
693 // Go 2 frames back, this method is always called from newInstance0, which is called from
694 // Constructor.newInstance(Object... args).
695 ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
696 // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
697 // access checks anyways. TODO: Investigate if this the correct behavior.
698 if (caller != nullptr && !caller->CanAccess(c.Get())) {
699 AbortTransactionOrFail(self, "Cannot access class");
700 return;
701 }
702 }
703 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
704 DCHECK(self->IsExceptionPending());
705 return;
706 }
707 if (c->IsClassClass()) {
708 AbortTransactionOrFail(self, "new Class() is not supported");
709 return;
710 }
711
712 // String constructor is replaced by a StringFactory method in InvokeMethod.
713 if (c->IsStringClass()) {
714 // We don't support strings.
715 AbortTransactionOrFail(self, "String construction is not supported");
716 return;
717 }
718
719 Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
720 if (receiver == nullptr) {
721 AbortTransactionOrFail(self, "Could not allocate");
722 return;
723 }
724
725 // It's easier to use reflection to make the call, than create the uint32_t array.
726 {
727 ScopedObjectAccessUnchecked soa(self);
728 ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
729 soa.AddLocalReference<jobject>(m.Get()));
730 ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
731 soa.AddLocalReference<jobject>(receiver.Get()));
732 ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
733 soa.AddLocalReference<jobject>(args.Get()));
734 InvokeMethod(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
735 }
736 if (self->IsExceptionPending()) {
737 AbortTransactionOrFail(self, "Failed running constructor");
738 } else {
739 result->SetL(receiver.Get());
740 }
741}
742
Andreas Gampe799681b2015-05-15 19:24:12 -0700743void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700744 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700745 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
746 mirror::ClassLoader* class_loader =
747 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
748 StackHandleScope<2> hs(self);
749 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
750 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
751 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
752 "VMClassLoader.findLoadedClass", false, false);
753 // This might have an error pending. But semantics are to just return null.
754 if (self->IsExceptionPending()) {
755 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
David Sehr709b0702016-10-13 09:12:37 -0700756 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700757 if (type != "java.lang.InternalError") {
758 self->ClearException();
759 }
760 }
761}
762
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700763// Arraycopy emulation.
764// Note: we can't use any fast copy functions, as they are not available under transaction.
765
766template <typename T>
767static void PrimitiveArrayCopy(Thread* self,
768 mirror::Array* src_array, int32_t src_pos,
769 mirror::Array* dst_array, int32_t dst_pos,
770 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700771 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700772 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700773 AbortTransactionOrFail(self,
774 "Types mismatched in arraycopy: %s vs %s.",
775 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700776 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700777 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700778 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700779 return;
780 }
781 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
782 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
783 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
784 if (copy_forward) {
785 for (int32_t i = 0; i < length; ++i) {
786 dst->Set(dst_pos + i, src->Get(src_pos + i));
787 }
788 } else {
789 for (int32_t i = 1; i <= length; ++i) {
790 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
791 }
792 }
793}
794
Andreas Gampe799681b2015-05-15 19:24:12 -0700795void UnstartedRuntime::UnstartedSystemArraycopy(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700796 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700797 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700798 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
799 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700800 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700801
Andreas Gampe85a098a2016-03-31 13:30:53 -0700802 mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
803 mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
804 // Null checking. For simplicity, abort transaction.
805 if (src_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700806 AbortTransactionOrFail(self, "src is null in arraycopy.");
807 return;
808 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700809 if (dst_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700810 AbortTransactionOrFail(self, "dst is null in arraycopy.");
811 return;
812 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700813 // Test for arrayness. Throw ArrayStoreException.
814 if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
815 self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
816 return;
817 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700818
Andreas Gampe85a098a2016-03-31 13:30:53 -0700819 mirror::Array* src_array = src_obj->AsArray();
820 mirror::Array* dst_array = dst_obj->AsArray();
821
822 // Bounds checking. Throw IndexOutOfBoundsException.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700823 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
824 UNLIKELY(src_pos > src_array->GetLength() - length) ||
825 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700826 self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700827 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
828 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
829 length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700830 return;
831 }
832
833 // Type checking.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100834 ObjPtr<mirror::Class> src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700835 GetComponentType();
836
837 if (!src_type->IsPrimitive()) {
838 // Check that the second type is not primitive.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100839 ObjPtr<mirror::Class> trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700840 GetComponentType();
841 if (trg_type->IsPrimitiveInt()) {
842 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700843 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700844 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700845 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700846 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700847 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700848 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700849
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700850 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
851 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
852 if (src == dst) {
853 // Can overlap, but not have type mismatches.
Andreas Gampe85a098a2016-03-31 13:30:53 -0700854 // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700855 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
856 if (copy_forward) {
857 for (int32_t i = 0; i < length; ++i) {
858 dst->Set(dst_pos + i, src->Get(src_pos + i));
859 }
860 } else {
861 for (int32_t i = 1; i <= length; ++i) {
862 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
863 }
864 }
865 } else {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700866 // We're being lazy here. Optimally this could be a memcpy (if component types are
867 // assignable), but the ObjectArray implementation doesn't support transactions. The
868 // checking version, however, does.
869 if (Runtime::Current()->IsActiveTransaction()) {
870 dst->AssignableCheckingMemcpy<true>(
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700871 dst_pos, src, src_pos, length, /* throw_exception= */ true);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700872 } else {
873 dst->AssignableCheckingMemcpy<false>(
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700874 dst_pos, src, src_pos, length, /* throw_exception= */ true);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700875 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700876 }
Andreas Gampe5c9af612016-04-05 14:16:10 -0700877 } else if (src_type->IsPrimitiveByte()) {
878 PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700879 } else if (src_type->IsPrimitiveChar()) {
880 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
881 } else if (src_type->IsPrimitiveInt()) {
882 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700883 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700884 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700885 src_type->PrettyDescriptor().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700886 }
887}
888
Andreas Gampe5c9af612016-04-05 14:16:10 -0700889void UnstartedRuntime::UnstartedSystemArraycopyByte(
890 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
891 // Just forward.
892 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
893}
894
Andreas Gampe799681b2015-05-15 19:24:12 -0700895void UnstartedRuntime::UnstartedSystemArraycopyChar(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700896 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700897 // Just forward.
898 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
899}
900
901void UnstartedRuntime::UnstartedSystemArraycopyInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700902 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700903 // Just forward.
904 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
905}
906
Narayan Kamath34a316f2016-03-30 13:11:18 +0100907void UnstartedRuntime::UnstartedSystemGetSecurityManager(
908 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
909 JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
910 result->SetL(nullptr);
911}
912
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700913static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
914
915static void GetSystemProperty(Thread* self,
916 ShadowFrame* shadow_frame,
917 JValue* result,
918 size_t arg_offset,
919 bool is_default_version)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700920 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700921 StackHandleScope<4> hs(self);
922 Handle<mirror::String> h_key(
923 hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800924 if (h_key == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700925 AbortTransactionOrFail(self, "getProperty key was null");
926 return;
927 }
928
929 // This is overall inefficient, but reflecting the values here is not great, either. So
930 // for simplicity, and with the assumption that the number of getProperty calls is not
931 // too great, just iterate each time.
932
933 // Get the storage class.
934 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
935 Handle<mirror::Class> h_props_class(hs.NewHandle(
936 class_linker->FindClass(self,
937 "Ljava/lang/AndroidHardcodedSystemProperties;",
938 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800939 if (h_props_class == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700940 AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
941 return;
942 }
943 if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
944 AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
945 return;
946 }
947
948 // Get the storage array.
949 ArtField* static_properties =
950 h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
951 "[[Ljava/lang/String;");
952 if (static_properties == nullptr) {
953 AbortTransactionOrFail(self,
954 "Could not find %s field",
955 kAndroidHardcodedSystemPropertiesFieldName);
956 return;
957 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700958 ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
959 Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
960 props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800961 if (h_2string_array == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700962 AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
963 return;
964 }
965
966 // Iterate over it.
967 const int32_t prop_count = h_2string_array->GetLength();
968 // Use the third handle as mutable.
969 MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
970 hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
971 for (int32_t i = 0; i < prop_count; ++i) {
972 h_string_array.Assign(h_2string_array->Get(i));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800973 if (h_string_array == nullptr ||
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700974 h_string_array->GetLength() != 2 ||
975 h_string_array->Get(0) == nullptr) {
976 AbortTransactionOrFail(self,
977 "Unexpected content of %s",
978 kAndroidHardcodedSystemPropertiesFieldName);
979 return;
980 }
981 if (h_key->Equals(h_string_array->Get(0))) {
982 // Found a value.
983 if (h_string_array->Get(1) == nullptr && is_default_version) {
984 // Null is being delegated to the default map, and then resolved to the given default value.
985 // As there's no default map, return the given value.
986 result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
987 } else {
988 result->SetL(h_string_array->Get(1));
989 }
990 return;
991 }
992 }
993
994 // Key is not supported.
995 AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
996}
997
998void UnstartedRuntime::UnstartedSystemGetProperty(
999 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1000 GetSystemProperty(self, shadow_frame, result, arg_offset, false);
1001}
1002
1003void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
1004 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1005 GetSystemProperty(self, shadow_frame, result, arg_offset, true);
1006}
1007
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001008static std::string GetImmediateCaller(ShadowFrame* shadow_frame)
1009 REQUIRES_SHARED(Locks::mutator_lock_) {
1010 if (shadow_frame->GetLink() == nullptr) {
1011 return "<no caller>";
1012 }
1013 return ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1014}
1015
1016static bool CheckCallers(ShadowFrame* shadow_frame,
1017 std::initializer_list<std::string> allowed_call_stack)
1018 REQUIRES_SHARED(Locks::mutator_lock_) {
1019 for (const std::string& allowed_caller : allowed_call_stack) {
1020 if (shadow_frame->GetLink() == nullptr) {
1021 return false;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001022 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001023
1024 std::string found_caller = ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1025 if (allowed_caller != found_caller) {
1026 return false;
1027 }
1028
1029 shadow_frame = shadow_frame->GetLink();
1030 }
1031 return true;
1032}
1033
1034static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_descriptor)
1035 REQUIRES_SHARED(Locks::mutator_lock_) {
1036 // Find the requested class.
1037 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1038 ObjPtr<mirror::Class> klass =
1039 class_linker->FindClass(self, class_descriptor, ScopedNullHandle<mirror::ClassLoader>());
1040 if (klass == nullptr) {
1041 AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
1042 return nullptr;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001043 }
1044
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001045 StackHandleScope<2> hs(self);
1046 Handle<mirror::Class> h_class(hs.NewHandle(klass));
1047 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001048 if (h_obj != nullptr) {
Vladimir Markoba118822017-06-12 15:41:56 +01001049 ArtMethod* init_method = h_class->FindConstructor("()V", class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001050 if (init_method == nullptr) {
1051 AbortTransactionOrFail(self, "Could not find <init> for %s", class_descriptor);
1052 return nullptr;
1053 } else {
1054 JValue invoke_result;
1055 EnterInterpreterFromInvoke(self, init_method, h_obj.Get(), nullptr, nullptr);
1056 if (!self->IsExceptionPending()) {
1057 return h_obj.Get();
1058 }
1059 AbortTransactionOrFail(self, "Could not run <init> for %s", class_descriptor);
1060 }
1061 }
1062 AbortTransactionOrFail(self, "Could not allocate instance of %s", class_descriptor);
1063 return nullptr;
1064}
1065
1066void UnstartedRuntime::UnstartedThreadLocalGet(
1067 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1068 if (CheckCallers(shadow_frame, { "sun.misc.FloatingDecimal$BinaryToASCIIBuffer "
1069 "sun.misc.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1070 result->SetL(CreateInstanceOf(self, "Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;"));
1071 } else {
1072 AbortTransactionOrFail(self,
1073 "ThreadLocal.get() does not support %s",
1074 GetImmediateCaller(shadow_frame).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001075 }
1076}
1077
Andreas Gampebad529d2017-02-13 18:52:10 -08001078void UnstartedRuntime::UnstartedThreadCurrentThread(
1079 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1080 if (CheckCallers(shadow_frame,
1081 { "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
Paul Duffin7ec95c52018-08-01 15:09:37 +01001082 "java.lang.String, long, java.security.AccessControlContext)",
1083 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
Andreas Gampebad529d2017-02-13 18:52:10 -08001084 "java.lang.String, long)",
1085 "void java.lang.Thread.<init>()",
1086 "void java.util.logging.LogManager$Cleaner.<init>("
1087 "java.util.logging.LogManager)" })) {
1088 // Whitelist LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
1089 // Thread constructor only asks for the current thread to set up defaults and add the
1090 // thread as unstarted to the ThreadGroup. A faked-up main thread peer is good enough for
1091 // these purposes.
1092 Runtime::Current()->InitThreadGroups(self);
1093 jobject main_peer =
1094 self->CreateCompileTimePeer(self->GetJniEnv(),
1095 "main",
1096 false,
1097 Runtime::Current()->GetMainThreadGroup());
1098 if (main_peer == nullptr) {
1099 AbortTransactionOrFail(self, "Failed allocating peer");
1100 return;
1101 }
1102
1103 result->SetL(self->DecodeJObject(main_peer));
1104 self->GetJniEnv()->DeleteLocalRef(main_peer);
1105 } else {
1106 AbortTransactionOrFail(self,
1107 "Thread.currentThread() does not support %s",
1108 GetImmediateCaller(shadow_frame).c_str());
1109 }
1110}
1111
1112void UnstartedRuntime::UnstartedThreadGetNativeState(
1113 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1114 if (CheckCallers(shadow_frame,
1115 { "java.lang.Thread$State java.lang.Thread.getState()",
1116 "java.lang.ThreadGroup java.lang.Thread.getThreadGroup()",
1117 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
Paul Duffin7ec95c52018-08-01 15:09:37 +01001118 "java.lang.String, long, java.security.AccessControlContext)",
1119 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
Andreas Gampebad529d2017-02-13 18:52:10 -08001120 "java.lang.String, long)",
1121 "void java.lang.Thread.<init>()",
1122 "void java.util.logging.LogManager$Cleaner.<init>("
1123 "java.util.logging.LogManager)" })) {
1124 // Whitelist reading the state of the "main" thread when creating another (unstarted) thread
1125 // for LogManager. Report the thread as "new" (it really only counts that it isn't terminated).
1126 constexpr int32_t kJavaRunnable = 1;
1127 result->SetI(kJavaRunnable);
1128 } else {
1129 AbortTransactionOrFail(self,
1130 "Thread.getNativeState() does not support %s",
1131 GetImmediateCaller(shadow_frame).c_str());
1132 }
1133}
1134
Sergio Giro83261202016-04-11 20:49:20 +01001135void UnstartedRuntime::UnstartedMathCeil(
1136 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001137 result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
Sergio Giro83261202016-04-11 20:49:20 +01001138}
1139
1140void UnstartedRuntime::UnstartedMathFloor(
1141 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001142 result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001143}
1144
Andreas Gampeb8a00f92016-04-18 20:51:13 -07001145void UnstartedRuntime::UnstartedMathSin(
1146 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1147 result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
1148}
1149
1150void UnstartedRuntime::UnstartedMathCos(
1151 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1152 result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
1153}
1154
1155void UnstartedRuntime::UnstartedMathPow(
1156 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1157 result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
1158 shadow_frame->GetVRegDouble(arg_offset + 2)));
1159}
1160
Andreas Gampe799681b2015-05-15 19:24:12 -07001161void UnstartedRuntime::UnstartedObjectHashCode(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001162 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001163 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1164 result->SetI(obj->IdentityHashCode());
1165}
1166
Andreas Gampe799681b2015-05-15 19:24:12 -07001167void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
Andreas Gampedd9d0552015-03-09 12:57:41 -07001168 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001169 double in = shadow_frame->GetVRegDouble(arg_offset);
Roland Levillainda4d79b2015-03-24 14:36:11 +00001170 result->SetJ(bit_cast<int64_t, double>(in));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001171}
1172
Andreas Gampedd9d0552015-03-09 12:57:41 -07001173static void UnstartedMemoryPeek(
1174 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1175 int64_t address = shadow_frame->GetVRegLong(arg_offset);
1176 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
1177 // aborting the transaction.
1178
1179 switch (type) {
1180 case Primitive::kPrimByte: {
1181 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
1182 return;
1183 }
1184
1185 case Primitive::kPrimShort: {
Andreas Gampec55bb392018-09-21 00:02:02 +00001186 using unaligned_short __attribute__((__aligned__(1))) = int16_t;
Andreas Gampe799681b2015-05-15 19:24:12 -07001187 result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001188 return;
1189 }
1190
1191 case Primitive::kPrimInt: {
Andreas Gampec55bb392018-09-21 00:02:02 +00001192 using unaligned_int __attribute__((__aligned__(1))) = int32_t;
Andreas Gampe799681b2015-05-15 19:24:12 -07001193 result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001194 return;
1195 }
1196
1197 case Primitive::kPrimLong: {
Andreas Gampec55bb392018-09-21 00:02:02 +00001198 using unaligned_long __attribute__((__aligned__(1))) = int64_t;
Andreas Gampe799681b2015-05-15 19:24:12 -07001199 result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001200 return;
1201 }
1202
1203 case Primitive::kPrimBoolean:
1204 case Primitive::kPrimChar:
1205 case Primitive::kPrimFloat:
1206 case Primitive::kPrimDouble:
1207 case Primitive::kPrimVoid:
1208 case Primitive::kPrimNot:
1209 LOG(FATAL) << "Not in the Memory API: " << type;
1210 UNREACHABLE();
1211 }
1212 LOG(FATAL) << "Should not reach here";
1213 UNREACHABLE();
1214}
1215
Andreas Gampe799681b2015-05-15 19:24:12 -07001216void UnstartedRuntime::UnstartedMemoryPeekByte(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001217 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001218 UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
1219}
1220
1221void UnstartedRuntime::UnstartedMemoryPeekShort(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001222 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001223 UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
1224}
1225
1226void UnstartedRuntime::UnstartedMemoryPeekInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001227 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001228 UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
1229}
1230
1231void UnstartedRuntime::UnstartedMemoryPeekLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001232 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001233 UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001234}
1235
1236static void UnstartedMemoryPeekArray(
1237 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001238 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampedd9d0552015-03-09 12:57:41 -07001239 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1240 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1241 if (obj == nullptr) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001242 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
Andreas Gampedd9d0552015-03-09 12:57:41 -07001243 return;
1244 }
1245 mirror::Array* array = obj->AsArray();
1246
1247 int offset = shadow_frame->GetVReg(arg_offset + 3);
1248 int count = shadow_frame->GetVReg(arg_offset + 4);
1249 if (offset < 0 || offset + count > array->GetLength()) {
1250 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
1251 offset, count, array->GetLength()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001252 Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
Andreas Gampedd9d0552015-03-09 12:57:41 -07001253 return;
1254 }
1255
1256 switch (type) {
1257 case Primitive::kPrimByte: {
1258 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
1259 mirror::ByteArray* byte_array = array->AsByteArray();
1260 for (int32_t i = 0; i < count; ++i, ++address) {
1261 byte_array->SetWithoutChecks<true>(i + offset, *address);
1262 }
1263 return;
1264 }
1265
1266 case Primitive::kPrimShort:
1267 case Primitive::kPrimInt:
1268 case Primitive::kPrimLong:
1269 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1270 UNREACHABLE();
1271
1272 case Primitive::kPrimBoolean:
1273 case Primitive::kPrimChar:
1274 case Primitive::kPrimFloat:
1275 case Primitive::kPrimDouble:
1276 case Primitive::kPrimVoid:
1277 case Primitive::kPrimNot:
1278 LOG(FATAL) << "Not in the Memory API: " << type;
1279 UNREACHABLE();
1280 }
1281 LOG(FATAL) << "Should not reach here";
1282 UNREACHABLE();
1283}
1284
Andreas Gampe799681b2015-05-15 19:24:12 -07001285void UnstartedRuntime::UnstartedMemoryPeekByteArray(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001286 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001287 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001288}
1289
Kenny Root1c9e61c2015-05-14 15:58:17 -07001290// This allows reading the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001291void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001292 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001293 jint start = shadow_frame->GetVReg(arg_offset + 1);
1294 jint end = shadow_frame->GetVReg(arg_offset + 2);
1295 jint index = shadow_frame->GetVReg(arg_offset + 4);
1296 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1297 if (string == nullptr) {
1298 AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1299 return;
1300 }
Kenny Root57f91e82015-05-14 15:58:17 -07001301 DCHECK_GE(start, 0);
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001302 DCHECK_LE(start, end);
1303 DCHECK_LE(end, string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001304 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001305 Handle<mirror::CharArray> h_char_array(
1306 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001307 DCHECK_GE(index, 0);
Kenny Root57f91e82015-05-14 15:58:17 -07001308 DCHECK_LE(index, h_char_array->GetLength());
1309 DCHECK_LE(end - start, h_char_array->GetLength() - index);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001310 string->GetChars(start, end, h_char_array, index);
1311}
1312
1313// This allows reading chars from the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001314void UnstartedRuntime::UnstartedStringCharAt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001315 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001316 jint index = shadow_frame->GetVReg(arg_offset + 1);
1317 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1318 if (string == nullptr) {
1319 AbortTransactionOrFail(self, "String.charAt with null object");
1320 return;
1321 }
1322 result->SetC(string->CharAt(index));
1323}
1324
Vladimir Marko92907f32017-02-20 14:08:30 +00001325// This allows creating String objects with replaced characters during compilation.
1326// String.doReplace(char, char) is called from String.replace(char, char) when there is a match.
1327void UnstartedRuntime::UnstartedStringDoReplace(
1328 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1329 jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
1330 jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001331 StackHandleScope<1> hs(self);
1332 Handle<mirror::String> string =
1333 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
Kenny Root57f91e82015-05-14 15:58:17 -07001334 if (string == nullptr) {
Vladimir Marko92907f32017-02-20 14:08:30 +00001335 AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
Kenny Root57f91e82015-05-14 15:58:17 -07001336 return;
1337 }
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001338 result->SetL(mirror::String::DoReplace(self, string, old_c, new_c));
Kenny Root57f91e82015-05-14 15:58:17 -07001339}
1340
Kenny Root1c9e61c2015-05-14 15:58:17 -07001341// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001342void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001343 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001344 jint offset = shadow_frame->GetVReg(arg_offset);
1345 jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1346 DCHECK_GE(char_count, 0);
1347 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001348 Handle<mirror::CharArray> h_char_array(
1349 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
Kenny Root1c9e61c2015-05-14 15:58:17 -07001350 Runtime* runtime = Runtime::Current();
1351 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1352 result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator));
1353}
1354
1355// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001356void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001357 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root57f91e82015-05-14 15:58:17 -07001358 mirror::String* to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1359 if (to_copy == nullptr) {
1360 AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1361 return;
1362 }
1363 StackHandleScope<1> hs(self);
1364 Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1365 Runtime* runtime = Runtime::Current();
1366 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1367 result->SetL(mirror::String::AllocFromString<true>(self, h_string->GetLength(), h_string, 0,
1368 allocator));
1369}
1370
Andreas Gampe799681b2015-05-15 19:24:12 -07001371void UnstartedRuntime::UnstartedStringFastSubstring(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001372 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001373 jint start = shadow_frame->GetVReg(arg_offset + 1);
1374 jint length = shadow_frame->GetVReg(arg_offset + 2);
Kenny Root57f91e82015-05-14 15:58:17 -07001375 DCHECK_GE(start, 0);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001376 DCHECK_GE(length, 0);
1377 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001378 Handle<mirror::String> h_string(
1379 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
Kenny Root57f91e82015-05-14 15:58:17 -07001380 DCHECK_LE(start, h_string->GetLength());
1381 DCHECK_LE(start + length, h_string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001382 Runtime* runtime = Runtime::Current();
1383 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1384 result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator));
1385}
1386
Kenny Root57f91e82015-05-14 15:58:17 -07001387// This allows getting the char array for new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001388void UnstartedRuntime::UnstartedStringToCharArray(
Kenny Root57f91e82015-05-14 15:58:17 -07001389 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001390 REQUIRES_SHARED(Locks::mutator_lock_) {
Kenny Root57f91e82015-05-14 15:58:17 -07001391 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1392 if (string == nullptr) {
1393 AbortTransactionOrFail(self, "String.charAt with null object");
1394 return;
1395 }
1396 result->SetL(string->ToCharArray(self));
1397}
1398
Andreas Gampebc4d2182016-02-22 10:03:12 -08001399// This allows statically initializing ConcurrentHashMap and SynchronousQueue.
1400void UnstartedRuntime::UnstartedReferenceGetReferent(
1401 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001402 ObjPtr<mirror::Reference> const ref = down_cast<mirror::Reference*>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001403 shadow_frame->GetVRegReference(arg_offset));
1404 if (ref == nullptr) {
1405 AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1406 return;
1407 }
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001408 ObjPtr<mirror::Object> const referent =
Andreas Gampebc4d2182016-02-22 10:03:12 -08001409 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1410 result->SetL(referent);
1411}
1412
1413// This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1414// conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1415// where we can predict the behavior (somewhat).
1416// Note: this is required (instead of lazy initialization) as these classes are used in the static
1417// initialization of other classes, so will *use* the value.
1418void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1419 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001420 if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001421 // SynchronousQueue really only separates between single- and multiprocessor case. Return
1422 // 8 as a conservative upper approximation.
1423 result->SetI(8);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001424 } else if (CheckCallers(shadow_frame,
1425 { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001426 // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1427 // a good upper bound.
1428 // TODO: Consider resetting in the zygote?
1429 result->SetI(8);
1430 } else {
1431 // Not supported.
1432 AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1433 }
1434}
1435
1436// This allows accessing ConcurrentHashMap/SynchronousQueue.
1437
1438void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1439 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1440 // Argument 0 is the Unsafe instance, skip.
1441 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1442 if (obj == nullptr) {
1443 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1444 return;
1445 }
1446 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1447 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1448 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001449 bool success;
1450 // Check whether we're in a transaction, call accordingly.
1451 if (Runtime::Current()->IsActiveTransaction()) {
1452 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1453 expectedValue,
1454 newValue);
1455 } else {
1456 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1457 expectedValue,
1458 newValue);
1459 }
1460 result->SetZ(success ? 1 : 0);
1461}
1462
1463void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1464 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1465 // Argument 0 is the Unsafe instance, skip.
1466 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1467 if (obj == nullptr) {
1468 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1469 return;
1470 }
1471 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1472 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1473 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 5);
1474
1475 // Must use non transactional mode.
1476 if (kUseReadBarrier) {
1477 // Need to make sure the reference stored in the field is a to-space one before attempting the
1478 // CAS or the CAS could fail incorrectly.
1479 mirror::HeapReference<mirror::Object>* field_addr =
1480 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1481 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001482 ReadBarrier::Barrier<
1483 mirror::Object,
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001484 /* kIsVolatile= */ false,
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001485 kWithReadBarrier,
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001486 /* kAlwaysUpdateField= */ true>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001487 obj,
1488 MemberOffset(offset),
1489 field_addr);
1490 }
1491 bool success;
1492 // Check whether we're in a transaction, call accordingly.
1493 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001494 success = obj->CasFieldObject<true>(MemberOffset(offset),
1495 expected_value,
1496 newValue,
1497 CASMode::kStrong,
1498 std::memory_order_seq_cst);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001499 } else {
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001500 success = obj->CasFieldObject<false>(MemberOffset(offset),
1501 expected_value,
1502 newValue,
1503 CASMode::kStrong,
1504 std::memory_order_seq_cst);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001505 }
1506 result->SetZ(success ? 1 : 0);
1507}
1508
1509void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1510 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001511 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001512 // Argument 0 is the Unsafe instance, skip.
1513 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1514 if (obj == nullptr) {
1515 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1516 return;
1517 }
1518 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1519 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1520 result->SetL(value);
1521}
1522
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001523void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1524 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001525 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001526 // Argument 0 is the Unsafe instance, skip.
1527 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1528 if (obj == nullptr) {
1529 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1530 return;
1531 }
1532 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1533 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1534 if (Runtime::Current()->IsActiveTransaction()) {
1535 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1536 } else {
1537 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1538 }
1539}
1540
Andreas Gampebc4d2182016-02-22 10:03:12 -08001541void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1542 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001543 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001544 // Argument 0 is the Unsafe instance, skip.
1545 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1546 if (obj == nullptr) {
1547 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1548 return;
1549 }
1550 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1551 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 4);
Orion Hodson27b96762018-03-13 16:06:57 +00001552 std::atomic_thread_fence(std::memory_order_release);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001553 if (Runtime::Current()->IsActiveTransaction()) {
1554 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1555 } else {
1556 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1557 }
1558}
1559
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001560// A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1561// of correctly handling the corner cases.
1562void UnstartedRuntime::UnstartedIntegerParseInt(
1563 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001564 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001565 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1566 if (obj == nullptr) {
1567 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1568 return;
1569 }
1570
1571 std::string string_value = obj->AsString()->ToModifiedUtf8();
1572 if (string_value.empty()) {
1573 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1574 return;
1575 }
1576
1577 const char* c_str = string_value.c_str();
1578 char *end;
1579 // Can we set errno to 0? Is this always a variable, and not a macro?
1580 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1581 int64_t l = strtol(c_str, &end, 10);
1582
1583 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1584 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1585 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1586 return;
1587 }
1588 if (l == 0) {
1589 // Check whether the string wasn't exactly zero.
1590 if (string_value != "0") {
1591 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1592 return;
1593 }
1594 } else if (*end != '\0') {
1595 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1596 return;
1597 }
1598
1599 result->SetI(static_cast<int32_t>(l));
1600}
1601
1602// A cutout for Long.parseLong.
1603//
1604// Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1605// well.
1606void UnstartedRuntime::UnstartedLongParseLong(
1607 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001608 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001609 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1610 if (obj == nullptr) {
1611 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1612 return;
1613 }
1614
1615 std::string string_value = obj->AsString()->ToModifiedUtf8();
1616 if (string_value.empty()) {
1617 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1618 return;
1619 }
1620
1621 const char* c_str = string_value.c_str();
1622 char *end;
1623 // Can we set errno to 0? Is this always a variable, and not a macro?
1624 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1625 int64_t l = strtol(c_str, &end, 10);
1626
1627 // Note: comparing against int32_t min/max is intentional here.
1628 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1629 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1630 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1631 return;
1632 }
1633 if (l == 0) {
1634 // Check whether the string wasn't exactly zero.
1635 if (string_value != "0") {
1636 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1637 return;
1638 }
1639 } else if (*end != '\0') {
1640 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1641 return;
1642 }
1643
1644 result->SetJ(l);
1645}
1646
Andreas Gampe715fdc22016-04-18 17:07:30 -07001647void UnstartedRuntime::UnstartedMethodInvoke(
1648 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001649 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe715fdc22016-04-18 17:07:30 -07001650 JNIEnvExt* env = self->GetJniEnv();
1651 ScopedObjectAccessUnchecked soa(self);
1652
Mathieu Chartier8778c522016-10-04 19:06:30 -07001653 ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001654 ScopedLocalRef<jobject> java_method(env,
Roland Levillain5e8d5f02016-10-18 18:03:43 +01001655 java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001656
Mathieu Chartier8778c522016-10-04 19:06:30 -07001657 ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001658 ScopedLocalRef<jobject> java_receiver(env,
1659 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1660
Mathieu Chartier8778c522016-10-04 19:06:30 -07001661 ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001662 ScopedLocalRef<jobject> java_args(env,
1663 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1664
1665 ScopedLocalRef<jobject> result_jobj(env,
1666 InvokeMethod(soa, java_method.get(), java_receiver.get(), java_args.get()));
1667
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001668 result->SetL(self->DecodeJObject(result_jobj.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001669
1670 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1671 // InvocationTargetExceptions.
1672 if (self->IsExceptionPending()) {
1673 AbortTransactionOrFail(self, "Failed Method.invoke");
1674 }
1675}
1676
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001677void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1678 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1679 REQUIRES_SHARED(Locks::mutator_lock_) {
1680 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1681 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1682}
Andreas Gampebc4d2182016-02-22 10:03:12 -08001683
Orion Hodson43f0cdb2017-10-10 14:47:32 +01001684// Checks whether the runtime is s64-bit. This is needed for the clinit of
1685// java.lang.invoke.VarHandle clinit. The clinit determines sets of
1686// available VarHandle accessors and these differ based on machine
1687// word size.
1688void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1689 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1690 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1691 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1692 jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1693 result->SetZ(is64bit);
1694}
1695
Mathieu Chartiere401d142015-04-22 13:56:20 -07001696void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
Vladimir Marko78baed52018-10-11 10:44:58 +01001697 Thread* self,
1698 ArtMethod* method ATTRIBUTE_UNUSED,
1699 mirror::Object* receiver ATTRIBUTE_UNUSED,
1700 uint32_t* args,
1701 JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001702 int32_t length = args[1];
1703 DCHECK_GE(length, 0);
Vladimir Marko78baed52018-10-11 10:44:58 +01001704 ObjPtr<mirror::Object> element_class = reinterpret_cast32<mirror::Object*>(args[0])->AsClass();
1705 if (element_class == nullptr) {
1706 AbortTransactionOrFail(self, "VMRuntime.newUnpaddedArray with null element_class.");
1707 return;
1708 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001709 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001710 ObjPtr<mirror::Class> array_class =
Vladimir Marko78baed52018-10-11 10:44:58 +01001711 runtime->GetClassLinker()->FindArrayClass(self, element_class->AsClass());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001712 DCHECK(array_class != nullptr);
1713 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001714 result->SetL(mirror::Array::Alloc<true, true>(self,
1715 array_class,
1716 length,
1717 array_class->GetComponentSizeShift(),
1718 allocator));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001719}
1720
Mathieu Chartiere401d142015-04-22 13:56:20 -07001721void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1722 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1723 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001724 result->SetL(nullptr);
1725}
1726
Mathieu Chartiere401d142015-04-22 13:56:20 -07001727void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1728 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1729 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001730 NthCallerVisitor visitor(self, 3);
1731 visitor.WalkStack();
1732 if (visitor.caller != nullptr) {
1733 result->SetL(visitor.caller->GetDeclaringClass());
1734 }
1735}
1736
Mathieu Chartiere401d142015-04-22 13:56:20 -07001737void UnstartedRuntime::UnstartedJNIMathLog(
1738 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1739 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001740 JValue value;
1741 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1742 result->SetD(log(value.GetD()));
1743}
1744
Mathieu Chartiere401d142015-04-22 13:56:20 -07001745void UnstartedRuntime::UnstartedJNIMathExp(
1746 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1747 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001748 JValue value;
1749 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1750 result->SetD(exp(value.GetD()));
1751}
1752
Andreas Gampebc4d2182016-02-22 10:03:12 -08001753void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1754 Thread* self ATTRIBUTE_UNUSED,
1755 ArtMethod* method ATTRIBUTE_UNUSED,
1756 mirror::Object* receiver ATTRIBUTE_UNUSED,
1757 uint32_t* args ATTRIBUTE_UNUSED,
1758 JValue* result) {
1759 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1760 ? 0
1761 : 1);
1762}
1763
Mathieu Chartiere401d142015-04-22 13:56:20 -07001764void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1765 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1766 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001767 StackHandleScope<1> hs(self);
1768 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1769}
1770
Andreas Gampebc4d2182016-02-22 10:03:12 -08001771void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1772 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1773 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1774 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1775 result->SetD(bit_cast<double>(long_input));
1776}
1777
Mathieu Chartiere401d142015-04-22 13:56:20 -07001778void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1779 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1780 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001781 result->SetI(args[0]);
1782}
1783
Mathieu Chartiere401d142015-04-22 13:56:20 -07001784void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1785 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1786 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001787 result->SetI(args[0]);
1788}
1789
Mathieu Chartiere401d142015-04-22 13:56:20 -07001790void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1791 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1792 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001793 result->SetL(receiver->Clone(self));
1794}
1795
Mathieu Chartiere401d142015-04-22 13:56:20 -07001796void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1797 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1798 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001799 receiver->NotifyAll(self);
1800}
1801
Vladimir Marko78baed52018-10-11 10:44:58 +01001802void UnstartedRuntime::UnstartedJNIStringCompareTo(Thread* self,
1803 ArtMethod* method ATTRIBUTE_UNUSED,
1804 mirror::Object* receiver,
1805 uint32_t* args,
1806 JValue* result) {
1807 ObjPtr<mirror::Object> rhs = reinterpret_cast32<mirror::Object*>(args[0]);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001808 if (rhs == nullptr) {
Vladimir Marko78baed52018-10-11 10:44:58 +01001809 AbortTransactionOrFail(self, "String.compareTo with null object.");
1810 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001811 }
Vladimir Marko78baed52018-10-11 10:44:58 +01001812 result->SetI(receiver->AsString()->CompareTo(rhs->AsString()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001813}
1814
Mathieu Chartiere401d142015-04-22 13:56:20 -07001815void UnstartedRuntime::UnstartedJNIStringIntern(
1816 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1817 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001818 result->SetL(receiver->AsString()->Intern());
1819}
1820
Mathieu Chartiere401d142015-04-22 13:56:20 -07001821void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1822 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1823 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001824 StackHandleScope<2> hs(self);
1825 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1826 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1827 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1828}
1829
Mathieu Chartiere401d142015-04-22 13:56:20 -07001830void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1831 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1832 uint32_t* args, JValue* result) {
Andreas Gampee598e042015-04-10 14:57:10 -07001833 int32_t length = static_cast<int32_t>(args[1]);
1834 if (length < 0) {
1835 ThrowNegativeArraySizeException(length);
1836 return;
1837 }
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001838 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
Andreas Gampee598e042015-04-10 14:57:10 -07001839 Runtime* runtime = Runtime::Current();
1840 ClassLinker* class_linker = runtime->GetClassLinker();
Vladimir Markobcf17522018-06-01 13:14:32 +01001841 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, element_class);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001842 if (UNLIKELY(array_class == nullptr)) {
Andreas Gampee598e042015-04-10 14:57:10 -07001843 CHECK(self->IsExceptionPending());
1844 return;
1845 }
1846 DCHECK(array_class->IsObjectArrayClass());
Vladimir Markobcf17522018-06-01 13:14:32 +01001847 ObjPtr<mirror::Array> new_array = mirror::ObjectArray<mirror::Object>::Alloc(
Andreas Gampee598e042015-04-10 14:57:10 -07001848 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1849 result->SetL(new_array);
1850}
1851
Mathieu Chartiere401d142015-04-22 13:56:20 -07001852void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1853 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1854 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001855 ScopedObjectAccessUnchecked soa(self);
1856 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001857 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<true>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001858 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001859 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<false>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001860 }
1861}
1862
Mathieu Chartiere401d142015-04-22 13:56:20 -07001863void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
1864 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1865 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001866 result->SetZ(JNI_TRUE);
1867}
1868
Mathieu Chartiere401d142015-04-22 13:56:20 -07001869void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
Vladimir Marko78baed52018-10-11 10:44:58 +01001870 Thread* self,
1871 ArtMethod* method ATTRIBUTE_UNUSED,
1872 mirror::Object* receiver ATTRIBUTE_UNUSED,
1873 uint32_t* args,
1874 JValue* result) {
1875 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1876 if (obj == nullptr) {
1877 AbortTransactionOrFail(self, "Unsafe.compareAndSwapInt with null object.");
1878 return;
1879 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001880 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1881 jint expectedValue = args[3];
1882 jint newValue = args[4];
1883 bool success;
1884 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier42c2e502018-06-19 12:30:56 -07001885 success = obj->CasField32<true>(MemberOffset(offset),
1886 expectedValue,
1887 newValue,
1888 CASMode::kStrong,
1889 std::memory_order_seq_cst);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001890 } else {
Mathieu Chartier42c2e502018-06-19 12:30:56 -07001891 success = obj->CasField32<false>(MemberOffset(offset),
1892 expectedValue,
1893 newValue,
1894 CASMode::kStrong,
1895 std::memory_order_seq_cst);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001896 }
1897 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1898}
1899
Vladimir Marko78baed52018-10-11 10:44:58 +01001900void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(Thread* self,
1901 ArtMethod* method ATTRIBUTE_UNUSED,
1902 mirror::Object* receiver ATTRIBUTE_UNUSED,
1903 uint32_t* args,
1904 JValue* result) {
1905 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
Narayan Kamath34a316f2016-03-30 13:11:18 +01001906 if (obj == nullptr) {
Vladimir Marko78baed52018-10-11 10:44:58 +01001907 AbortTransactionOrFail(self, "Unsafe.compareAndSwapIntVolatile with null object.");
Narayan Kamath34a316f2016-03-30 13:11:18 +01001908 return;
1909 }
1910
1911 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1912 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1913}
1914
Vladimir Marko78baed52018-10-11 10:44:58 +01001915void UnstartedRuntime::UnstartedJNIUnsafePutObject(Thread* self,
1916 ArtMethod* method ATTRIBUTE_UNUSED,
1917 mirror::Object* receiver ATTRIBUTE_UNUSED,
1918 uint32_t* args,
1919 JValue* result ATTRIBUTE_UNUSED) {
1920 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1921 if (obj == nullptr) {
1922 AbortTransactionOrFail(self, "Unsafe.putObject with null object.");
1923 return;
1924 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001925 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
Vladimir Marko78baed52018-10-11 10:44:58 +01001926 ObjPtr<mirror::Object> newValue = reinterpret_cast32<mirror::Object*>(args[3]);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001927 if (Runtime::Current()->IsActiveTransaction()) {
1928 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1929 } else {
1930 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1931 }
1932}
1933
Andreas Gampe799681b2015-05-15 19:24:12 -07001934void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
Vladimir Marko78baed52018-10-11 10:44:58 +01001935 Thread* self,
1936 ArtMethod* method ATTRIBUTE_UNUSED,
1937 mirror::Object* receiver ATTRIBUTE_UNUSED,
1938 uint32_t* args,
1939 JValue* result) {
1940 ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
1941 if (component == nullptr) {
1942 AbortTransactionOrFail(self, "Unsafe.getArrayBaseOffsetForComponentType with null component.");
1943 return;
1944 }
1945 Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001946 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1947}
1948
Andreas Gampe799681b2015-05-15 19:24:12 -07001949void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
Vladimir Marko78baed52018-10-11 10:44:58 +01001950 Thread* self,
1951 ArtMethod* method ATTRIBUTE_UNUSED,
1952 mirror::Object* receiver ATTRIBUTE_UNUSED,
1953 uint32_t* args,
1954 JValue* result) {
1955 ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
1956 if (component == nullptr) {
1957 AbortTransactionOrFail(self, "Unsafe.getArrayIndexScaleForComponentType with null component.");
1958 return;
1959 }
1960 Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001961 result->SetI(Primitive::ComponentSize(primitive_type));
1962}
1963
Andreas Gampec55bb392018-09-21 00:02:02 +00001964using InvokeHandler = void(*)(Thread* self,
1965 ShadowFrame* shadow_frame,
1966 JValue* result,
1967 size_t arg_size);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001968
Andreas Gampec55bb392018-09-21 00:02:02 +00001969using JNIHandler = void(*)(Thread* self,
1970 ArtMethod* method,
1971 mirror::Object* receiver,
1972 uint32_t* args,
1973 JValue* result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001974
1975static bool tables_initialized_ = false;
1976static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
1977static std::unordered_map<std::string, JNIHandler> jni_handlers_;
1978
Andreas Gampe799681b2015-05-15 19:24:12 -07001979void UnstartedRuntime::InitializeInvokeHandlers() {
1980#define UNSTARTED_DIRECT(ShortName, Sig) \
1981 invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
1982#include "unstarted_runtime_list.h"
1983 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
1984#undef UNSTARTED_RUNTIME_DIRECT_LIST
1985#undef UNSTARTED_RUNTIME_JNI_LIST
1986#undef UNSTARTED_DIRECT
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001987}
1988
Andreas Gampe799681b2015-05-15 19:24:12 -07001989void UnstartedRuntime::InitializeJNIHandlers() {
1990#define UNSTARTED_JNI(ShortName, Sig) \
1991 jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
1992#include "unstarted_runtime_list.h"
1993 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
1994#undef UNSTARTED_RUNTIME_DIRECT_LIST
1995#undef UNSTARTED_RUNTIME_JNI_LIST
1996#undef UNSTARTED_JNI
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001997}
1998
Andreas Gampe799681b2015-05-15 19:24:12 -07001999void UnstartedRuntime::Initialize() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002000 CHECK(!tables_initialized_);
2001
Andreas Gampe799681b2015-05-15 19:24:12 -07002002 InitializeInvokeHandlers();
2003 InitializeJNIHandlers();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002004
2005 tables_initialized_ = true;
2006}
2007
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002008void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
Andreas Gampe799681b2015-05-15 19:24:12 -07002009 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002010 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
2011 // problems in core libraries.
2012 CHECK(tables_initialized_);
2013
David Sehr709b0702016-10-13 09:12:37 -07002014 std::string name(ArtMethod::PrettyMethod(shadow_frame->GetMethod()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002015 const auto& iter = invoke_handlers_.find(name);
2016 if (iter != invoke_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07002017 // Clear out the result in case it's not zeroed out.
Yi Kong4b22b342018-08-02 14:43:21 -07002018 result->SetL(nullptr);
Andreas Gampe715fdc22016-04-18 17:07:30 -07002019
2020 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
2021 self->PushShadowFrame(shadow_frame);
2022
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002023 (*iter->second)(self, shadow_frame, result, arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07002024
2025 self->PopShadowFrame();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002026 } else {
2027 // Not special, continue with regular interpreter execution.
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002028 ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002029 }
2030}
2031
2032// 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 -07002033void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe799681b2015-05-15 19:24:12 -07002034 uint32_t* args, JValue* result) {
David Sehr709b0702016-10-13 09:12:37 -07002035 std::string name(ArtMethod::PrettyMethod(method));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002036 const auto& iter = jni_handlers_.find(name);
2037 if (iter != jni_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07002038 // Clear out the result in case it's not zeroed out.
Yi Kong4b22b342018-08-02 14:43:21 -07002039 result->SetL(nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002040 (*iter->second)(self, method, receiver, args, result);
2041 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02002042 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
2043 name.c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002044 } else {
David Sehr709b0702016-10-13 09:12:37 -07002045 LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002046 "non-transactional runtime";
2047 }
2048}
2049
2050} // namespace interpreter
2051} // namespace art