blob: 791ebf09b7d4120ca3cc401602ef1bafb252db4f [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 Gampe2969bcd2015-03-09 12:57:41 -070047#include "mirror/array-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070048#include "mirror/class.h"
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070049#include "mirror/field-inl.h"
Narayan Kamath14832ef2016-08-05 11:44:32 +010050#include "mirror/method.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070051#include "mirror/object-inl.h"
52#include "mirror/object_array-inl.h"
53#include "mirror/string-inl.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070054#include "nativehelper/scoped_local_ref.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070055#include "nth_caller_visitor.h"
Andreas Gampe715fdc22016-04-18 17:07:30 -070056#include "reflection.h"
Andreas Gampe513061a2017-06-01 09:17:34 -070057#include "thread-inl.h"
Sebastien Hertz2fd7e692015-04-02 11:11:19 +020058#include "transaction.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070059#include "well_known_classes.h"
60
61namespace art {
62namespace interpreter {
63
Andreas Gampe46ee31b2016-12-14 10:11:49 -080064using android::base::StringAppendV;
65using android::base::StringPrintf;
66
Andreas Gampe068b0c02015-03-11 12:44:47 -070067static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
Sebastien Hertz45b15972015-04-03 16:07:05 +020068 __attribute__((__format__(__printf__, 2, 3)))
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070069 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertz45b15972015-04-03 16:07:05 +020070
71static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
Andreas Gampe068b0c02015-03-11 12:44:47 -070072 va_list args;
Andreas Gampe068b0c02015-03-11 12:44:47 -070073 if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +020074 va_start(args, fmt);
75 AbortTransactionV(self, fmt, args);
Andreas Gampe068b0c02015-03-11 12:44:47 -070076 va_end(args);
77 } else {
Sebastien Hertz45b15972015-04-03 16:07:05 +020078 va_start(args, fmt);
79 std::string msg;
80 StringAppendV(&msg, fmt, args);
81 va_end(args);
82 LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
Andreas Gampe068b0c02015-03-11 12:44:47 -070083 UNREACHABLE();
84 }
85}
86
Andreas Gampe8ce9c302016-04-15 21:24:28 -070087// Restricted support for character upper case / lower case. Only support ASCII, where
88// it's easy. Abort the transaction otherwise.
89static void CharacterLowerUpper(Thread* self,
90 ShadowFrame* shadow_frame,
91 JValue* result,
92 size_t arg_offset,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070093 bool to_lower_case) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8ce9c302016-04-15 21:24:28 -070094 uint32_t int_value = static_cast<uint32_t>(shadow_frame->GetVReg(arg_offset));
95
96 // Only ASCII (7-bit).
97 if (!isascii(int_value)) {
98 AbortTransactionOrFail(self,
99 "Only support ASCII characters for toLowerCase/toUpperCase: %u",
100 int_value);
101 return;
102 }
103
104 std::locale c_locale("C");
105 char char_value = static_cast<char>(int_value);
106
107 if (to_lower_case) {
108 result->SetI(std::tolower(char_value, c_locale));
109 } else {
110 result->SetI(std::toupper(char_value, c_locale));
111 }
112}
113
114void UnstartedRuntime::UnstartedCharacterToLowerCase(
115 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
116 CharacterLowerUpper(self, shadow_frame, result, arg_offset, true);
117}
118
119void UnstartedRuntime::UnstartedCharacterToUpperCase(
120 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
121 CharacterLowerUpper(self, shadow_frame, result, arg_offset, false);
122}
123
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700124// Helper function to deal with class loading in an unstarted runtime.
125static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
126 Handle<mirror::ClassLoader> class_loader, JValue* result,
127 const std::string& method_name, bool initialize_class,
128 bool abort_if_not_found)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700129 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampefa4333d2017-02-14 11:10:34 -0800130 CHECK(className != nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700131 std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
132 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
133
134 mirror::Class* found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
135 if (found == nullptr && abort_if_not_found) {
136 if (!self->IsExceptionPending()) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700137 AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
David Sehr709b0702016-10-13 09:12:37 -0700138 method_name.c_str(),
139 PrettyDescriptor(descriptor.c_str()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700140 }
141 return;
142 }
143 if (found != nullptr && initialize_class) {
144 StackHandleScope<1> hs(self);
145 Handle<mirror::Class> h_class(hs.NewHandle(found));
146 if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
147 CHECK(self->IsExceptionPending());
148 return;
149 }
150 }
151 result->SetL(found);
152}
153
154// Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
155// rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
156// ClassNotFoundException), so need to do the same. The only exception is if the exception is
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200157// actually the transaction abort exception. This must not be wrapped, as it signals an
158// initialization abort.
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700159static void CheckExceptionGenerateClassNotFound(Thread* self)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700160 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700161 if (self->IsExceptionPending()) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200162 // If it is not the transaction abort exception, wrap it.
David Sehr709b0702016-10-13 09:12:37 -0700163 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200164 if (type != Transaction::kAbortExceptionDescriptor) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700165 self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
166 "ClassNotFoundException");
167 }
168 }
169}
170
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700171static mirror::String* GetClassName(Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700172 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700173 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
174 if (param == nullptr) {
175 AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
176 return nullptr;
177 }
178 return param->AsString();
179}
180
David Brazdila02cb112018-01-31 11:36:39 +0000181template<typename T>
182static ALWAYS_INLINE bool ShouldBlockAccessToMember(T* member, ShadowFrame* frame)
183 REQUIRES_SHARED(Locks::mutator_lock_) {
Narayan Kamathf5f1f802018-04-03 15:23:46 +0100184 // All uses in this file are from reflection
185 constexpr hiddenapi::AccessMethod access_method = hiddenapi::kReflection;
186 return hiddenapi::GetMemberAction(
David Brazdil8ce3bfa2018-03-12 18:01:18 +0000187 member,
188 frame->GetMethod()->GetDeclaringClass()->GetClassLoader(),
David Brazdil8e1a7cb2018-03-27 08:14:25 +0000189 frame->GetMethod()->GetDeclaringClass()->GetDexCache(),
Narayan Kamathf5f1f802018-04-03 15:23:46 +0100190 access_method) == hiddenapi::kDeny;
David Brazdila02cb112018-01-31 11:36:39 +0000191}
192
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800193void UnstartedRuntime::UnstartedClassForNameCommon(Thread* self,
194 ShadowFrame* shadow_frame,
195 JValue* result,
196 size_t arg_offset,
197 bool long_form,
198 const char* caller) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700199 mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
200 if (class_name == nullptr) {
201 return;
202 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800203 bool initialize_class;
204 mirror::ClassLoader* class_loader;
205 if (long_form) {
206 initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
207 class_loader = down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
208 } else {
209 initialize_class = true;
210 // TODO: This is really only correct for the boot classpath, and for robustness we should
211 // check the caller.
212 class_loader = nullptr;
213 }
214
215 ScopedObjectAccessUnchecked soa(self);
216 if (class_loader != nullptr && !ClassLinker::IsBootClassLoader(soa, class_loader)) {
217 AbortTransactionOrFail(self,
218 "Only the boot classloader is supported: %s",
219 mirror::Object::PrettyTypeOf(class_loader).c_str());
220 return;
221 }
222
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700223 StackHandleScope<1> hs(self);
224 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800225 UnstartedRuntimeFindClass(self,
226 h_class_name,
227 ScopedNullHandle<mirror::ClassLoader>(),
228 result,
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800229 caller,
230 initialize_class,
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800231 false);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700232 CheckExceptionGenerateClassNotFound(self);
233}
234
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800235void UnstartedRuntime::UnstartedClassForName(
236 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
237 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, false, "Class.forName");
238}
239
Andreas Gampe799681b2015-05-15 19:24:12 -0700240void UnstartedRuntime::UnstartedClassForNameLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700241 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800242 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.forName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700243}
244
Vladimir Marko7287c4d2018-02-15 10:41:07 +0000245void UnstartedRuntime::UnstartedClassGetPrimitiveClass(
246 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
247 ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
248 ObjPtr<mirror::Class> klass = mirror::Class::GetPrimitiveClass(class_name);
249 if (UNLIKELY(klass == nullptr)) {
250 DCHECK(self->IsExceptionPending());
251 AbortTransactionOrFail(self,
252 "Class.getPrimitiveClass() failed: %s",
253 self->GetException()->GetDetailMessage()->ToModifiedUtf8().c_str());
254 return;
255 }
256 result->SetL(klass);
257}
258
Andreas Gampe799681b2015-05-15 19:24:12 -0700259void UnstartedRuntime::UnstartedClassClassForName(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700260 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800261 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.classForName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700262}
263
Andreas Gampe799681b2015-05-15 19:24:12 -0700264void UnstartedRuntime::UnstartedClassNewInstance(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700265 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
266 StackHandleScope<2> hs(self); // Class, constructor, object.
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700267 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
268 if (param == nullptr) {
269 AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
270 return;
271 }
272 mirror::Class* klass = param->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700273 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700274
275 // Check that it's not null.
Andreas Gampefa4333d2017-02-14 11:10:34 -0800276 if (h_klass == nullptr) {
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700277 AbortTransactionOrFail(self, "Class reference is null for newInstance");
278 return;
279 }
280
281 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
282 if (Runtime::Current()->IsActiveTransaction()) {
283 if (h_klass.Get()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200284 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700285 h_klass->PrettyClass().c_str());
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700286 return;
287 }
288 }
289
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700290 // There are two situations in which we'll abort this run.
291 // 1) If the class isn't yet initialized and initialization fails.
292 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
293 // Note that 2) could likely be handled here, but for safety abort the transaction.
294 bool ok = false;
Mathieu Chartiere401d142015-04-22 13:56:20 -0700295 auto* cl = Runtime::Current()->GetClassLinker();
296 if (cl->EnsureInitialized(self, h_klass, true, true)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000297 ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
David Brazdila02cb112018-01-31 11:36:39 +0000298 if (cons != nullptr && ShouldBlockAccessToMember(cons, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000299 cons = nullptr;
300 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700301 if (cons != nullptr) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700302 Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800303 CHECK(h_obj != nullptr); // We don't expect OOM at compile-time.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700304 EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700305 if (!self->IsExceptionPending()) {
306 result->SetL(h_obj.Get());
307 ok = true;
308 }
309 } else {
310 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
311 "Could not find default constructor for '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700312 h_klass->PrettyClass().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700313 }
314 }
315 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700316 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
David Sehr709b0702016-10-13 09:12:37 -0700317 h_klass->PrettyClass().c_str(),
318 mirror::Object::PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700319 }
320}
321
Andreas Gampe799681b2015-05-15 19:24:12 -0700322void UnstartedRuntime::UnstartedClassGetDeclaredField(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700323 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700324 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
325 // going the reflective Dex way.
326 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
327 mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700328 ArtField* found = nullptr;
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700329 for (ArtField& field : klass->GetIFields()) {
330 if (name2->Equals(field.GetName())) {
331 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700332 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700333 }
334 }
335 if (found == nullptr) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700336 for (ArtField& field : klass->GetSFields()) {
337 if (name2->Equals(field.GetName())) {
338 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700339 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700340 }
341 }
342 }
David Brazdila02cb112018-01-31 11:36:39 +0000343 if (found != nullptr && ShouldBlockAccessToMember(found, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000344 found = nullptr;
345 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700346 if (found == nullptr) {
347 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
348 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
David Sehr709b0702016-10-13 09:12:37 -0700349 klass->PrettyDescriptor().c_str());
Andreas Gampe068b0c02015-03-11 12:44:47 -0700350 return;
351 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700352 Runtime* runtime = Runtime::Current();
Andreas Gampe542451c2016-07-26 09:02:02 -0700353 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Andreas Gampee01e3642016-07-25 13:06:04 -0700354 mirror::Field* field;
355 if (runtime->IsActiveTransaction()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700356 if (pointer_size == PointerSize::k64) {
357 field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
358 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700359 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700360 field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
361 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700362 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700363 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700364 if (pointer_size == PointerSize::k64) {
365 field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
366 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700367 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700368 field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
369 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700370 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700371 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700372 result->SetL(field);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700373}
374
Andreas Gampebc4d2182016-02-22 10:03:12 -0800375// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
376void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
377 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
378 // Special managed code cut-out to allow method lookup in a un-started runtime.
379 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
380 if (klass == nullptr) {
381 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
382 return;
383 }
384 mirror::String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
385 mirror::ObjectArray<mirror::Class>* args =
386 shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700387 Runtime* runtime = Runtime::Current();
388 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700389 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700390 ObjPtr<mirror::Method> method;
Andreas Gampee01e3642016-07-25 13:06:04 -0700391 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700392 if (pointer_size == PointerSize::k64) {
393 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
394 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700395 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700396 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
397 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700398 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800399 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700400 if (pointer_size == PointerSize::k64) {
401 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
402 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700403 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700404 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
405 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700406 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800407 }
David Brazdila02cb112018-01-31 11:36:39 +0000408 if (method != nullptr && ShouldBlockAccessToMember(method->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000409 method = nullptr;
410 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700411 result->SetL(method);
Andreas Gampebc4d2182016-02-22 10:03:12 -0800412}
413
Andreas Gampe6039e562016-04-05 18:18:43 -0700414// Special managed code cut-out to allow constructor lookup in a un-started runtime.
415void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
416 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
417 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
418 if (klass == nullptr) {
419 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
420 return;
421 }
422 mirror::ObjectArray<mirror::Class>* args =
423 shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700424 Runtime* runtime = Runtime::Current();
425 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700426 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700427 ObjPtr<mirror::Constructor> constructor;
Andreas Gampee01e3642016-07-25 13:06:04 -0700428 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700429 if (pointer_size == PointerSize::k64) {
430 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
431 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700432 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700433 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
434 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700435 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700436 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700437 if (pointer_size == PointerSize::k64) {
438 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
439 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700440 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700441 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
442 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700443 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700444 }
David Brazdil5a61bb72018-01-19 16:59:46 +0000445 if (constructor != nullptr &&
David Brazdila02cb112018-01-31 11:36:39 +0000446 ShouldBlockAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000447 constructor = nullptr;
448 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700449 result->SetL(constructor);
Andreas Gampe6039e562016-04-05 18:18:43 -0700450}
451
Andreas Gampeae78c262017-02-01 20:40:44 -0800452void UnstartedRuntime::UnstartedClassGetDeclaringClass(
453 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
454 StackHandleScope<1> hs(self);
455 Handle<mirror::Class> klass(hs.NewHandle(
456 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
457 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
458 result->SetL(nullptr);
459 return;
460 }
461 // Return null for anonymous classes.
462 JValue is_anon_result;
463 UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
464 if (is_anon_result.GetZ() != 0) {
465 result->SetL(nullptr);
466 return;
467 }
468 result->SetL(annotations::GetDeclaringClass(klass));
469}
470
Andreas Gampe633750c2016-02-19 10:49:50 -0800471void UnstartedRuntime::UnstartedClassGetEnclosingClass(
472 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
473 StackHandleScope<1> hs(self);
474 Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
475 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
476 result->SetL(nullptr);
477 }
David Sehr9323e6e2016-09-13 08:58:35 -0700478 result->SetL(annotations::GetEnclosingClass(klass));
Andreas Gampe633750c2016-02-19 10:49:50 -0800479}
480
Andreas Gampe715fdc22016-04-18 17:07:30 -0700481void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
482 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
483 StackHandleScope<1> hs(self);
484 Handle<mirror::Class> klass(hs.NewHandle(
485 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
486 const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
487 result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
488}
489
Andreas Gampe9486a162017-02-16 15:17:47 -0800490void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
491 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
492 StackHandleScope<1> hs(self);
493 Handle<mirror::Class> klass(hs.NewHandle(
494 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
495
496 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
497 result->SetL(nullptr);
498 return;
499 }
500
501 result->SetL(annotations::GetSignatureAnnotationForClass(klass));
502}
503
Andreas Gampeae78c262017-02-01 20:40:44 -0800504void UnstartedRuntime::UnstartedClassIsAnonymousClass(
505 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
506 StackHandleScope<1> hs(self);
507 Handle<mirror::Class> klass(hs.NewHandle(
508 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
509 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
510 result->SetZ(false);
511 return;
512 }
513 mirror::String* class_name = nullptr;
514 if (!annotations::GetInnerClass(klass, &class_name)) {
515 result->SetZ(false);
516 return;
517 }
518 result->SetZ(class_name == nullptr);
519}
520
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700521static std::unique_ptr<MemMap> FindAndExtractEntry(const std::string& jar_file,
522 const char* entry_name,
523 size_t* size,
524 std::string* error_msg) {
525 CHECK(size != nullptr);
526
527 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
528 if (zip_archive == nullptr) {
Mathieu Chartier6beced42016-11-15 15:51:31 -0800529 return nullptr;
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700530 }
531 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
532 if (zip_entry == nullptr) {
533 return nullptr;
534 }
535 std::unique_ptr<MemMap> tmp_map(
536 zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg));
537 if (tmp_map == nullptr) {
538 return nullptr;
539 }
540
541 // OK, from here everything seems fine.
542 *size = zip_entry->GetUncompressedLength();
543 return tmp_map;
544}
545
546static void GetResourceAsStream(Thread* self,
547 ShadowFrame* shadow_frame,
548 JValue* result,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700549 size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700550 mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
551 if (resource_obj == nullptr) {
552 AbortTransactionOrFail(self, "null name for getResourceAsStream");
553 return;
554 }
555 CHECK(resource_obj->IsString());
556 mirror::String* resource_name = resource_obj->AsString();
557
558 std::string resource_name_str = resource_name->ToModifiedUtf8();
559 if (resource_name_str.empty() || resource_name_str == "/") {
560 AbortTransactionOrFail(self,
561 "Unsupported name %s for getResourceAsStream",
562 resource_name_str.c_str());
563 return;
564 }
565 const char* resource_cstr = resource_name_str.c_str();
566 if (resource_cstr[0] == '/') {
567 resource_cstr++;
568 }
569
570 Runtime* runtime = Runtime::Current();
571
572 std::vector<std::string> split;
573 Split(runtime->GetBootClassPathString(), ':', &split);
574 if (split.empty()) {
575 AbortTransactionOrFail(self,
576 "Boot classpath not set or split error:: %s",
577 runtime->GetBootClassPathString().c_str());
578 return;
579 }
580
581 std::unique_ptr<MemMap> mem_map;
582 size_t map_size;
583 std::string last_error_msg; // Only store the last message (we could concatenate).
584
585 for (const std::string& jar_file : split) {
586 mem_map = FindAndExtractEntry(jar_file, resource_cstr, &map_size, &last_error_msg);
587 if (mem_map != nullptr) {
588 break;
589 }
590 }
591
592 if (mem_map == nullptr) {
593 // Didn't find it. There's a good chance this will be the same at runtime, but still
594 // conservatively abort the transaction here.
595 AbortTransactionOrFail(self,
596 "Could not find resource %s. Last error was %s.",
597 resource_name_str.c_str(),
598 last_error_msg.c_str());
599 return;
600 }
601
602 StackHandleScope<3> hs(self);
603
604 // Create byte array for content.
605 Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800606 if (h_array == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700607 AbortTransactionOrFail(self, "Could not find/create byte array class");
608 return;
609 }
610 // Copy in content.
611 memcpy(h_array->GetData(), mem_map->Begin(), map_size);
612 // Be proactive releasing memory.
Andreas Gampeeac4f282017-04-26 21:07:04 -0700613 mem_map.reset();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700614
615 // Create a ByteArrayInputStream.
616 Handle<mirror::Class> h_class(hs.NewHandle(
617 runtime->GetClassLinker()->FindClass(self,
618 "Ljava/io/ByteArrayInputStream;",
619 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800620 if (h_class == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700621 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
622 return;
623 }
624 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
625 AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
626 return;
627 }
628
629 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800630 if (h_obj == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700631 AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
632 return;
633 }
634
635 auto* cl = Runtime::Current()->GetClassLinker();
Vladimir Markoba118822017-06-12 15:41:56 +0100636 ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700637 if (constructor == nullptr) {
638 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
639 return;
640 }
641
642 uint32_t args[1];
643 args[0] = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_array.Get()));
644 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
645
646 if (self->IsExceptionPending()) {
647 AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
648 return;
649 }
650
651 result->SetL(h_obj.Get());
652}
653
654void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
655 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
656 {
657 mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
658 CHECK(this_obj != nullptr);
659 CHECK(this_obj->IsClassLoader());
660
661 StackHandleScope<1> hs(self);
662 Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
663
664 if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
665 this_classloader_class.Get()) {
666 AbortTransactionOrFail(self,
David Sehr709b0702016-10-13 09:12:37 -0700667 "Unsupported classloader type %s for getResourceAsStream",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700668 mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700669 return;
670 }
671 }
672
673 GetResourceAsStream(self, shadow_frame, result, arg_offset);
674}
675
Andreas Gampe85bef7e2017-02-16 18:13:26 -0800676void UnstartedRuntime::UnstartedConstructorNewInstance0(
677 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
678 // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
679 StackHandleScope<4> hs(self);
680 Handle<mirror::Constructor> m = hs.NewHandle(
681 reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
682 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
683 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
684 shadow_frame->GetVRegReference(arg_offset + 1)));
685 Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
686 if (UNLIKELY(c->IsAbstract())) {
687 AbortTransactionOrFail(self, "Cannot handle abstract classes");
688 return;
689 }
690 // Verify that we can access the class.
691 if (!m->IsAccessible() && !c->IsPublic()) {
692 // Go 2 frames back, this method is always called from newInstance0, which is called from
693 // Constructor.newInstance(Object... args).
694 ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
695 // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
696 // access checks anyways. TODO: Investigate if this the correct behavior.
697 if (caller != nullptr && !caller->CanAccess(c.Get())) {
698 AbortTransactionOrFail(self, "Cannot access class");
699 return;
700 }
701 }
702 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
703 DCHECK(self->IsExceptionPending());
704 return;
705 }
706 if (c->IsClassClass()) {
707 AbortTransactionOrFail(self, "new Class() is not supported");
708 return;
709 }
710
711 // String constructor is replaced by a StringFactory method in InvokeMethod.
712 if (c->IsStringClass()) {
713 // We don't support strings.
714 AbortTransactionOrFail(self, "String construction is not supported");
715 return;
716 }
717
718 Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
719 if (receiver == nullptr) {
720 AbortTransactionOrFail(self, "Could not allocate");
721 return;
722 }
723
724 // It's easier to use reflection to make the call, than create the uint32_t array.
725 {
726 ScopedObjectAccessUnchecked soa(self);
727 ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
728 soa.AddLocalReference<jobject>(m.Get()));
729 ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
730 soa.AddLocalReference<jobject>(receiver.Get()));
731 ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
732 soa.AddLocalReference<jobject>(args.Get()));
733 InvokeMethod(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
734 }
735 if (self->IsExceptionPending()) {
736 AbortTransactionOrFail(self, "Failed running constructor");
737 } else {
738 result->SetL(receiver.Get());
739 }
740}
741
Andreas Gampe799681b2015-05-15 19:24:12 -0700742void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700743 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700744 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
745 mirror::ClassLoader* class_loader =
746 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
747 StackHandleScope<2> hs(self);
748 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
749 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
750 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
751 "VMClassLoader.findLoadedClass", false, false);
752 // This might have an error pending. But semantics are to just return null.
753 if (self->IsExceptionPending()) {
754 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
David Sehr709b0702016-10-13 09:12:37 -0700755 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700756 if (type != "java.lang.InternalError") {
757 self->ClearException();
758 }
759 }
760}
761
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700762// Arraycopy emulation.
763// Note: we can't use any fast copy functions, as they are not available under transaction.
764
765template <typename T>
766static void PrimitiveArrayCopy(Thread* self,
767 mirror::Array* src_array, int32_t src_pos,
768 mirror::Array* dst_array, int32_t dst_pos,
769 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700770 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700771 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700772 AbortTransactionOrFail(self,
773 "Types mismatched in arraycopy: %s vs %s.",
774 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700775 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700776 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700777 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700778 return;
779 }
780 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
781 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
782 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
783 if (copy_forward) {
784 for (int32_t i = 0; i < length; ++i) {
785 dst->Set(dst_pos + i, src->Get(src_pos + i));
786 }
787 } else {
788 for (int32_t i = 1; i <= length; ++i) {
789 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
790 }
791 }
792}
793
Andreas Gampe799681b2015-05-15 19:24:12 -0700794void UnstartedRuntime::UnstartedSystemArraycopy(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700795 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700796 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700797 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
798 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700799 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700800
Andreas Gampe85a098a2016-03-31 13:30:53 -0700801 mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
802 mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
803 // Null checking. For simplicity, abort transaction.
804 if (src_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700805 AbortTransactionOrFail(self, "src is null in arraycopy.");
806 return;
807 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700808 if (dst_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700809 AbortTransactionOrFail(self, "dst is null in arraycopy.");
810 return;
811 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700812 // Test for arrayness. Throw ArrayStoreException.
813 if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
814 self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
815 return;
816 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700817
Andreas Gampe85a098a2016-03-31 13:30:53 -0700818 mirror::Array* src_array = src_obj->AsArray();
819 mirror::Array* dst_array = dst_obj->AsArray();
820
821 // Bounds checking. Throw IndexOutOfBoundsException.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700822 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
823 UNLIKELY(src_pos > src_array->GetLength() - length) ||
824 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700825 self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700826 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
827 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
828 length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700829 return;
830 }
831
832 // Type checking.
833 mirror::Class* src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
834 GetComponentType();
835
836 if (!src_type->IsPrimitive()) {
837 // Check that the second type is not primitive.
838 mirror::Class* trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
839 GetComponentType();
840 if (trg_type->IsPrimitiveInt()) {
841 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700842 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700843 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700844 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700845 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700846 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700847 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700848
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700849 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
850 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
851 if (src == dst) {
852 // Can overlap, but not have type mismatches.
Andreas Gampe85a098a2016-03-31 13:30:53 -0700853 // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700854 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
855 if (copy_forward) {
856 for (int32_t i = 0; i < length; ++i) {
857 dst->Set(dst_pos + i, src->Get(src_pos + i));
858 }
859 } else {
860 for (int32_t i = 1; i <= length; ++i) {
861 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
862 }
863 }
864 } else {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700865 // We're being lazy here. Optimally this could be a memcpy (if component types are
866 // assignable), but the ObjectArray implementation doesn't support transactions. The
867 // checking version, however, does.
868 if (Runtime::Current()->IsActiveTransaction()) {
869 dst->AssignableCheckingMemcpy<true>(
870 dst_pos, src, src_pos, length, true /* throw_exception */);
871 } else {
872 dst->AssignableCheckingMemcpy<false>(
873 dst_pos, src, src_pos, length, true /* throw_exception */);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700874 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700875 }
Andreas Gampe5c9af612016-04-05 14:16:10 -0700876 } else if (src_type->IsPrimitiveByte()) {
877 PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700878 } else if (src_type->IsPrimitiveChar()) {
879 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
880 } else if (src_type->IsPrimitiveInt()) {
881 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700882 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700883 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700884 src_type->PrettyDescriptor().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700885 }
886}
887
Andreas Gampe5c9af612016-04-05 14:16:10 -0700888void UnstartedRuntime::UnstartedSystemArraycopyByte(
889 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
890 // Just forward.
891 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
892}
893
Andreas Gampe799681b2015-05-15 19:24:12 -0700894void UnstartedRuntime::UnstartedSystemArraycopyChar(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700895 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700896 // Just forward.
897 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
898}
899
900void UnstartedRuntime::UnstartedSystemArraycopyInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700901 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700902 // Just forward.
903 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
904}
905
Narayan Kamath34a316f2016-03-30 13:11:18 +0100906void UnstartedRuntime::UnstartedSystemGetSecurityManager(
907 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
908 JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
909 result->SetL(nullptr);
910}
911
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700912static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
913
914static void GetSystemProperty(Thread* self,
915 ShadowFrame* shadow_frame,
916 JValue* result,
917 size_t arg_offset,
918 bool is_default_version)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700919 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700920 StackHandleScope<4> hs(self);
921 Handle<mirror::String> h_key(
922 hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800923 if (h_key == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700924 AbortTransactionOrFail(self, "getProperty key was null");
925 return;
926 }
927
928 // This is overall inefficient, but reflecting the values here is not great, either. So
929 // for simplicity, and with the assumption that the number of getProperty calls is not
930 // too great, just iterate each time.
931
932 // Get the storage class.
933 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
934 Handle<mirror::Class> h_props_class(hs.NewHandle(
935 class_linker->FindClass(self,
936 "Ljava/lang/AndroidHardcodedSystemProperties;",
937 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800938 if (h_props_class == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700939 AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
940 return;
941 }
942 if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
943 AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
944 return;
945 }
946
947 // Get the storage array.
948 ArtField* static_properties =
949 h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
950 "[[Ljava/lang/String;");
951 if (static_properties == nullptr) {
952 AbortTransactionOrFail(self,
953 "Could not find %s field",
954 kAndroidHardcodedSystemPropertiesFieldName);
955 return;
956 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700957 ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
958 Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
959 props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800960 if (h_2string_array == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700961 AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
962 return;
963 }
964
965 // Iterate over it.
966 const int32_t prop_count = h_2string_array->GetLength();
967 // Use the third handle as mutable.
968 MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
969 hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
970 for (int32_t i = 0; i < prop_count; ++i) {
971 h_string_array.Assign(h_2string_array->Get(i));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800972 if (h_string_array == nullptr ||
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700973 h_string_array->GetLength() != 2 ||
974 h_string_array->Get(0) == nullptr) {
975 AbortTransactionOrFail(self,
976 "Unexpected content of %s",
977 kAndroidHardcodedSystemPropertiesFieldName);
978 return;
979 }
980 if (h_key->Equals(h_string_array->Get(0))) {
981 // Found a value.
982 if (h_string_array->Get(1) == nullptr && is_default_version) {
983 // Null is being delegated to the default map, and then resolved to the given default value.
984 // As there's no default map, return the given value.
985 result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
986 } else {
987 result->SetL(h_string_array->Get(1));
988 }
989 return;
990 }
991 }
992
993 // Key is not supported.
994 AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
995}
996
997void UnstartedRuntime::UnstartedSystemGetProperty(
998 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
999 GetSystemProperty(self, shadow_frame, result, arg_offset, false);
1000}
1001
1002void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
1003 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1004 GetSystemProperty(self, shadow_frame, result, arg_offset, true);
1005}
1006
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001007static std::string GetImmediateCaller(ShadowFrame* shadow_frame)
1008 REQUIRES_SHARED(Locks::mutator_lock_) {
1009 if (shadow_frame->GetLink() == nullptr) {
1010 return "<no caller>";
1011 }
1012 return ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1013}
1014
1015static bool CheckCallers(ShadowFrame* shadow_frame,
1016 std::initializer_list<std::string> allowed_call_stack)
1017 REQUIRES_SHARED(Locks::mutator_lock_) {
1018 for (const std::string& allowed_caller : allowed_call_stack) {
1019 if (shadow_frame->GetLink() == nullptr) {
1020 return false;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001021 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001022
1023 std::string found_caller = ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1024 if (allowed_caller != found_caller) {
1025 return false;
1026 }
1027
1028 shadow_frame = shadow_frame->GetLink();
1029 }
1030 return true;
1031}
1032
1033static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_descriptor)
1034 REQUIRES_SHARED(Locks::mutator_lock_) {
1035 // Find the requested class.
1036 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1037 ObjPtr<mirror::Class> klass =
1038 class_linker->FindClass(self, class_descriptor, ScopedNullHandle<mirror::ClassLoader>());
1039 if (klass == nullptr) {
1040 AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
1041 return nullptr;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001042 }
1043
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001044 StackHandleScope<2> hs(self);
1045 Handle<mirror::Class> h_class(hs.NewHandle(klass));
1046 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001047 if (h_obj != nullptr) {
Vladimir Markoba118822017-06-12 15:41:56 +01001048 ArtMethod* init_method = h_class->FindConstructor("()V", class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001049 if (init_method == nullptr) {
1050 AbortTransactionOrFail(self, "Could not find <init> for %s", class_descriptor);
1051 return nullptr;
1052 } else {
1053 JValue invoke_result;
1054 EnterInterpreterFromInvoke(self, init_method, h_obj.Get(), nullptr, nullptr);
1055 if (!self->IsExceptionPending()) {
1056 return h_obj.Get();
1057 }
1058 AbortTransactionOrFail(self, "Could not run <init> for %s", class_descriptor);
1059 }
1060 }
1061 AbortTransactionOrFail(self, "Could not allocate instance of %s", class_descriptor);
1062 return nullptr;
1063}
1064
1065void UnstartedRuntime::UnstartedThreadLocalGet(
1066 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1067 if (CheckCallers(shadow_frame, { "sun.misc.FloatingDecimal$BinaryToASCIIBuffer "
1068 "sun.misc.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1069 result->SetL(CreateInstanceOf(self, "Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;"));
1070 } else {
1071 AbortTransactionOrFail(self,
1072 "ThreadLocal.get() does not support %s",
1073 GetImmediateCaller(shadow_frame).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001074 }
1075}
1076
Andreas Gampebad529d2017-02-13 18:52:10 -08001077void UnstartedRuntime::UnstartedThreadCurrentThread(
1078 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1079 if (CheckCallers(shadow_frame,
1080 { "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1081 "java.lang.String, long)",
1082 "void java.lang.Thread.<init>()",
1083 "void java.util.logging.LogManager$Cleaner.<init>("
1084 "java.util.logging.LogManager)" })) {
1085 // Whitelist LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
1086 // Thread constructor only asks for the current thread to set up defaults and add the
1087 // thread as unstarted to the ThreadGroup. A faked-up main thread peer is good enough for
1088 // these purposes.
1089 Runtime::Current()->InitThreadGroups(self);
1090 jobject main_peer =
1091 self->CreateCompileTimePeer(self->GetJniEnv(),
1092 "main",
1093 false,
1094 Runtime::Current()->GetMainThreadGroup());
1095 if (main_peer == nullptr) {
1096 AbortTransactionOrFail(self, "Failed allocating peer");
1097 return;
1098 }
1099
1100 result->SetL(self->DecodeJObject(main_peer));
1101 self->GetJniEnv()->DeleteLocalRef(main_peer);
1102 } else {
1103 AbortTransactionOrFail(self,
1104 "Thread.currentThread() does not support %s",
1105 GetImmediateCaller(shadow_frame).c_str());
1106 }
1107}
1108
1109void UnstartedRuntime::UnstartedThreadGetNativeState(
1110 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1111 if (CheckCallers(shadow_frame,
1112 { "java.lang.Thread$State java.lang.Thread.getState()",
1113 "java.lang.ThreadGroup java.lang.Thread.getThreadGroup()",
1114 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1115 "java.lang.String, long)",
1116 "void java.lang.Thread.<init>()",
1117 "void java.util.logging.LogManager$Cleaner.<init>("
1118 "java.util.logging.LogManager)" })) {
1119 // Whitelist reading the state of the "main" thread when creating another (unstarted) thread
1120 // for LogManager. Report the thread as "new" (it really only counts that it isn't terminated).
1121 constexpr int32_t kJavaRunnable = 1;
1122 result->SetI(kJavaRunnable);
1123 } else {
1124 AbortTransactionOrFail(self,
1125 "Thread.getNativeState() does not support %s",
1126 GetImmediateCaller(shadow_frame).c_str());
1127 }
1128}
1129
Sergio Giro83261202016-04-11 20:49:20 +01001130void UnstartedRuntime::UnstartedMathCeil(
1131 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001132 result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
Sergio Giro83261202016-04-11 20:49:20 +01001133}
1134
1135void UnstartedRuntime::UnstartedMathFloor(
1136 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001137 result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001138}
1139
Andreas Gampeb8a00f92016-04-18 20:51:13 -07001140void UnstartedRuntime::UnstartedMathSin(
1141 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1142 result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
1143}
1144
1145void UnstartedRuntime::UnstartedMathCos(
1146 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1147 result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
1148}
1149
1150void UnstartedRuntime::UnstartedMathPow(
1151 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1152 result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
1153 shadow_frame->GetVRegDouble(arg_offset + 2)));
1154}
1155
Andreas Gampe799681b2015-05-15 19:24:12 -07001156void UnstartedRuntime::UnstartedObjectHashCode(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001157 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001158 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1159 result->SetI(obj->IdentityHashCode());
1160}
1161
Andreas Gampe799681b2015-05-15 19:24:12 -07001162void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
Andreas Gampedd9d0552015-03-09 12:57:41 -07001163 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001164 double in = shadow_frame->GetVRegDouble(arg_offset);
Roland Levillainda4d79b2015-03-24 14:36:11 +00001165 result->SetJ(bit_cast<int64_t, double>(in));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001166}
1167
Andreas Gampedd9d0552015-03-09 12:57:41 -07001168static void UnstartedMemoryPeek(
1169 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1170 int64_t address = shadow_frame->GetVRegLong(arg_offset);
1171 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
1172 // aborting the transaction.
1173
1174 switch (type) {
1175 case Primitive::kPrimByte: {
1176 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
1177 return;
1178 }
1179
1180 case Primitive::kPrimShort: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001181 typedef int16_t unaligned_short __attribute__ ((aligned (1)));
1182 result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001183 return;
1184 }
1185
1186 case Primitive::kPrimInt: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001187 typedef int32_t unaligned_int __attribute__ ((aligned (1)));
1188 result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001189 return;
1190 }
1191
1192 case Primitive::kPrimLong: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001193 typedef int64_t unaligned_long __attribute__ ((aligned (1)));
1194 result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001195 return;
1196 }
1197
1198 case Primitive::kPrimBoolean:
1199 case Primitive::kPrimChar:
1200 case Primitive::kPrimFloat:
1201 case Primitive::kPrimDouble:
1202 case Primitive::kPrimVoid:
1203 case Primitive::kPrimNot:
1204 LOG(FATAL) << "Not in the Memory API: " << type;
1205 UNREACHABLE();
1206 }
1207 LOG(FATAL) << "Should not reach here";
1208 UNREACHABLE();
1209}
1210
Andreas Gampe799681b2015-05-15 19:24:12 -07001211void UnstartedRuntime::UnstartedMemoryPeekByte(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001212 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001213 UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
1214}
1215
1216void UnstartedRuntime::UnstartedMemoryPeekShort(
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::kPrimShort, shadow_frame, result, arg_offset);
1219}
1220
1221void UnstartedRuntime::UnstartedMemoryPeekInt(
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::kPrimInt, shadow_frame, result, arg_offset);
1224}
1225
1226void UnstartedRuntime::UnstartedMemoryPeekLong(
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::kPrimLong, shadow_frame, result, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001229}
1230
1231static void UnstartedMemoryPeekArray(
1232 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001233 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampedd9d0552015-03-09 12:57:41 -07001234 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1235 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1236 if (obj == nullptr) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001237 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
Andreas Gampedd9d0552015-03-09 12:57:41 -07001238 return;
1239 }
1240 mirror::Array* array = obj->AsArray();
1241
1242 int offset = shadow_frame->GetVReg(arg_offset + 3);
1243 int count = shadow_frame->GetVReg(arg_offset + 4);
1244 if (offset < 0 || offset + count > array->GetLength()) {
1245 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
1246 offset, count, array->GetLength()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001247 Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
Andreas Gampedd9d0552015-03-09 12:57:41 -07001248 return;
1249 }
1250
1251 switch (type) {
1252 case Primitive::kPrimByte: {
1253 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
1254 mirror::ByteArray* byte_array = array->AsByteArray();
1255 for (int32_t i = 0; i < count; ++i, ++address) {
1256 byte_array->SetWithoutChecks<true>(i + offset, *address);
1257 }
1258 return;
1259 }
1260
1261 case Primitive::kPrimShort:
1262 case Primitive::kPrimInt:
1263 case Primitive::kPrimLong:
1264 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1265 UNREACHABLE();
1266
1267 case Primitive::kPrimBoolean:
1268 case Primitive::kPrimChar:
1269 case Primitive::kPrimFloat:
1270 case Primitive::kPrimDouble:
1271 case Primitive::kPrimVoid:
1272 case Primitive::kPrimNot:
1273 LOG(FATAL) << "Not in the Memory API: " << type;
1274 UNREACHABLE();
1275 }
1276 LOG(FATAL) << "Should not reach here";
1277 UNREACHABLE();
1278}
1279
Andreas Gampe799681b2015-05-15 19:24:12 -07001280void UnstartedRuntime::UnstartedMemoryPeekByteArray(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001281 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001282 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001283}
1284
Kenny Root1c9e61c2015-05-14 15:58:17 -07001285// This allows reading the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001286void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001287 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001288 jint start = shadow_frame->GetVReg(arg_offset + 1);
1289 jint end = shadow_frame->GetVReg(arg_offset + 2);
1290 jint index = shadow_frame->GetVReg(arg_offset + 4);
1291 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1292 if (string == nullptr) {
1293 AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1294 return;
1295 }
Kenny Root57f91e82015-05-14 15:58:17 -07001296 DCHECK_GE(start, 0);
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001297 DCHECK_LE(start, end);
1298 DCHECK_LE(end, string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001299 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001300 Handle<mirror::CharArray> h_char_array(
1301 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001302 DCHECK_GE(index, 0);
Kenny Root57f91e82015-05-14 15:58:17 -07001303 DCHECK_LE(index, h_char_array->GetLength());
1304 DCHECK_LE(end - start, h_char_array->GetLength() - index);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001305 string->GetChars(start, end, h_char_array, index);
1306}
1307
1308// This allows reading chars from the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001309void UnstartedRuntime::UnstartedStringCharAt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001310 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001311 jint index = shadow_frame->GetVReg(arg_offset + 1);
1312 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1313 if (string == nullptr) {
1314 AbortTransactionOrFail(self, "String.charAt with null object");
1315 return;
1316 }
1317 result->SetC(string->CharAt(index));
1318}
1319
Vladimir Marko92907f32017-02-20 14:08:30 +00001320// This allows creating String objects with replaced characters during compilation.
1321// String.doReplace(char, char) is called from String.replace(char, char) when there is a match.
1322void UnstartedRuntime::UnstartedStringDoReplace(
1323 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1324 jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
1325 jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001326 StackHandleScope<1> hs(self);
1327 Handle<mirror::String> string =
1328 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
Kenny Root57f91e82015-05-14 15:58:17 -07001329 if (string == nullptr) {
Vladimir Marko92907f32017-02-20 14:08:30 +00001330 AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
Kenny Root57f91e82015-05-14 15:58:17 -07001331 return;
1332 }
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001333 result->SetL(mirror::String::DoReplace(self, string, old_c, new_c));
Kenny Root57f91e82015-05-14 15:58:17 -07001334}
1335
Kenny Root1c9e61c2015-05-14 15:58:17 -07001336// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001337void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001338 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001339 jint offset = shadow_frame->GetVReg(arg_offset);
1340 jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1341 DCHECK_GE(char_count, 0);
1342 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001343 Handle<mirror::CharArray> h_char_array(
1344 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
Kenny Root1c9e61c2015-05-14 15:58:17 -07001345 Runtime* runtime = Runtime::Current();
1346 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1347 result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator));
1348}
1349
1350// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001351void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001352 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root57f91e82015-05-14 15:58:17 -07001353 mirror::String* to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1354 if (to_copy == nullptr) {
1355 AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1356 return;
1357 }
1358 StackHandleScope<1> hs(self);
1359 Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1360 Runtime* runtime = Runtime::Current();
1361 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1362 result->SetL(mirror::String::AllocFromString<true>(self, h_string->GetLength(), h_string, 0,
1363 allocator));
1364}
1365
Andreas Gampe799681b2015-05-15 19:24:12 -07001366void UnstartedRuntime::UnstartedStringFastSubstring(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001367 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001368 jint start = shadow_frame->GetVReg(arg_offset + 1);
1369 jint length = shadow_frame->GetVReg(arg_offset + 2);
Kenny Root57f91e82015-05-14 15:58:17 -07001370 DCHECK_GE(start, 0);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001371 DCHECK_GE(length, 0);
1372 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001373 Handle<mirror::String> h_string(
1374 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
Kenny Root57f91e82015-05-14 15:58:17 -07001375 DCHECK_LE(start, h_string->GetLength());
1376 DCHECK_LE(start + length, h_string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001377 Runtime* runtime = Runtime::Current();
1378 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1379 result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator));
1380}
1381
Kenny Root57f91e82015-05-14 15:58:17 -07001382// This allows getting the char array for new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001383void UnstartedRuntime::UnstartedStringToCharArray(
Kenny Root57f91e82015-05-14 15:58:17 -07001384 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001385 REQUIRES_SHARED(Locks::mutator_lock_) {
Kenny Root57f91e82015-05-14 15:58:17 -07001386 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1387 if (string == nullptr) {
1388 AbortTransactionOrFail(self, "String.charAt with null object");
1389 return;
1390 }
1391 result->SetL(string->ToCharArray(self));
1392}
1393
Andreas Gampebc4d2182016-02-22 10:03:12 -08001394// This allows statically initializing ConcurrentHashMap and SynchronousQueue.
1395void UnstartedRuntime::UnstartedReferenceGetReferent(
1396 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001397 ObjPtr<mirror::Reference> const ref = down_cast<mirror::Reference*>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001398 shadow_frame->GetVRegReference(arg_offset));
1399 if (ref == nullptr) {
1400 AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1401 return;
1402 }
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001403 ObjPtr<mirror::Object> const referent =
Andreas Gampebc4d2182016-02-22 10:03:12 -08001404 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1405 result->SetL(referent);
1406}
1407
1408// This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1409// conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1410// where we can predict the behavior (somewhat).
1411// Note: this is required (instead of lazy initialization) as these classes are used in the static
1412// initialization of other classes, so will *use* the value.
1413void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1414 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001415 if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001416 // SynchronousQueue really only separates between single- and multiprocessor case. Return
1417 // 8 as a conservative upper approximation.
1418 result->SetI(8);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001419 } else if (CheckCallers(shadow_frame,
1420 { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001421 // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1422 // a good upper bound.
1423 // TODO: Consider resetting in the zygote?
1424 result->SetI(8);
1425 } else {
1426 // Not supported.
1427 AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1428 }
1429}
1430
1431// This allows accessing ConcurrentHashMap/SynchronousQueue.
1432
1433void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1434 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1435 // Argument 0 is the Unsafe instance, skip.
1436 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1437 if (obj == nullptr) {
1438 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1439 return;
1440 }
1441 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1442 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1443 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001444 bool success;
1445 // Check whether we're in a transaction, call accordingly.
1446 if (Runtime::Current()->IsActiveTransaction()) {
1447 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1448 expectedValue,
1449 newValue);
1450 } else {
1451 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1452 expectedValue,
1453 newValue);
1454 }
1455 result->SetZ(success ? 1 : 0);
1456}
1457
1458void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1459 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1460 // Argument 0 is the Unsafe instance, skip.
1461 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1462 if (obj == nullptr) {
1463 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1464 return;
1465 }
1466 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1467 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1468 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 5);
1469
1470 // Must use non transactional mode.
1471 if (kUseReadBarrier) {
1472 // Need to make sure the reference stored in the field is a to-space one before attempting the
1473 // CAS or the CAS could fail incorrectly.
1474 mirror::HeapReference<mirror::Object>* field_addr =
1475 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1476 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001477 ReadBarrier::Barrier<
1478 mirror::Object,
1479 /* kIsVolatile */ false,
1480 kWithReadBarrier,
1481 /* kAlwaysUpdateField */ true>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001482 obj,
1483 MemberOffset(offset),
1484 field_addr);
1485 }
1486 bool success;
1487 // Check whether we're in a transaction, call accordingly.
1488 if (Runtime::Current()->IsActiveTransaction()) {
1489 success = obj->CasFieldStrongSequentiallyConsistentObject<true>(MemberOffset(offset),
1490 expected_value,
1491 newValue);
1492 } else {
1493 success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
1494 expected_value,
1495 newValue);
1496 }
1497 result->SetZ(success ? 1 : 0);
1498}
1499
1500void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1501 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001502 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001503 // Argument 0 is the Unsafe instance, skip.
1504 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1505 if (obj == nullptr) {
1506 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1507 return;
1508 }
1509 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1510 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1511 result->SetL(value);
1512}
1513
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001514void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1515 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001516 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001517 // Argument 0 is the Unsafe instance, skip.
1518 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1519 if (obj == nullptr) {
1520 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1521 return;
1522 }
1523 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1524 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1525 if (Runtime::Current()->IsActiveTransaction()) {
1526 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1527 } else {
1528 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1529 }
1530}
1531
Andreas Gampebc4d2182016-02-22 10:03:12 -08001532void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1533 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001534 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001535 // Argument 0 is the Unsafe instance, skip.
1536 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1537 if (obj == nullptr) {
1538 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1539 return;
1540 }
1541 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1542 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 4);
Orion Hodson27b96762018-03-13 16:06:57 +00001543 std::atomic_thread_fence(std::memory_order_release);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001544 if (Runtime::Current()->IsActiveTransaction()) {
1545 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1546 } else {
1547 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1548 }
1549}
1550
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001551// A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1552// of correctly handling the corner cases.
1553void UnstartedRuntime::UnstartedIntegerParseInt(
1554 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001555 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001556 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1557 if (obj == nullptr) {
1558 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1559 return;
1560 }
1561
1562 std::string string_value = obj->AsString()->ToModifiedUtf8();
1563 if (string_value.empty()) {
1564 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1565 return;
1566 }
1567
1568 const char* c_str = string_value.c_str();
1569 char *end;
1570 // Can we set errno to 0? Is this always a variable, and not a macro?
1571 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1572 int64_t l = strtol(c_str, &end, 10);
1573
1574 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1575 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1576 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1577 return;
1578 }
1579 if (l == 0) {
1580 // Check whether the string wasn't exactly zero.
1581 if (string_value != "0") {
1582 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1583 return;
1584 }
1585 } else if (*end != '\0') {
1586 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1587 return;
1588 }
1589
1590 result->SetI(static_cast<int32_t>(l));
1591}
1592
1593// A cutout for Long.parseLong.
1594//
1595// Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1596// well.
1597void UnstartedRuntime::UnstartedLongParseLong(
1598 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001599 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001600 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1601 if (obj == nullptr) {
1602 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1603 return;
1604 }
1605
1606 std::string string_value = obj->AsString()->ToModifiedUtf8();
1607 if (string_value.empty()) {
1608 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1609 return;
1610 }
1611
1612 const char* c_str = string_value.c_str();
1613 char *end;
1614 // Can we set errno to 0? Is this always a variable, and not a macro?
1615 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1616 int64_t l = strtol(c_str, &end, 10);
1617
1618 // Note: comparing against int32_t min/max is intentional here.
1619 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1620 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1621 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1622 return;
1623 }
1624 if (l == 0) {
1625 // Check whether the string wasn't exactly zero.
1626 if (string_value != "0") {
1627 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1628 return;
1629 }
1630 } else if (*end != '\0') {
1631 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1632 return;
1633 }
1634
1635 result->SetJ(l);
1636}
1637
Andreas Gampe715fdc22016-04-18 17:07:30 -07001638void UnstartedRuntime::UnstartedMethodInvoke(
1639 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001640 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe715fdc22016-04-18 17:07:30 -07001641 JNIEnvExt* env = self->GetJniEnv();
1642 ScopedObjectAccessUnchecked soa(self);
1643
Mathieu Chartier8778c522016-10-04 19:06:30 -07001644 ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001645 ScopedLocalRef<jobject> java_method(env,
Roland Levillain5e8d5f02016-10-18 18:03:43 +01001646 java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001647
Mathieu Chartier8778c522016-10-04 19:06:30 -07001648 ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001649 ScopedLocalRef<jobject> java_receiver(env,
1650 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1651
Mathieu Chartier8778c522016-10-04 19:06:30 -07001652 ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001653 ScopedLocalRef<jobject> java_args(env,
1654 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1655
1656 ScopedLocalRef<jobject> result_jobj(env,
1657 InvokeMethod(soa, java_method.get(), java_receiver.get(), java_args.get()));
1658
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001659 result->SetL(self->DecodeJObject(result_jobj.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001660
1661 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1662 // InvocationTargetExceptions.
1663 if (self->IsExceptionPending()) {
1664 AbortTransactionOrFail(self, "Failed Method.invoke");
1665 }
1666}
1667
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001668void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1669 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1670 REQUIRES_SHARED(Locks::mutator_lock_) {
1671 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1672 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1673}
Andreas Gampebc4d2182016-02-22 10:03:12 -08001674
Orion Hodson43f0cdb2017-10-10 14:47:32 +01001675// Checks whether the runtime is s64-bit. This is needed for the clinit of
1676// java.lang.invoke.VarHandle clinit. The clinit determines sets of
1677// available VarHandle accessors and these differ based on machine
1678// word size.
1679void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1680 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1681 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1682 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1683 jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1684 result->SetZ(is64bit);
1685}
1686
Mathieu Chartiere401d142015-04-22 13:56:20 -07001687void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
1688 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1689 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001690 int32_t length = args[1];
1691 DCHECK_GE(length, 0);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001692 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001693 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001694 ObjPtr<mirror::Class> array_class =
1695 runtime->GetClassLinker()->FindArrayClass(self, &element_class);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001696 DCHECK(array_class != nullptr);
1697 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001698 result->SetL(mirror::Array::Alloc<true, true>(self,
1699 array_class,
1700 length,
1701 array_class->GetComponentSizeShift(),
1702 allocator));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001703}
1704
Mathieu Chartiere401d142015-04-22 13:56:20 -07001705void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1706 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1707 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001708 result->SetL(nullptr);
1709}
1710
Mathieu Chartiere401d142015-04-22 13:56:20 -07001711void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1712 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1713 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001714 NthCallerVisitor visitor(self, 3);
1715 visitor.WalkStack();
1716 if (visitor.caller != nullptr) {
1717 result->SetL(visitor.caller->GetDeclaringClass());
1718 }
1719}
1720
Mathieu Chartiere401d142015-04-22 13:56:20 -07001721void UnstartedRuntime::UnstartedJNIMathLog(
1722 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1723 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001724 JValue value;
1725 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1726 result->SetD(log(value.GetD()));
1727}
1728
Mathieu Chartiere401d142015-04-22 13:56:20 -07001729void UnstartedRuntime::UnstartedJNIMathExp(
1730 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1731 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001732 JValue value;
1733 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1734 result->SetD(exp(value.GetD()));
1735}
1736
Andreas Gampebc4d2182016-02-22 10:03:12 -08001737void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1738 Thread* self ATTRIBUTE_UNUSED,
1739 ArtMethod* method ATTRIBUTE_UNUSED,
1740 mirror::Object* receiver ATTRIBUTE_UNUSED,
1741 uint32_t* args ATTRIBUTE_UNUSED,
1742 JValue* result) {
1743 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1744 ? 0
1745 : 1);
1746}
1747
Mathieu Chartiere401d142015-04-22 13:56:20 -07001748void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1749 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1750 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001751 StackHandleScope<1> hs(self);
1752 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1753}
1754
Andreas Gampebc4d2182016-02-22 10:03:12 -08001755void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1756 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1757 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1758 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1759 result->SetD(bit_cast<double>(long_input));
1760}
1761
Mathieu Chartiere401d142015-04-22 13:56:20 -07001762void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1763 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1764 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001765 result->SetI(args[0]);
1766}
1767
Mathieu Chartiere401d142015-04-22 13:56:20 -07001768void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1769 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1770 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001771 result->SetI(args[0]);
1772}
1773
Mathieu Chartiere401d142015-04-22 13:56:20 -07001774void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1775 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1776 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001777 result->SetL(receiver->Clone(self));
1778}
1779
Mathieu Chartiere401d142015-04-22 13:56:20 -07001780void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1781 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1782 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001783 receiver->NotifyAll(self);
1784}
1785
Mathieu Chartiere401d142015-04-22 13:56:20 -07001786void UnstartedRuntime::UnstartedJNIStringCompareTo(
1787 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver, uint32_t* args,
1788 JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001789 mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
1790 if (rhs == nullptr) {
Andreas Gampe068b0c02015-03-11 12:44:47 -07001791 AbortTransactionOrFail(self, "String.compareTo with null object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001792 }
1793 result->SetI(receiver->AsString()->CompareTo(rhs));
1794}
1795
Mathieu Chartiere401d142015-04-22 13:56:20 -07001796void UnstartedRuntime::UnstartedJNIStringIntern(
1797 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1798 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001799 result->SetL(receiver->AsString()->Intern());
1800}
1801
Mathieu Chartiere401d142015-04-22 13:56:20 -07001802void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1803 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1804 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001805 StackHandleScope<2> hs(self);
1806 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1807 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1808 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1809}
1810
Mathieu Chartiere401d142015-04-22 13:56:20 -07001811void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1812 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1813 uint32_t* args, JValue* result) {
Andreas Gampee598e042015-04-10 14:57:10 -07001814 int32_t length = static_cast<int32_t>(args[1]);
1815 if (length < 0) {
1816 ThrowNegativeArraySizeException(length);
1817 return;
1818 }
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001819 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
Andreas Gampee598e042015-04-10 14:57:10 -07001820 Runtime* runtime = Runtime::Current();
1821 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001822 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, &element_class);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001823 if (UNLIKELY(array_class == nullptr)) {
Andreas Gampee598e042015-04-10 14:57:10 -07001824 CHECK(self->IsExceptionPending());
1825 return;
1826 }
1827 DCHECK(array_class->IsObjectArrayClass());
1828 mirror::Array* new_array = mirror::ObjectArray<mirror::Object*>::Alloc(
1829 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1830 result->SetL(new_array);
1831}
1832
Mathieu Chartiere401d142015-04-22 13:56:20 -07001833void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1834 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1835 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001836 ScopedObjectAccessUnchecked soa(self);
1837 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001838 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<true>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001839 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001840 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<false>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001841 }
1842}
1843
Mathieu Chartiere401d142015-04-22 13:56:20 -07001844void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
1845 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1846 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001847 result->SetZ(JNI_TRUE);
1848}
1849
Mathieu Chartiere401d142015-04-22 13:56:20 -07001850void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
1851 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1852 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001853 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1854 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1855 jint expectedValue = args[3];
1856 jint newValue = args[4];
1857 bool success;
1858 if (Runtime::Current()->IsActiveTransaction()) {
1859 success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
1860 expectedValue, newValue);
1861 } else {
1862 success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
1863 expectedValue, newValue);
1864 }
1865 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1866}
1867
Narayan Kamath34a316f2016-03-30 13:11:18 +01001868void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(
1869 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1870 uint32_t* args, JValue* result) {
1871 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1872 if (obj == nullptr) {
1873 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1874 return;
1875 }
1876
1877 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1878 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1879}
1880
Mathieu Chartiere401d142015-04-22 13:56:20 -07001881void UnstartedRuntime::UnstartedJNIUnsafePutObject(
1882 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1883 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001884 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1885 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1886 mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
1887 if (Runtime::Current()->IsActiveTransaction()) {
1888 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1889 } else {
1890 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1891 }
1892}
1893
Andreas Gampe799681b2015-05-15 19:24:12 -07001894void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001895 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1896 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001897 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1898 Primitive::Type primitive_type = component->GetPrimitiveType();
1899 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1900}
1901
Andreas Gampe799681b2015-05-15 19:24:12 -07001902void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001903 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1904 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001905 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1906 Primitive::Type primitive_type = component->GetPrimitiveType();
1907 result->SetI(Primitive::ComponentSize(primitive_type));
1908}
1909
Andreas Gampedd9d0552015-03-09 12:57:41 -07001910typedef void (*InvokeHandler)(Thread* self, ShadowFrame* shadow_frame, JValue* result,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001911 size_t arg_size);
1912
Mathieu Chartiere401d142015-04-22 13:56:20 -07001913typedef void (*JNIHandler)(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001914 uint32_t* args, JValue* result);
1915
1916static bool tables_initialized_ = false;
1917static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
1918static std::unordered_map<std::string, JNIHandler> jni_handlers_;
1919
Andreas Gampe799681b2015-05-15 19:24:12 -07001920void UnstartedRuntime::InitializeInvokeHandlers() {
1921#define UNSTARTED_DIRECT(ShortName, Sig) \
1922 invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
1923#include "unstarted_runtime_list.h"
1924 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
1925#undef UNSTARTED_RUNTIME_DIRECT_LIST
1926#undef UNSTARTED_RUNTIME_JNI_LIST
1927#undef UNSTARTED_DIRECT
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001928}
1929
Andreas Gampe799681b2015-05-15 19:24:12 -07001930void UnstartedRuntime::InitializeJNIHandlers() {
1931#define UNSTARTED_JNI(ShortName, Sig) \
1932 jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
1933#include "unstarted_runtime_list.h"
1934 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
1935#undef UNSTARTED_RUNTIME_DIRECT_LIST
1936#undef UNSTARTED_RUNTIME_JNI_LIST
1937#undef UNSTARTED_JNI
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001938}
1939
Andreas Gampe799681b2015-05-15 19:24:12 -07001940void UnstartedRuntime::Initialize() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001941 CHECK(!tables_initialized_);
1942
Andreas Gampe799681b2015-05-15 19:24:12 -07001943 InitializeInvokeHandlers();
1944 InitializeJNIHandlers();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001945
1946 tables_initialized_ = true;
1947}
1948
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001949void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
Andreas Gampe799681b2015-05-15 19:24:12 -07001950 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001951 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
1952 // problems in core libraries.
1953 CHECK(tables_initialized_);
1954
David Sehr709b0702016-10-13 09:12:37 -07001955 std::string name(ArtMethod::PrettyMethod(shadow_frame->GetMethod()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001956 const auto& iter = invoke_handlers_.find(name);
1957 if (iter != invoke_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001958 // Clear out the result in case it's not zeroed out.
1959 result->SetL(0);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001960
1961 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
1962 self->PushShadowFrame(shadow_frame);
1963
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001964 (*iter->second)(self, shadow_frame, result, arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001965
1966 self->PopShadowFrame();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001967 } else {
1968 // Not special, continue with regular interpreter execution.
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001969 ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001970 }
1971}
1972
1973// 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 -07001974void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe799681b2015-05-15 19:24:12 -07001975 uint32_t* args, JValue* result) {
David Sehr709b0702016-10-13 09:12:37 -07001976 std::string name(ArtMethod::PrettyMethod(method));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001977 const auto& iter = jni_handlers_.find(name);
1978 if (iter != jni_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001979 // Clear out the result in case it's not zeroed out.
1980 result->SetL(0);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001981 (*iter->second)(self, method, receiver, args, result);
1982 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02001983 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
1984 name.c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001985 } else {
David Sehr709b0702016-10-13 09:12:37 -07001986 LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001987 "non-transactional runtime";
1988 }
1989}
1990
1991} // namespace interpreter
1992} // namespace art