blob: 7abb00783835470ef6c5e725fd2255bab7b57a5d [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 Sehr8f4b0562018-03-02 12:01:51 -080036#include "base/quasi_atomic.h"
David Sehrc75f0af2018-04-05 11:02:03 -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
Vladimir Marko55c12cd2018-05-22 15:33:48 +0100134 ObjPtr<mirror::Class> found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700135 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);
Vladimir Marko55c12cd2018-05-22 15:33:48 +0100145 HandleWrapperObjPtr<mirror::Class> h_class = hs.NewHandleWrapper(&found);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700146 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 Kamathe453a8d2018-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 Brazdil6ca80d22018-03-12 18:01:18 +0000187 member,
188 frame->GetMethod()->GetDeclaringClass()->GetClassLoader(),
David Brazdilf2a300b2018-03-27 08:14:25 +0000189 frame->GetMethod()->GetDeclaringClass()->GetDexCache(),
Narayan Kamathe453a8d2018-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 }
Vladimir Marko55c12cd2018-05-22 15:33:48 +0100272 Handle<mirror::Class> h_klass(hs.NewHandle(param->AsClass()));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700273
274 // Check that it's not null.
Andreas Gampefa4333d2017-02-14 11:10:34 -0800275 if (h_klass == nullptr) {
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700276 AbortTransactionOrFail(self, "Class reference is null for newInstance");
277 return;
278 }
279
280 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
281 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko55c12cd2018-05-22 15:33:48 +0100282 if (h_klass->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200283 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700284 h_klass->PrettyClass().c_str());
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700285 return;
286 }
287 }
288
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700289 // There are two situations in which we'll abort this run.
290 // 1) If the class isn't yet initialized and initialization fails.
291 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
292 // Note that 2) could likely be handled here, but for safety abort the transaction.
293 bool ok = false;
Mathieu Chartiere401d142015-04-22 13:56:20 -0700294 auto* cl = Runtime::Current()->GetClassLinker();
295 if (cl->EnsureInitialized(self, h_klass, true, true)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000296 ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
David Brazdila02cb112018-01-31 11:36:39 +0000297 if (cons != nullptr && ShouldBlockAccessToMember(cons, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000298 cons = nullptr;
299 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700300 if (cons != nullptr) {
Vladimir Marko55c12cd2018-05-22 15:33:48 +0100301 Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800302 CHECK(h_obj != nullptr); // We don't expect OOM at compile-time.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700303 EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700304 if (!self->IsExceptionPending()) {
305 result->SetL(h_obj.Get());
306 ok = true;
307 }
308 } else {
309 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
310 "Could not find default constructor for '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700311 h_klass->PrettyClass().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700312 }
313 }
314 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700315 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
David Sehr709b0702016-10-13 09:12:37 -0700316 h_klass->PrettyClass().c_str(),
317 mirror::Object::PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700318 }
319}
320
Andreas Gampe799681b2015-05-15 19:24:12 -0700321void UnstartedRuntime::UnstartedClassGetDeclaredField(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700322 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700323 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
324 // going the reflective Dex way.
Vladimir Marko55c12cd2018-05-22 15:33:48 +0100325 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
326 ObjPtr<mirror::String> name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700327 ArtField* found = nullptr;
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700328 for (ArtField& field : klass->GetIFields()) {
329 if (name2->Equals(field.GetName())) {
330 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700331 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700332 }
333 }
334 if (found == nullptr) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700335 for (ArtField& field : klass->GetSFields()) {
336 if (name2->Equals(field.GetName())) {
337 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700338 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700339 }
340 }
341 }
David Brazdila02cb112018-01-31 11:36:39 +0000342 if (found != nullptr && ShouldBlockAccessToMember(found, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000343 found = nullptr;
344 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700345 if (found == nullptr) {
346 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
347 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
David Sehr709b0702016-10-13 09:12:37 -0700348 klass->PrettyDescriptor().c_str());
Andreas Gampe068b0c02015-03-11 12:44:47 -0700349 return;
350 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700351 Runtime* runtime = Runtime::Current();
Andreas Gampe542451c2016-07-26 09:02:02 -0700352 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Andreas Gampee01e3642016-07-25 13:06:04 -0700353 mirror::Field* field;
354 if (runtime->IsActiveTransaction()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700355 if (pointer_size == PointerSize::k64) {
356 field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
357 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700358 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700359 field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
360 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700361 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700362 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700363 if (pointer_size == PointerSize::k64) {
364 field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
365 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700366 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700367 field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
368 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700369 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700370 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700371 result->SetL(field);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700372}
373
Andreas Gampebc4d2182016-02-22 10:03:12 -0800374// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
375void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
376 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
377 // Special managed code cut-out to allow method lookup in a un-started runtime.
Vladimir Marko55c12cd2018-05-22 15:33:48 +0100378 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
Andreas Gampebc4d2182016-02-22 10:03:12 -0800379 if (klass == nullptr) {
380 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
381 return;
382 }
Vladimir Marko55c12cd2018-05-22 15:33:48 +0100383 ObjPtr<mirror::String> name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
384 ObjPtr<mirror::ObjectArray<mirror::Class>> args =
Andreas Gampebc4d2182016-02-22 10:03:12 -0800385 shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700386 Runtime* runtime = Runtime::Current();
387 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700388 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700389 ObjPtr<mirror::Method> method;
Andreas Gampee01e3642016-07-25 13:06:04 -0700390 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700391 if (pointer_size == PointerSize::k64) {
392 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
393 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700394 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700395 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
396 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700397 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800398 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700399 if (pointer_size == PointerSize::k64) {
400 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
401 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700402 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700403 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
404 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700405 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800406 }
David Brazdila02cb112018-01-31 11:36:39 +0000407 if (method != nullptr && ShouldBlockAccessToMember(method->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000408 method = nullptr;
409 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700410 result->SetL(method);
Andreas Gampebc4d2182016-02-22 10:03:12 -0800411}
412
Andreas Gampe6039e562016-04-05 18:18:43 -0700413// Special managed code cut-out to allow constructor lookup in a un-started runtime.
414void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
415 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Vladimir Marko55c12cd2018-05-22 15:33:48 +0100416 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
Andreas Gampe6039e562016-04-05 18:18:43 -0700417 if (klass == nullptr) {
418 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
419 return;
420 }
421 mirror::ObjectArray<mirror::Class>* args =
422 shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700423 Runtime* runtime = Runtime::Current();
424 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700425 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700426 ObjPtr<mirror::Constructor> constructor;
Andreas Gampee01e3642016-07-25 13:06:04 -0700427 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700428 if (pointer_size == PointerSize::k64) {
429 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
430 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700431 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700432 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
433 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700434 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700435 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700436 if (pointer_size == PointerSize::k64) {
437 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
438 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700439 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700440 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
441 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700442 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700443 }
David Brazdil5a61bb72018-01-19 16:59:46 +0000444 if (constructor != nullptr &&
David Brazdila02cb112018-01-31 11:36:39 +0000445 ShouldBlockAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000446 constructor = nullptr;
447 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700448 result->SetL(constructor);
Andreas Gampe6039e562016-04-05 18:18:43 -0700449}
450
Andreas Gampeae78c262017-02-01 20:40:44 -0800451void UnstartedRuntime::UnstartedClassGetDeclaringClass(
452 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
453 StackHandleScope<1> hs(self);
454 Handle<mirror::Class> klass(hs.NewHandle(
455 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
456 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
457 result->SetL(nullptr);
458 return;
459 }
460 // Return null for anonymous classes.
461 JValue is_anon_result;
462 UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
463 if (is_anon_result.GetZ() != 0) {
464 result->SetL(nullptr);
465 return;
466 }
467 result->SetL(annotations::GetDeclaringClass(klass));
468}
469
Andreas Gampe633750c2016-02-19 10:49:50 -0800470void UnstartedRuntime::UnstartedClassGetEnclosingClass(
471 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
472 StackHandleScope<1> hs(self);
473 Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
474 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
475 result->SetL(nullptr);
476 }
David Sehr9323e6e2016-09-13 08:58:35 -0700477 result->SetL(annotations::GetEnclosingClass(klass));
Andreas Gampe633750c2016-02-19 10:49:50 -0800478}
479
Andreas Gampe715fdc22016-04-18 17:07:30 -0700480void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
481 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
482 StackHandleScope<1> hs(self);
483 Handle<mirror::Class> klass(hs.NewHandle(
484 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
485 const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
486 result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
487}
488
Andreas Gampe9486a162017-02-16 15:17:47 -0800489void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
490 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
491 StackHandleScope<1> hs(self);
492 Handle<mirror::Class> klass(hs.NewHandle(
493 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
494
495 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
496 result->SetL(nullptr);
497 return;
498 }
499
500 result->SetL(annotations::GetSignatureAnnotationForClass(klass));
501}
502
Andreas Gampeae78c262017-02-01 20:40:44 -0800503void UnstartedRuntime::UnstartedClassIsAnonymousClass(
504 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
505 StackHandleScope<1> hs(self);
506 Handle<mirror::Class> klass(hs.NewHandle(
507 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
508 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
509 result->SetZ(false);
510 return;
511 }
Vladimir Marko8092dff2018-05-22 13:56:09 +0100512 ObjPtr<mirror::String> class_name = nullptr;
Andreas Gampeae78c262017-02-01 20:40:44 -0800513 if (!annotations::GetInnerClass(klass, &class_name)) {
514 result->SetZ(false);
515 return;
516 }
517 result->SetZ(class_name == nullptr);
518}
519
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700520static std::unique_ptr<MemMap> FindAndExtractEntry(const std::string& jar_file,
521 const char* entry_name,
522 size_t* size,
523 std::string* error_msg) {
524 CHECK(size != nullptr);
525
526 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
527 if (zip_archive == nullptr) {
Mathieu Chartier6beced42016-11-15 15:51:31 -0800528 return nullptr;
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700529 }
530 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
531 if (zip_entry == nullptr) {
532 return nullptr;
533 }
534 std::unique_ptr<MemMap> tmp_map(
535 zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg));
536 if (tmp_map == nullptr) {
537 return nullptr;
538 }
539
540 // OK, from here everything seems fine.
541 *size = zip_entry->GetUncompressedLength();
542 return tmp_map;
543}
544
545static void GetResourceAsStream(Thread* self,
546 ShadowFrame* shadow_frame,
547 JValue* result,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700548 size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700549 mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
550 if (resource_obj == nullptr) {
551 AbortTransactionOrFail(self, "null name for getResourceAsStream");
552 return;
553 }
554 CHECK(resource_obj->IsString());
555 mirror::String* resource_name = resource_obj->AsString();
556
557 std::string resource_name_str = resource_name->ToModifiedUtf8();
558 if (resource_name_str.empty() || resource_name_str == "/") {
559 AbortTransactionOrFail(self,
560 "Unsupported name %s for getResourceAsStream",
561 resource_name_str.c_str());
562 return;
563 }
564 const char* resource_cstr = resource_name_str.c_str();
565 if (resource_cstr[0] == '/') {
566 resource_cstr++;
567 }
568
569 Runtime* runtime = Runtime::Current();
570
571 std::vector<std::string> split;
572 Split(runtime->GetBootClassPathString(), ':', &split);
573 if (split.empty()) {
574 AbortTransactionOrFail(self,
575 "Boot classpath not set or split error:: %s",
576 runtime->GetBootClassPathString().c_str());
577 return;
578 }
579
580 std::unique_ptr<MemMap> mem_map;
581 size_t map_size;
582 std::string last_error_msg; // Only store the last message (we could concatenate).
583
584 for (const std::string& jar_file : split) {
585 mem_map = FindAndExtractEntry(jar_file, resource_cstr, &map_size, &last_error_msg);
586 if (mem_map != nullptr) {
587 break;
588 }
589 }
590
591 if (mem_map == nullptr) {
592 // Didn't find it. There's a good chance this will be the same at runtime, but still
593 // conservatively abort the transaction here.
594 AbortTransactionOrFail(self,
595 "Could not find resource %s. Last error was %s.",
596 resource_name_str.c_str(),
597 last_error_msg.c_str());
598 return;
599 }
600
601 StackHandleScope<3> hs(self);
602
603 // Create byte array for content.
604 Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800605 if (h_array == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700606 AbortTransactionOrFail(self, "Could not find/create byte array class");
607 return;
608 }
609 // Copy in content.
610 memcpy(h_array->GetData(), mem_map->Begin(), map_size);
611 // Be proactive releasing memory.
Andreas Gampeeac4f282017-04-26 21:07:04 -0700612 mem_map.reset();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700613
614 // Create a ByteArrayInputStream.
615 Handle<mirror::Class> h_class(hs.NewHandle(
616 runtime->GetClassLinker()->FindClass(self,
617 "Ljava/io/ByteArrayInputStream;",
618 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800619 if (h_class == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700620 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
621 return;
622 }
623 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
624 AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
625 return;
626 }
627
628 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800629 if (h_obj == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700630 AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
631 return;
632 }
633
634 auto* cl = Runtime::Current()->GetClassLinker();
Vladimir Markoba118822017-06-12 15:41:56 +0100635 ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700636 if (constructor == nullptr) {
637 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
638 return;
639 }
640
641 uint32_t args[1];
642 args[0] = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_array.Get()));
643 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
644
645 if (self->IsExceptionPending()) {
646 AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
647 return;
648 }
649
650 result->SetL(h_obj.Get());
651}
652
653void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
654 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
655 {
656 mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
657 CHECK(this_obj != nullptr);
658 CHECK(this_obj->IsClassLoader());
659
660 StackHandleScope<1> hs(self);
661 Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
662
663 if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
664 this_classloader_class.Get()) {
665 AbortTransactionOrFail(self,
David Sehr709b0702016-10-13 09:12:37 -0700666 "Unsupported classloader type %s for getResourceAsStream",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700667 mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700668 return;
669 }
670 }
671
672 GetResourceAsStream(self, shadow_frame, result, arg_offset);
673}
674
Andreas Gampe85bef7e2017-02-16 18:13:26 -0800675void UnstartedRuntime::UnstartedConstructorNewInstance0(
676 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
677 // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
678 StackHandleScope<4> hs(self);
679 Handle<mirror::Constructor> m = hs.NewHandle(
680 reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
681 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
682 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
683 shadow_frame->GetVRegReference(arg_offset + 1)));
684 Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
685 if (UNLIKELY(c->IsAbstract())) {
686 AbortTransactionOrFail(self, "Cannot handle abstract classes");
687 return;
688 }
689 // Verify that we can access the class.
690 if (!m->IsAccessible() && !c->IsPublic()) {
691 // Go 2 frames back, this method is always called from newInstance0, which is called from
692 // Constructor.newInstance(Object... args).
693 ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
694 // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
695 // access checks anyways. TODO: Investigate if this the correct behavior.
696 if (caller != nullptr && !caller->CanAccess(c.Get())) {
697 AbortTransactionOrFail(self, "Cannot access class");
698 return;
699 }
700 }
701 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
702 DCHECK(self->IsExceptionPending());
703 return;
704 }
705 if (c->IsClassClass()) {
706 AbortTransactionOrFail(self, "new Class() is not supported");
707 return;
708 }
709
710 // String constructor is replaced by a StringFactory method in InvokeMethod.
711 if (c->IsStringClass()) {
712 // We don't support strings.
713 AbortTransactionOrFail(self, "String construction is not supported");
714 return;
715 }
716
717 Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
718 if (receiver == nullptr) {
719 AbortTransactionOrFail(self, "Could not allocate");
720 return;
721 }
722
723 // It's easier to use reflection to make the call, than create the uint32_t array.
724 {
725 ScopedObjectAccessUnchecked soa(self);
726 ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
727 soa.AddLocalReference<jobject>(m.Get()));
728 ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
729 soa.AddLocalReference<jobject>(receiver.Get()));
730 ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
731 soa.AddLocalReference<jobject>(args.Get()));
732 InvokeMethod(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
733 }
734 if (self->IsExceptionPending()) {
735 AbortTransactionOrFail(self, "Failed running constructor");
736 } else {
737 result->SetL(receiver.Get());
738 }
739}
740
Andreas Gampe799681b2015-05-15 19:24:12 -0700741void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700742 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700743 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
744 mirror::ClassLoader* class_loader =
745 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
746 StackHandleScope<2> hs(self);
747 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
748 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
749 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
750 "VMClassLoader.findLoadedClass", false, false);
751 // This might have an error pending. But semantics are to just return null.
752 if (self->IsExceptionPending()) {
753 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
David Sehr709b0702016-10-13 09:12:37 -0700754 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700755 if (type != "java.lang.InternalError") {
756 self->ClearException();
757 }
758 }
759}
760
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700761// Arraycopy emulation.
762// Note: we can't use any fast copy functions, as they are not available under transaction.
763
764template <typename T>
765static void PrimitiveArrayCopy(Thread* self,
766 mirror::Array* src_array, int32_t src_pos,
767 mirror::Array* dst_array, int32_t dst_pos,
768 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700769 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700770 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700771 AbortTransactionOrFail(self,
772 "Types mismatched in arraycopy: %s vs %s.",
773 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700774 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700775 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700776 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700777 return;
778 }
779 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
780 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
781 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
782 if (copy_forward) {
783 for (int32_t i = 0; i < length; ++i) {
784 dst->Set(dst_pos + i, src->Get(src_pos + i));
785 }
786 } else {
787 for (int32_t i = 1; i <= length; ++i) {
788 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
789 }
790 }
791}
792
Andreas Gampe799681b2015-05-15 19:24:12 -0700793void UnstartedRuntime::UnstartedSystemArraycopy(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700794 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700795 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700796 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
797 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700798 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700799
Andreas Gampe85a098a2016-03-31 13:30:53 -0700800 mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
801 mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
802 // Null checking. For simplicity, abort transaction.
803 if (src_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700804 AbortTransactionOrFail(self, "src is null in arraycopy.");
805 return;
806 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700807 if (dst_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700808 AbortTransactionOrFail(self, "dst is null in arraycopy.");
809 return;
810 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700811 // Test for arrayness. Throw ArrayStoreException.
812 if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
813 self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
814 return;
815 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700816
Andreas Gampe85a098a2016-03-31 13:30:53 -0700817 mirror::Array* src_array = src_obj->AsArray();
818 mirror::Array* dst_array = dst_obj->AsArray();
819
820 // Bounds checking. Throw IndexOutOfBoundsException.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700821 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
822 UNLIKELY(src_pos > src_array->GetLength() - length) ||
823 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700824 self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700825 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
826 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
827 length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700828 return;
829 }
830
831 // Type checking.
Vladimir Marko55c12cd2018-05-22 15:33:48 +0100832 ObjPtr<mirror::Class> src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700833 GetComponentType();
834
835 if (!src_type->IsPrimitive()) {
836 // Check that the second type is not primitive.
Vladimir Marko55c12cd2018-05-22 15:33:48 +0100837 ObjPtr<mirror::Class> trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700838 GetComponentType();
839 if (trg_type->IsPrimitiveInt()) {
840 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700841 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700842 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700843 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700844 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700845 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700846 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700847
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700848 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
849 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
850 if (src == dst) {
851 // Can overlap, but not have type mismatches.
Andreas Gampe85a098a2016-03-31 13:30:53 -0700852 // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700853 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
854 if (copy_forward) {
855 for (int32_t i = 0; i < length; ++i) {
856 dst->Set(dst_pos + i, src->Get(src_pos + i));
857 }
858 } else {
859 for (int32_t i = 1; i <= length; ++i) {
860 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
861 }
862 }
863 } else {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700864 // We're being lazy here. Optimally this could be a memcpy (if component types are
865 // assignable), but the ObjectArray implementation doesn't support transactions. The
866 // checking version, however, does.
867 if (Runtime::Current()->IsActiveTransaction()) {
868 dst->AssignableCheckingMemcpy<true>(
869 dst_pos, src, src_pos, length, true /* throw_exception */);
870 } else {
871 dst->AssignableCheckingMemcpy<false>(
872 dst_pos, src, src_pos, length, true /* throw_exception */);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700873 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700874 }
Andreas Gampe5c9af612016-04-05 14:16:10 -0700875 } else if (src_type->IsPrimitiveByte()) {
876 PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700877 } else if (src_type->IsPrimitiveChar()) {
878 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
879 } else if (src_type->IsPrimitiveInt()) {
880 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700881 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700882 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700883 src_type->PrettyDescriptor().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700884 }
885}
886
Andreas Gampe5c9af612016-04-05 14:16:10 -0700887void UnstartedRuntime::UnstartedSystemArraycopyByte(
888 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
889 // Just forward.
890 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
891}
892
Andreas Gampe799681b2015-05-15 19:24:12 -0700893void UnstartedRuntime::UnstartedSystemArraycopyChar(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700894 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700895 // Just forward.
896 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
897}
898
899void UnstartedRuntime::UnstartedSystemArraycopyInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700900 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700901 // Just forward.
902 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
903}
904
Narayan Kamath34a316f2016-03-30 13:11:18 +0100905void UnstartedRuntime::UnstartedSystemGetSecurityManager(
906 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
907 JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
908 result->SetL(nullptr);
909}
910
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700911static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
912
913static void GetSystemProperty(Thread* self,
914 ShadowFrame* shadow_frame,
915 JValue* result,
916 size_t arg_offset,
917 bool is_default_version)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700918 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700919 StackHandleScope<4> hs(self);
920 Handle<mirror::String> h_key(
921 hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800922 if (h_key == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700923 AbortTransactionOrFail(self, "getProperty key was null");
924 return;
925 }
926
927 // This is overall inefficient, but reflecting the values here is not great, either. So
928 // for simplicity, and with the assumption that the number of getProperty calls is not
929 // too great, just iterate each time.
930
931 // Get the storage class.
932 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
933 Handle<mirror::Class> h_props_class(hs.NewHandle(
934 class_linker->FindClass(self,
935 "Ljava/lang/AndroidHardcodedSystemProperties;",
936 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800937 if (h_props_class == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700938 AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
939 return;
940 }
941 if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
942 AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
943 return;
944 }
945
946 // Get the storage array.
947 ArtField* static_properties =
948 h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
949 "[[Ljava/lang/String;");
950 if (static_properties == nullptr) {
951 AbortTransactionOrFail(self,
952 "Could not find %s field",
953 kAndroidHardcodedSystemPropertiesFieldName);
954 return;
955 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700956 ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
957 Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
958 props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800959 if (h_2string_array == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700960 AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
961 return;
962 }
963
964 // Iterate over it.
965 const int32_t prop_count = h_2string_array->GetLength();
966 // Use the third handle as mutable.
967 MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
968 hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
969 for (int32_t i = 0; i < prop_count; ++i) {
970 h_string_array.Assign(h_2string_array->Get(i));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800971 if (h_string_array == nullptr ||
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700972 h_string_array->GetLength() != 2 ||
973 h_string_array->Get(0) == nullptr) {
974 AbortTransactionOrFail(self,
975 "Unexpected content of %s",
976 kAndroidHardcodedSystemPropertiesFieldName);
977 return;
978 }
979 if (h_key->Equals(h_string_array->Get(0))) {
980 // Found a value.
981 if (h_string_array->Get(1) == nullptr && is_default_version) {
982 // Null is being delegated to the default map, and then resolved to the given default value.
983 // As there's no default map, return the given value.
984 result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
985 } else {
986 result->SetL(h_string_array->Get(1));
987 }
988 return;
989 }
990 }
991
992 // Key is not supported.
993 AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
994}
995
996void UnstartedRuntime::UnstartedSystemGetProperty(
997 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
998 GetSystemProperty(self, shadow_frame, result, arg_offset, false);
999}
1000
1001void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
1002 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1003 GetSystemProperty(self, shadow_frame, result, arg_offset, true);
1004}
1005
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001006static std::string GetImmediateCaller(ShadowFrame* shadow_frame)
1007 REQUIRES_SHARED(Locks::mutator_lock_) {
1008 if (shadow_frame->GetLink() == nullptr) {
1009 return "<no caller>";
1010 }
1011 return ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1012}
1013
1014static bool CheckCallers(ShadowFrame* shadow_frame,
1015 std::initializer_list<std::string> allowed_call_stack)
1016 REQUIRES_SHARED(Locks::mutator_lock_) {
1017 for (const std::string& allowed_caller : allowed_call_stack) {
1018 if (shadow_frame->GetLink() == nullptr) {
1019 return false;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001020 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001021
1022 std::string found_caller = ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1023 if (allowed_caller != found_caller) {
1024 return false;
1025 }
1026
1027 shadow_frame = shadow_frame->GetLink();
1028 }
1029 return true;
1030}
1031
1032static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_descriptor)
1033 REQUIRES_SHARED(Locks::mutator_lock_) {
1034 // Find the requested class.
1035 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1036 ObjPtr<mirror::Class> klass =
1037 class_linker->FindClass(self, class_descriptor, ScopedNullHandle<mirror::ClassLoader>());
1038 if (klass == nullptr) {
1039 AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
1040 return nullptr;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001041 }
1042
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001043 StackHandleScope<2> hs(self);
1044 Handle<mirror::Class> h_class(hs.NewHandle(klass));
1045 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001046 if (h_obj != nullptr) {
Vladimir Markoba118822017-06-12 15:41:56 +01001047 ArtMethod* init_method = h_class->FindConstructor("()V", class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001048 if (init_method == nullptr) {
1049 AbortTransactionOrFail(self, "Could not find <init> for %s", class_descriptor);
1050 return nullptr;
1051 } else {
1052 JValue invoke_result;
1053 EnterInterpreterFromInvoke(self, init_method, h_obj.Get(), nullptr, nullptr);
1054 if (!self->IsExceptionPending()) {
1055 return h_obj.Get();
1056 }
1057 AbortTransactionOrFail(self, "Could not run <init> for %s", class_descriptor);
1058 }
1059 }
1060 AbortTransactionOrFail(self, "Could not allocate instance of %s", class_descriptor);
1061 return nullptr;
1062}
1063
1064void UnstartedRuntime::UnstartedThreadLocalGet(
1065 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1066 if (CheckCallers(shadow_frame, { "sun.misc.FloatingDecimal$BinaryToASCIIBuffer "
1067 "sun.misc.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1068 result->SetL(CreateInstanceOf(self, "Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;"));
1069 } else {
1070 AbortTransactionOrFail(self,
1071 "ThreadLocal.get() does not support %s",
1072 GetImmediateCaller(shadow_frame).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001073 }
1074}
1075
Andreas Gampebad529d2017-02-13 18:52:10 -08001076void UnstartedRuntime::UnstartedThreadCurrentThread(
1077 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1078 if (CheckCallers(shadow_frame,
1079 { "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1080 "java.lang.String, long)",
1081 "void java.lang.Thread.<init>()",
1082 "void java.util.logging.LogManager$Cleaner.<init>("
1083 "java.util.logging.LogManager)" })) {
1084 // Whitelist LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
1085 // Thread constructor only asks for the current thread to set up defaults and add the
1086 // thread as unstarted to the ThreadGroup. A faked-up main thread peer is good enough for
1087 // these purposes.
1088 Runtime::Current()->InitThreadGroups(self);
1089 jobject main_peer =
1090 self->CreateCompileTimePeer(self->GetJniEnv(),
1091 "main",
1092 false,
1093 Runtime::Current()->GetMainThreadGroup());
1094 if (main_peer == nullptr) {
1095 AbortTransactionOrFail(self, "Failed allocating peer");
1096 return;
1097 }
1098
1099 result->SetL(self->DecodeJObject(main_peer));
1100 self->GetJniEnv()->DeleteLocalRef(main_peer);
1101 } else {
1102 AbortTransactionOrFail(self,
1103 "Thread.currentThread() does not support %s",
1104 GetImmediateCaller(shadow_frame).c_str());
1105 }
1106}
1107
1108void UnstartedRuntime::UnstartedThreadGetNativeState(
1109 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1110 if (CheckCallers(shadow_frame,
1111 { "java.lang.Thread$State java.lang.Thread.getState()",
1112 "java.lang.ThreadGroup java.lang.Thread.getThreadGroup()",
1113 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1114 "java.lang.String, long)",
1115 "void java.lang.Thread.<init>()",
1116 "void java.util.logging.LogManager$Cleaner.<init>("
1117 "java.util.logging.LogManager)" })) {
1118 // Whitelist reading the state of the "main" thread when creating another (unstarted) thread
1119 // for LogManager. Report the thread as "new" (it really only counts that it isn't terminated).
1120 constexpr int32_t kJavaRunnable = 1;
1121 result->SetI(kJavaRunnable);
1122 } else {
1123 AbortTransactionOrFail(self,
1124 "Thread.getNativeState() does not support %s",
1125 GetImmediateCaller(shadow_frame).c_str());
1126 }
1127}
1128
Sergio Giro83261202016-04-11 20:49:20 +01001129void UnstartedRuntime::UnstartedMathCeil(
1130 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001131 result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
Sergio Giro83261202016-04-11 20:49:20 +01001132}
1133
1134void UnstartedRuntime::UnstartedMathFloor(
1135 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001136 result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001137}
1138
Andreas Gampeb8a00f92016-04-18 20:51:13 -07001139void UnstartedRuntime::UnstartedMathSin(
1140 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1141 result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
1142}
1143
1144void UnstartedRuntime::UnstartedMathCos(
1145 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1146 result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
1147}
1148
1149void UnstartedRuntime::UnstartedMathPow(
1150 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1151 result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
1152 shadow_frame->GetVRegDouble(arg_offset + 2)));
1153}
1154
Andreas Gampe799681b2015-05-15 19:24:12 -07001155void UnstartedRuntime::UnstartedObjectHashCode(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001156 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001157 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1158 result->SetI(obj->IdentityHashCode());
1159}
1160
Andreas Gampe799681b2015-05-15 19:24:12 -07001161void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
Andreas Gampedd9d0552015-03-09 12:57:41 -07001162 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001163 double in = shadow_frame->GetVRegDouble(arg_offset);
Roland Levillainda4d79b2015-03-24 14:36:11 +00001164 result->SetJ(bit_cast<int64_t, double>(in));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001165}
1166
Andreas Gampedd9d0552015-03-09 12:57:41 -07001167static void UnstartedMemoryPeek(
1168 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1169 int64_t address = shadow_frame->GetVRegLong(arg_offset);
1170 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
1171 // aborting the transaction.
1172
1173 switch (type) {
1174 case Primitive::kPrimByte: {
1175 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
1176 return;
1177 }
1178
1179 case Primitive::kPrimShort: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001180 typedef int16_t unaligned_short __attribute__ ((aligned (1)));
1181 result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001182 return;
1183 }
1184
1185 case Primitive::kPrimInt: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001186 typedef int32_t unaligned_int __attribute__ ((aligned (1)));
1187 result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001188 return;
1189 }
1190
1191 case Primitive::kPrimLong: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001192 typedef int64_t unaligned_long __attribute__ ((aligned (1)));
1193 result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001194 return;
1195 }
1196
1197 case Primitive::kPrimBoolean:
1198 case Primitive::kPrimChar:
1199 case Primitive::kPrimFloat:
1200 case Primitive::kPrimDouble:
1201 case Primitive::kPrimVoid:
1202 case Primitive::kPrimNot:
1203 LOG(FATAL) << "Not in the Memory API: " << type;
1204 UNREACHABLE();
1205 }
1206 LOG(FATAL) << "Should not reach here";
1207 UNREACHABLE();
1208}
1209
Andreas Gampe799681b2015-05-15 19:24:12 -07001210void UnstartedRuntime::UnstartedMemoryPeekByte(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001211 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001212 UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
1213}
1214
1215void UnstartedRuntime::UnstartedMemoryPeekShort(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001216 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001217 UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
1218}
1219
1220void UnstartedRuntime::UnstartedMemoryPeekInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001221 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001222 UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
1223}
1224
1225void UnstartedRuntime::UnstartedMemoryPeekLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001226 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001227 UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001228}
1229
1230static void UnstartedMemoryPeekArray(
1231 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001232 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampedd9d0552015-03-09 12:57:41 -07001233 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1234 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1235 if (obj == nullptr) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001236 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
Andreas Gampedd9d0552015-03-09 12:57:41 -07001237 return;
1238 }
1239 mirror::Array* array = obj->AsArray();
1240
1241 int offset = shadow_frame->GetVReg(arg_offset + 3);
1242 int count = shadow_frame->GetVReg(arg_offset + 4);
1243 if (offset < 0 || offset + count > array->GetLength()) {
1244 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
1245 offset, count, array->GetLength()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001246 Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
Andreas Gampedd9d0552015-03-09 12:57:41 -07001247 return;
1248 }
1249
1250 switch (type) {
1251 case Primitive::kPrimByte: {
1252 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
1253 mirror::ByteArray* byte_array = array->AsByteArray();
1254 for (int32_t i = 0; i < count; ++i, ++address) {
1255 byte_array->SetWithoutChecks<true>(i + offset, *address);
1256 }
1257 return;
1258 }
1259
1260 case Primitive::kPrimShort:
1261 case Primitive::kPrimInt:
1262 case Primitive::kPrimLong:
1263 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1264 UNREACHABLE();
1265
1266 case Primitive::kPrimBoolean:
1267 case Primitive::kPrimChar:
1268 case Primitive::kPrimFloat:
1269 case Primitive::kPrimDouble:
1270 case Primitive::kPrimVoid:
1271 case Primitive::kPrimNot:
1272 LOG(FATAL) << "Not in the Memory API: " << type;
1273 UNREACHABLE();
1274 }
1275 LOG(FATAL) << "Should not reach here";
1276 UNREACHABLE();
1277}
1278
Andreas Gampe799681b2015-05-15 19:24:12 -07001279void UnstartedRuntime::UnstartedMemoryPeekByteArray(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001280 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001281 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001282}
1283
Kenny Root1c9e61c2015-05-14 15:58:17 -07001284// This allows reading the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001285void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001286 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001287 jint start = shadow_frame->GetVReg(arg_offset + 1);
1288 jint end = shadow_frame->GetVReg(arg_offset + 2);
1289 jint index = shadow_frame->GetVReg(arg_offset + 4);
1290 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1291 if (string == nullptr) {
1292 AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1293 return;
1294 }
Kenny Root57f91e82015-05-14 15:58:17 -07001295 DCHECK_GE(start, 0);
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001296 DCHECK_LE(start, end);
1297 DCHECK_LE(end, string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001298 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001299 Handle<mirror::CharArray> h_char_array(
1300 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001301 DCHECK_GE(index, 0);
Kenny Root57f91e82015-05-14 15:58:17 -07001302 DCHECK_LE(index, h_char_array->GetLength());
1303 DCHECK_LE(end - start, h_char_array->GetLength() - index);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001304 string->GetChars(start, end, h_char_array, index);
1305}
1306
1307// This allows reading chars from the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001308void UnstartedRuntime::UnstartedStringCharAt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001309 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001310 jint index = shadow_frame->GetVReg(arg_offset + 1);
1311 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1312 if (string == nullptr) {
1313 AbortTransactionOrFail(self, "String.charAt with null object");
1314 return;
1315 }
1316 result->SetC(string->CharAt(index));
1317}
1318
Vladimir Marko92907f32017-02-20 14:08:30 +00001319// This allows creating String objects with replaced characters during compilation.
1320// String.doReplace(char, char) is called from String.replace(char, char) when there is a match.
1321void UnstartedRuntime::UnstartedStringDoReplace(
1322 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1323 jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
1324 jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001325 StackHandleScope<1> hs(self);
1326 Handle<mirror::String> string =
1327 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
Kenny Root57f91e82015-05-14 15:58:17 -07001328 if (string == nullptr) {
Vladimir Marko92907f32017-02-20 14:08:30 +00001329 AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
Kenny Root57f91e82015-05-14 15:58:17 -07001330 return;
1331 }
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001332 result->SetL(mirror::String::DoReplace(self, string, old_c, new_c));
Kenny Root57f91e82015-05-14 15:58:17 -07001333}
1334
Kenny Root1c9e61c2015-05-14 15:58:17 -07001335// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001336void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001337 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001338 jint offset = shadow_frame->GetVReg(arg_offset);
1339 jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1340 DCHECK_GE(char_count, 0);
1341 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001342 Handle<mirror::CharArray> h_char_array(
1343 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
Kenny Root1c9e61c2015-05-14 15:58:17 -07001344 Runtime* runtime = Runtime::Current();
1345 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1346 result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator));
1347}
1348
1349// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001350void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001351 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root57f91e82015-05-14 15:58:17 -07001352 mirror::String* to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1353 if (to_copy == nullptr) {
1354 AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1355 return;
1356 }
1357 StackHandleScope<1> hs(self);
1358 Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1359 Runtime* runtime = Runtime::Current();
1360 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1361 result->SetL(mirror::String::AllocFromString<true>(self, h_string->GetLength(), h_string, 0,
1362 allocator));
1363}
1364
Andreas Gampe799681b2015-05-15 19:24:12 -07001365void UnstartedRuntime::UnstartedStringFastSubstring(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001366 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001367 jint start = shadow_frame->GetVReg(arg_offset + 1);
1368 jint length = shadow_frame->GetVReg(arg_offset + 2);
Kenny Root57f91e82015-05-14 15:58:17 -07001369 DCHECK_GE(start, 0);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001370 DCHECK_GE(length, 0);
1371 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001372 Handle<mirror::String> h_string(
1373 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
Kenny Root57f91e82015-05-14 15:58:17 -07001374 DCHECK_LE(start, h_string->GetLength());
1375 DCHECK_LE(start + length, h_string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001376 Runtime* runtime = Runtime::Current();
1377 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1378 result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator));
1379}
1380
Kenny Root57f91e82015-05-14 15:58:17 -07001381// This allows getting the char array for new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001382void UnstartedRuntime::UnstartedStringToCharArray(
Kenny Root57f91e82015-05-14 15:58:17 -07001383 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001384 REQUIRES_SHARED(Locks::mutator_lock_) {
Kenny Root57f91e82015-05-14 15:58:17 -07001385 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1386 if (string == nullptr) {
1387 AbortTransactionOrFail(self, "String.charAt with null object");
1388 return;
1389 }
1390 result->SetL(string->ToCharArray(self));
1391}
1392
Andreas Gampebc4d2182016-02-22 10:03:12 -08001393// This allows statically initializing ConcurrentHashMap and SynchronousQueue.
1394void UnstartedRuntime::UnstartedReferenceGetReferent(
1395 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001396 ObjPtr<mirror::Reference> const ref = down_cast<mirror::Reference*>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001397 shadow_frame->GetVRegReference(arg_offset));
1398 if (ref == nullptr) {
1399 AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1400 return;
1401 }
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001402 ObjPtr<mirror::Object> const referent =
Andreas Gampebc4d2182016-02-22 10:03:12 -08001403 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1404 result->SetL(referent);
1405}
1406
1407// This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1408// conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1409// where we can predict the behavior (somewhat).
1410// Note: this is required (instead of lazy initialization) as these classes are used in the static
1411// initialization of other classes, so will *use* the value.
1412void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1413 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001414 if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001415 // SynchronousQueue really only separates between single- and multiprocessor case. Return
1416 // 8 as a conservative upper approximation.
1417 result->SetI(8);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001418 } else if (CheckCallers(shadow_frame,
1419 { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001420 // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1421 // a good upper bound.
1422 // TODO: Consider resetting in the zygote?
1423 result->SetI(8);
1424 } else {
1425 // Not supported.
1426 AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1427 }
1428}
1429
1430// This allows accessing ConcurrentHashMap/SynchronousQueue.
1431
1432void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1433 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1434 // Argument 0 is the Unsafe instance, skip.
1435 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1436 if (obj == nullptr) {
1437 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1438 return;
1439 }
1440 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1441 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1442 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001443 bool success;
1444 // Check whether we're in a transaction, call accordingly.
1445 if (Runtime::Current()->IsActiveTransaction()) {
1446 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1447 expectedValue,
1448 newValue);
1449 } else {
1450 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1451 expectedValue,
1452 newValue);
1453 }
1454 result->SetZ(success ? 1 : 0);
1455}
1456
1457void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1458 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1459 // Argument 0 is the Unsafe instance, skip.
1460 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1461 if (obj == nullptr) {
1462 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1463 return;
1464 }
1465 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1466 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1467 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 5);
1468
1469 // Must use non transactional mode.
1470 if (kUseReadBarrier) {
1471 // Need to make sure the reference stored in the field is a to-space one before attempting the
1472 // CAS or the CAS could fail incorrectly.
1473 mirror::HeapReference<mirror::Object>* field_addr =
1474 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1475 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001476 ReadBarrier::Barrier<
1477 mirror::Object,
1478 /* kIsVolatile */ false,
1479 kWithReadBarrier,
1480 /* kAlwaysUpdateField */ true>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001481 obj,
1482 MemberOffset(offset),
1483 field_addr);
1484 }
1485 bool success;
1486 // Check whether we're in a transaction, call accordingly.
1487 if (Runtime::Current()->IsActiveTransaction()) {
1488 success = obj->CasFieldStrongSequentiallyConsistentObject<true>(MemberOffset(offset),
1489 expected_value,
1490 newValue);
1491 } else {
1492 success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
1493 expected_value,
1494 newValue);
1495 }
1496 result->SetZ(success ? 1 : 0);
1497}
1498
1499void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1500 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001501 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001502 // Argument 0 is the Unsafe instance, skip.
1503 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1504 if (obj == nullptr) {
1505 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1506 return;
1507 }
1508 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1509 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1510 result->SetL(value);
1511}
1512
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001513void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1514 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001515 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001516 // Argument 0 is the Unsafe instance, skip.
1517 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1518 if (obj == nullptr) {
1519 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1520 return;
1521 }
1522 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1523 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1524 if (Runtime::Current()->IsActiveTransaction()) {
1525 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1526 } else {
1527 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1528 }
1529}
1530
Andreas Gampebc4d2182016-02-22 10:03:12 -08001531void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1532 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001533 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001534 // Argument 0 is the Unsafe instance, skip.
1535 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1536 if (obj == nullptr) {
1537 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1538 return;
1539 }
1540 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1541 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 4);
Orion Hodson2b6ac5f2018-03-13 16:06:57 +00001542 std::atomic_thread_fence(std::memory_order_release);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001543 if (Runtime::Current()->IsActiveTransaction()) {
1544 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1545 } else {
1546 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1547 }
1548}
1549
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001550// A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1551// of correctly handling the corner cases.
1552void UnstartedRuntime::UnstartedIntegerParseInt(
1553 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001554 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001555 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1556 if (obj == nullptr) {
1557 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1558 return;
1559 }
1560
1561 std::string string_value = obj->AsString()->ToModifiedUtf8();
1562 if (string_value.empty()) {
1563 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1564 return;
1565 }
1566
1567 const char* c_str = string_value.c_str();
1568 char *end;
1569 // Can we set errno to 0? Is this always a variable, and not a macro?
1570 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1571 int64_t l = strtol(c_str, &end, 10);
1572
1573 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1574 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1575 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1576 return;
1577 }
1578 if (l == 0) {
1579 // Check whether the string wasn't exactly zero.
1580 if (string_value != "0") {
1581 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1582 return;
1583 }
1584 } else if (*end != '\0') {
1585 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1586 return;
1587 }
1588
1589 result->SetI(static_cast<int32_t>(l));
1590}
1591
1592// A cutout for Long.parseLong.
1593//
1594// Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1595// well.
1596void UnstartedRuntime::UnstartedLongParseLong(
1597 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001598 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001599 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1600 if (obj == nullptr) {
1601 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1602 return;
1603 }
1604
1605 std::string string_value = obj->AsString()->ToModifiedUtf8();
1606 if (string_value.empty()) {
1607 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1608 return;
1609 }
1610
1611 const char* c_str = string_value.c_str();
1612 char *end;
1613 // Can we set errno to 0? Is this always a variable, and not a macro?
1614 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1615 int64_t l = strtol(c_str, &end, 10);
1616
1617 // Note: comparing against int32_t min/max is intentional here.
1618 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1619 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1620 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1621 return;
1622 }
1623 if (l == 0) {
1624 // Check whether the string wasn't exactly zero.
1625 if (string_value != "0") {
1626 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1627 return;
1628 }
1629 } else if (*end != '\0') {
1630 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1631 return;
1632 }
1633
1634 result->SetJ(l);
1635}
1636
Andreas Gampe715fdc22016-04-18 17:07:30 -07001637void UnstartedRuntime::UnstartedMethodInvoke(
1638 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001639 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe715fdc22016-04-18 17:07:30 -07001640 JNIEnvExt* env = self->GetJniEnv();
1641 ScopedObjectAccessUnchecked soa(self);
1642
Mathieu Chartier8778c522016-10-04 19:06:30 -07001643 ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001644 ScopedLocalRef<jobject> java_method(env,
Roland Levillain5e8d5f02016-10-18 18:03:43 +01001645 java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001646
Mathieu Chartier8778c522016-10-04 19:06:30 -07001647 ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001648 ScopedLocalRef<jobject> java_receiver(env,
1649 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1650
Mathieu Chartier8778c522016-10-04 19:06:30 -07001651 ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001652 ScopedLocalRef<jobject> java_args(env,
1653 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1654
1655 ScopedLocalRef<jobject> result_jobj(env,
1656 InvokeMethod(soa, java_method.get(), java_receiver.get(), java_args.get()));
1657
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001658 result->SetL(self->DecodeJObject(result_jobj.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001659
1660 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1661 // InvocationTargetExceptions.
1662 if (self->IsExceptionPending()) {
1663 AbortTransactionOrFail(self, "Failed Method.invoke");
1664 }
1665}
1666
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001667void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1668 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1669 REQUIRES_SHARED(Locks::mutator_lock_) {
1670 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1671 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1672}
Andreas Gampebc4d2182016-02-22 10:03:12 -08001673
Orion Hodson43f0cdb2017-10-10 14:47:32 +01001674// Checks whether the runtime is s64-bit. This is needed for the clinit of
1675// java.lang.invoke.VarHandle clinit. The clinit determines sets of
1676// available VarHandle accessors and these differ based on machine
1677// word size.
1678void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1679 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1680 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1681 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1682 jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1683 result->SetZ(is64bit);
1684}
1685
Mathieu Chartiere401d142015-04-22 13:56:20 -07001686void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
1687 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1688 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001689 int32_t length = args[1];
1690 DCHECK_GE(length, 0);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001691 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001692 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001693 ObjPtr<mirror::Class> array_class =
1694 runtime->GetClassLinker()->FindArrayClass(self, &element_class);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001695 DCHECK(array_class != nullptr);
1696 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001697 result->SetL(mirror::Array::Alloc<true, true>(self,
1698 array_class,
1699 length,
1700 array_class->GetComponentSizeShift(),
1701 allocator));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001702}
1703
Mathieu Chartiere401d142015-04-22 13:56:20 -07001704void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1705 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1706 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001707 result->SetL(nullptr);
1708}
1709
Mathieu Chartiere401d142015-04-22 13:56:20 -07001710void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1711 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1712 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001713 NthCallerVisitor visitor(self, 3);
1714 visitor.WalkStack();
1715 if (visitor.caller != nullptr) {
1716 result->SetL(visitor.caller->GetDeclaringClass());
1717 }
1718}
1719
Mathieu Chartiere401d142015-04-22 13:56:20 -07001720void UnstartedRuntime::UnstartedJNIMathLog(
1721 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1722 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001723 JValue value;
1724 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1725 result->SetD(log(value.GetD()));
1726}
1727
Mathieu Chartiere401d142015-04-22 13:56:20 -07001728void UnstartedRuntime::UnstartedJNIMathExp(
1729 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1730 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001731 JValue value;
1732 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1733 result->SetD(exp(value.GetD()));
1734}
1735
Andreas Gampebc4d2182016-02-22 10:03:12 -08001736void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1737 Thread* self ATTRIBUTE_UNUSED,
1738 ArtMethod* method ATTRIBUTE_UNUSED,
1739 mirror::Object* receiver ATTRIBUTE_UNUSED,
1740 uint32_t* args ATTRIBUTE_UNUSED,
1741 JValue* result) {
1742 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1743 ? 0
1744 : 1);
1745}
1746
Mathieu Chartiere401d142015-04-22 13:56:20 -07001747void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1748 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1749 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001750 StackHandleScope<1> hs(self);
1751 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1752}
1753
Andreas Gampebc4d2182016-02-22 10:03:12 -08001754void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1755 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1756 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1757 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1758 result->SetD(bit_cast<double>(long_input));
1759}
1760
Mathieu Chartiere401d142015-04-22 13:56:20 -07001761void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1762 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1763 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001764 result->SetI(args[0]);
1765}
1766
Mathieu Chartiere401d142015-04-22 13:56:20 -07001767void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1768 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1769 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001770 result->SetI(args[0]);
1771}
1772
Mathieu Chartiere401d142015-04-22 13:56:20 -07001773void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1774 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1775 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001776 result->SetL(receiver->Clone(self));
1777}
1778
Mathieu Chartiere401d142015-04-22 13:56:20 -07001779void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1780 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1781 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001782 receiver->NotifyAll(self);
1783}
1784
Mathieu Chartiere401d142015-04-22 13:56:20 -07001785void UnstartedRuntime::UnstartedJNIStringCompareTo(
1786 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver, uint32_t* args,
1787 JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001788 mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
1789 if (rhs == nullptr) {
Andreas Gampe068b0c02015-03-11 12:44:47 -07001790 AbortTransactionOrFail(self, "String.compareTo with null object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001791 }
1792 result->SetI(receiver->AsString()->CompareTo(rhs));
1793}
1794
Mathieu Chartiere401d142015-04-22 13:56:20 -07001795void UnstartedRuntime::UnstartedJNIStringIntern(
1796 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1797 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001798 result->SetL(receiver->AsString()->Intern());
1799}
1800
Mathieu Chartiere401d142015-04-22 13:56:20 -07001801void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1802 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1803 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001804 StackHandleScope<2> hs(self);
1805 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1806 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1807 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1808}
1809
Mathieu Chartiere401d142015-04-22 13:56:20 -07001810void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1811 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1812 uint32_t* args, JValue* result) {
Andreas Gampee598e042015-04-10 14:57:10 -07001813 int32_t length = static_cast<int32_t>(args[1]);
1814 if (length < 0) {
1815 ThrowNegativeArraySizeException(length);
1816 return;
1817 }
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001818 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
Andreas Gampee598e042015-04-10 14:57:10 -07001819 Runtime* runtime = Runtime::Current();
1820 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001821 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, &element_class);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001822 if (UNLIKELY(array_class == nullptr)) {
Andreas Gampee598e042015-04-10 14:57:10 -07001823 CHECK(self->IsExceptionPending());
1824 return;
1825 }
1826 DCHECK(array_class->IsObjectArrayClass());
1827 mirror::Array* new_array = mirror::ObjectArray<mirror::Object*>::Alloc(
1828 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1829 result->SetL(new_array);
1830}
1831
Mathieu Chartiere401d142015-04-22 13:56:20 -07001832void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1833 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1834 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001835 ScopedObjectAccessUnchecked soa(self);
1836 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001837 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<true>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001838 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001839 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<false>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001840 }
1841}
1842
Mathieu Chartiere401d142015-04-22 13:56:20 -07001843void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
1844 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1845 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001846 result->SetZ(JNI_TRUE);
1847}
1848
Mathieu Chartiere401d142015-04-22 13:56:20 -07001849void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
1850 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1851 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001852 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1853 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1854 jint expectedValue = args[3];
1855 jint newValue = args[4];
1856 bool success;
1857 if (Runtime::Current()->IsActiveTransaction()) {
1858 success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
1859 expectedValue, newValue);
1860 } else {
1861 success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
1862 expectedValue, newValue);
1863 }
1864 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1865}
1866
Narayan Kamath34a316f2016-03-30 13:11:18 +01001867void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(
1868 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1869 uint32_t* args, JValue* result) {
1870 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1871 if (obj == nullptr) {
1872 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1873 return;
1874 }
1875
1876 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1877 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1878}
1879
Mathieu Chartiere401d142015-04-22 13:56:20 -07001880void UnstartedRuntime::UnstartedJNIUnsafePutObject(
1881 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1882 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001883 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1884 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1885 mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
1886 if (Runtime::Current()->IsActiveTransaction()) {
1887 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1888 } else {
1889 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1890 }
1891}
1892
Andreas Gampe799681b2015-05-15 19:24:12 -07001893void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001894 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1895 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Vladimir Marko55c12cd2018-05-22 15:33:48 +01001896 ObjPtr<mirror::Class> component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001897 Primitive::Type primitive_type = component->GetPrimitiveType();
1898 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1899}
1900
Andreas Gampe799681b2015-05-15 19:24:12 -07001901void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001902 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1903 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Vladimir Marko55c12cd2018-05-22 15:33:48 +01001904 ObjPtr<mirror::Class> component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001905 Primitive::Type primitive_type = component->GetPrimitiveType();
1906 result->SetI(Primitive::ComponentSize(primitive_type));
1907}
1908
Andreas Gampedd9d0552015-03-09 12:57:41 -07001909typedef void (*InvokeHandler)(Thread* self, ShadowFrame* shadow_frame, JValue* result,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001910 size_t arg_size);
1911
Mathieu Chartiere401d142015-04-22 13:56:20 -07001912typedef void (*JNIHandler)(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001913 uint32_t* args, JValue* result);
1914
1915static bool tables_initialized_ = false;
1916static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
1917static std::unordered_map<std::string, JNIHandler> jni_handlers_;
1918
Andreas Gampe799681b2015-05-15 19:24:12 -07001919void UnstartedRuntime::InitializeInvokeHandlers() {
1920#define UNSTARTED_DIRECT(ShortName, Sig) \
1921 invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
1922#include "unstarted_runtime_list.h"
1923 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
1924#undef UNSTARTED_RUNTIME_DIRECT_LIST
1925#undef UNSTARTED_RUNTIME_JNI_LIST
1926#undef UNSTARTED_DIRECT
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001927}
1928
Andreas Gampe799681b2015-05-15 19:24:12 -07001929void UnstartedRuntime::InitializeJNIHandlers() {
1930#define UNSTARTED_JNI(ShortName, Sig) \
1931 jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
1932#include "unstarted_runtime_list.h"
1933 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
1934#undef UNSTARTED_RUNTIME_DIRECT_LIST
1935#undef UNSTARTED_RUNTIME_JNI_LIST
1936#undef UNSTARTED_JNI
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001937}
1938
Andreas Gampe799681b2015-05-15 19:24:12 -07001939void UnstartedRuntime::Initialize() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001940 CHECK(!tables_initialized_);
1941
Andreas Gampe799681b2015-05-15 19:24:12 -07001942 InitializeInvokeHandlers();
1943 InitializeJNIHandlers();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001944
1945 tables_initialized_ = true;
1946}
1947
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001948void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
Andreas Gampe799681b2015-05-15 19:24:12 -07001949 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001950 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
1951 // problems in core libraries.
1952 CHECK(tables_initialized_);
1953
David Sehr709b0702016-10-13 09:12:37 -07001954 std::string name(ArtMethod::PrettyMethod(shadow_frame->GetMethod()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001955 const auto& iter = invoke_handlers_.find(name);
1956 if (iter != invoke_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001957 // Clear out the result in case it's not zeroed out.
1958 result->SetL(0);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001959
1960 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
1961 self->PushShadowFrame(shadow_frame);
1962
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001963 (*iter->second)(self, shadow_frame, result, arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001964
1965 self->PopShadowFrame();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001966 } else {
1967 // Not special, continue with regular interpreter execution.
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001968 ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001969 }
1970}
1971
1972// 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 -07001973void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe799681b2015-05-15 19:24:12 -07001974 uint32_t* args, JValue* result) {
David Sehr709b0702016-10-13 09:12:37 -07001975 std::string name(ArtMethod::PrettyMethod(method));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001976 const auto& iter = jni_handlers_.find(name);
1977 if (iter != jni_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001978 // Clear out the result in case it's not zeroed out.
1979 result->SetL(0);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001980 (*iter->second)(self, method, receiver, args, result);
1981 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02001982 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
1983 name.c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001984 } else {
David Sehr709b0702016-10-13 09:12:37 -07001985 LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001986 "non-transactional runtime";
1987 }
1988}
1989
1990} // namespace interpreter
1991} // namespace art