blob: f8dd8293ca58b78cb02541a62af57f96da831bc4 [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"
36#include "class_linker.h"
37#include "common_throws.h"
38#include "entrypoints/entrypoint_utils-inl.h"
Andreas Gampebc4d2182016-02-22 10:03:12 -080039#include "gc/reference_processor.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070040#include "handle_scope-inl.h"
David Brazdil5a61bb72018-01-19 16:59:46 +000041#include "hidden_api.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070042#include "interpreter/interpreter_common.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070043#include "jvalue-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070044#include "mirror/array-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070045#include "mirror/class.h"
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070046#include "mirror/field-inl.h"
Narayan Kamath14832ef2016-08-05 11:44:32 +010047#include "mirror/method.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070048#include "mirror/object-inl.h"
49#include "mirror/object_array-inl.h"
50#include "mirror/string-inl.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070051#include "nativehelper/scoped_local_ref.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070052#include "nth_caller_visitor.h"
Andreas Gampe715fdc22016-04-18 17:07:30 -070053#include "reflection.h"
Andreas Gampe513061a2017-06-01 09:17:34 -070054#include "thread-inl.h"
Sebastien Hertz2fd7e692015-04-02 11:11:19 +020055#include "transaction.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070056#include "well_known_classes.h"
Andreas Gampef778eb22015-04-13 14:17:09 -070057#include "zip_archive.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070058
59namespace art {
60namespace interpreter {
61
Andreas Gampe46ee31b2016-12-14 10:11:49 -080062using android::base::StringAppendV;
63using android::base::StringPrintf;
64
Andreas Gampe068b0c02015-03-11 12:44:47 -070065static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
Sebastien Hertz45b15972015-04-03 16:07:05 +020066 __attribute__((__format__(__printf__, 2, 3)))
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070067 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertz45b15972015-04-03 16:07:05 +020068
69static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
Andreas Gampe068b0c02015-03-11 12:44:47 -070070 va_list args;
Andreas Gampe068b0c02015-03-11 12:44:47 -070071 if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +020072 va_start(args, fmt);
73 AbortTransactionV(self, fmt, args);
Andreas Gampe068b0c02015-03-11 12:44:47 -070074 va_end(args);
75 } else {
Sebastien Hertz45b15972015-04-03 16:07:05 +020076 va_start(args, fmt);
77 std::string msg;
78 StringAppendV(&msg, fmt, args);
79 va_end(args);
80 LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
Andreas Gampe068b0c02015-03-11 12:44:47 -070081 UNREACHABLE();
82 }
83}
84
Andreas Gampe8ce9c302016-04-15 21:24:28 -070085// Restricted support for character upper case / lower case. Only support ASCII, where
86// it's easy. Abort the transaction otherwise.
87static void CharacterLowerUpper(Thread* self,
88 ShadowFrame* shadow_frame,
89 JValue* result,
90 size_t arg_offset,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070091 bool to_lower_case) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8ce9c302016-04-15 21:24:28 -070092 uint32_t int_value = static_cast<uint32_t>(shadow_frame->GetVReg(arg_offset));
93
94 // Only ASCII (7-bit).
95 if (!isascii(int_value)) {
96 AbortTransactionOrFail(self,
97 "Only support ASCII characters for toLowerCase/toUpperCase: %u",
98 int_value);
99 return;
100 }
101
102 std::locale c_locale("C");
103 char char_value = static_cast<char>(int_value);
104
105 if (to_lower_case) {
106 result->SetI(std::tolower(char_value, c_locale));
107 } else {
108 result->SetI(std::toupper(char_value, c_locale));
109 }
110}
111
112void UnstartedRuntime::UnstartedCharacterToLowerCase(
113 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
114 CharacterLowerUpper(self, shadow_frame, result, arg_offset, true);
115}
116
117void UnstartedRuntime::UnstartedCharacterToUpperCase(
118 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
119 CharacterLowerUpper(self, shadow_frame, result, arg_offset, false);
120}
121
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700122// Helper function to deal with class loading in an unstarted runtime.
123static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
124 Handle<mirror::ClassLoader> class_loader, JValue* result,
125 const std::string& method_name, bool initialize_class,
126 bool abort_if_not_found)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700127 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampefa4333d2017-02-14 11:10:34 -0800128 CHECK(className != nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700129 std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
130 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
131
132 mirror::Class* found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
133 if (found == nullptr && abort_if_not_found) {
134 if (!self->IsExceptionPending()) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700135 AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
David Sehr709b0702016-10-13 09:12:37 -0700136 method_name.c_str(),
137 PrettyDescriptor(descriptor.c_str()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700138 }
139 return;
140 }
141 if (found != nullptr && initialize_class) {
142 StackHandleScope<1> hs(self);
143 Handle<mirror::Class> h_class(hs.NewHandle(found));
144 if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
145 CHECK(self->IsExceptionPending());
146 return;
147 }
148 }
149 result->SetL(found);
150}
151
152// Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
153// rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
154// ClassNotFoundException), so need to do the same. The only exception is if the exception is
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200155// actually the transaction abort exception. This must not be wrapped, as it signals an
156// initialization abort.
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700157static void CheckExceptionGenerateClassNotFound(Thread* self)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700158 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700159 if (self->IsExceptionPending()) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200160 // If it is not the transaction abort exception, wrap it.
David Sehr709b0702016-10-13 09:12:37 -0700161 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200162 if (type != Transaction::kAbortExceptionDescriptor) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700163 self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
164 "ClassNotFoundException");
165 }
166 }
167}
168
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700169static mirror::String* GetClassName(Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700170 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700171 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
172 if (param == nullptr) {
173 AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
174 return nullptr;
175 }
176 return param->AsString();
177}
178
David Brazdila02cb112018-01-31 11:36:39 +0000179template<typename T>
180static ALWAYS_INLINE bool ShouldBlockAccessToMember(T* member, ShadowFrame* frame)
181 REQUIRES_SHARED(Locks::mutator_lock_) {
182 return hiddenapi::ShouldBlockAccessToMember(
183 member->GetAccessFlags(), frame->GetMethod()->GetDeclaringClass());
184}
185
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800186void UnstartedRuntime::UnstartedClassForNameCommon(Thread* self,
187 ShadowFrame* shadow_frame,
188 JValue* result,
189 size_t arg_offset,
190 bool long_form,
191 const char* caller) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700192 mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
193 if (class_name == nullptr) {
194 return;
195 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800196 bool initialize_class;
197 mirror::ClassLoader* class_loader;
198 if (long_form) {
199 initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
200 class_loader = down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
201 } else {
202 initialize_class = true;
203 // TODO: This is really only correct for the boot classpath, and for robustness we should
204 // check the caller.
205 class_loader = nullptr;
206 }
207
208 ScopedObjectAccessUnchecked soa(self);
209 if (class_loader != nullptr && !ClassLinker::IsBootClassLoader(soa, class_loader)) {
210 AbortTransactionOrFail(self,
211 "Only the boot classloader is supported: %s",
212 mirror::Object::PrettyTypeOf(class_loader).c_str());
213 return;
214 }
215
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700216 StackHandleScope<1> hs(self);
217 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800218 UnstartedRuntimeFindClass(self,
219 h_class_name,
220 ScopedNullHandle<mirror::ClassLoader>(),
221 result,
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800222 caller,
223 initialize_class,
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800224 false);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700225 CheckExceptionGenerateClassNotFound(self);
226}
227
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800228void UnstartedRuntime::UnstartedClassForName(
229 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
230 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, false, "Class.forName");
231}
232
Andreas Gampe799681b2015-05-15 19:24:12 -0700233void UnstartedRuntime::UnstartedClassForNameLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700234 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800235 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.forName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700236}
237
Vladimir Marko7287c4d2018-02-15 10:41:07 +0000238void UnstartedRuntime::UnstartedClassGetPrimitiveClass(
239 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
240 ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
241 ObjPtr<mirror::Class> klass = mirror::Class::GetPrimitiveClass(class_name);
242 if (UNLIKELY(klass == nullptr)) {
243 DCHECK(self->IsExceptionPending());
244 AbortTransactionOrFail(self,
245 "Class.getPrimitiveClass() failed: %s",
246 self->GetException()->GetDetailMessage()->ToModifiedUtf8().c_str());
247 return;
248 }
249 result->SetL(klass);
250}
251
Andreas Gampe799681b2015-05-15 19:24:12 -0700252void UnstartedRuntime::UnstartedClassClassForName(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700253 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800254 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.classForName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700255}
256
Andreas Gampe799681b2015-05-15 19:24:12 -0700257void UnstartedRuntime::UnstartedClassNewInstance(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700258 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
259 StackHandleScope<2> hs(self); // Class, constructor, object.
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700260 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
261 if (param == nullptr) {
262 AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
263 return;
264 }
265 mirror::Class* klass = param->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700266 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700267
268 // Check that it's not null.
Andreas Gampefa4333d2017-02-14 11:10:34 -0800269 if (h_klass == nullptr) {
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700270 AbortTransactionOrFail(self, "Class reference is null for newInstance");
271 return;
272 }
273
274 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
275 if (Runtime::Current()->IsActiveTransaction()) {
276 if (h_klass.Get()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200277 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700278 h_klass->PrettyClass().c_str());
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700279 return;
280 }
281 }
282
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700283 // There are two situations in which we'll abort this run.
284 // 1) If the class isn't yet initialized and initialization fails.
285 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
286 // Note that 2) could likely be handled here, but for safety abort the transaction.
287 bool ok = false;
Mathieu Chartiere401d142015-04-22 13:56:20 -0700288 auto* cl = Runtime::Current()->GetClassLinker();
289 if (cl->EnsureInitialized(self, h_klass, true, true)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000290 ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
David Brazdila02cb112018-01-31 11:36:39 +0000291 if (cons != nullptr && ShouldBlockAccessToMember(cons, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000292 cons = nullptr;
293 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700294 if (cons != nullptr) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700295 Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800296 CHECK(h_obj != nullptr); // We don't expect OOM at compile-time.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700297 EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700298 if (!self->IsExceptionPending()) {
299 result->SetL(h_obj.Get());
300 ok = true;
301 }
302 } else {
303 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
304 "Could not find default constructor for '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700305 h_klass->PrettyClass().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700306 }
307 }
308 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700309 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
David Sehr709b0702016-10-13 09:12:37 -0700310 h_klass->PrettyClass().c_str(),
311 mirror::Object::PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700312 }
313}
314
Andreas Gampe799681b2015-05-15 19:24:12 -0700315void UnstartedRuntime::UnstartedClassGetDeclaredField(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700316 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700317 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
318 // going the reflective Dex way.
319 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
320 mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700321 ArtField* found = nullptr;
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700322 for (ArtField& field : klass->GetIFields()) {
323 if (name2->Equals(field.GetName())) {
324 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700325 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700326 }
327 }
328 if (found == nullptr) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700329 for (ArtField& field : klass->GetSFields()) {
330 if (name2->Equals(field.GetName())) {
331 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700332 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700333 }
334 }
335 }
David Brazdila02cb112018-01-31 11:36:39 +0000336 if (found != nullptr && ShouldBlockAccessToMember(found, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000337 found = nullptr;
338 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700339 if (found == nullptr) {
340 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
341 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
David Sehr709b0702016-10-13 09:12:37 -0700342 klass->PrettyDescriptor().c_str());
Andreas Gampe068b0c02015-03-11 12:44:47 -0700343 return;
344 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700345 Runtime* runtime = Runtime::Current();
Andreas Gampe542451c2016-07-26 09:02:02 -0700346 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Andreas Gampee01e3642016-07-25 13:06:04 -0700347 mirror::Field* field;
348 if (runtime->IsActiveTransaction()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700349 if (pointer_size == PointerSize::k64) {
350 field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
351 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700352 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700353 field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
354 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700355 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700356 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700357 if (pointer_size == PointerSize::k64) {
358 field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
359 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700360 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700361 field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
362 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700363 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700364 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700365 result->SetL(field);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700366}
367
Andreas Gampebc4d2182016-02-22 10:03:12 -0800368// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
369void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
370 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
371 // Special managed code cut-out to allow method lookup in a un-started runtime.
372 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
373 if (klass == nullptr) {
374 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
375 return;
376 }
377 mirror::String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
378 mirror::ObjectArray<mirror::Class>* args =
379 shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700380 Runtime* runtime = Runtime::Current();
381 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700382 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700383 ObjPtr<mirror::Method> method;
Andreas Gampee01e3642016-07-25 13:06:04 -0700384 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700385 if (pointer_size == PointerSize::k64) {
386 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
387 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700388 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700389 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
390 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700391 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800392 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700393 if (pointer_size == PointerSize::k64) {
394 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
395 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700396 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700397 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
398 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700399 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800400 }
David Brazdila02cb112018-01-31 11:36:39 +0000401 if (method != nullptr && ShouldBlockAccessToMember(method->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000402 method = nullptr;
403 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700404 result->SetL(method);
Andreas Gampebc4d2182016-02-22 10:03:12 -0800405}
406
Andreas Gampe6039e562016-04-05 18:18:43 -0700407// Special managed code cut-out to allow constructor lookup in a un-started runtime.
408void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
409 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
410 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
411 if (klass == nullptr) {
412 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
413 return;
414 }
415 mirror::ObjectArray<mirror::Class>* args =
416 shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700417 Runtime* runtime = Runtime::Current();
418 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700419 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700420 ObjPtr<mirror::Constructor> constructor;
Andreas Gampee01e3642016-07-25 13:06:04 -0700421 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700422 if (pointer_size == PointerSize::k64) {
423 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
424 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700425 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700426 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
427 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700428 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700429 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700430 if (pointer_size == PointerSize::k64) {
431 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
432 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700433 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700434 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
435 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700436 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700437 }
David Brazdil5a61bb72018-01-19 16:59:46 +0000438 if (constructor != nullptr &&
David Brazdila02cb112018-01-31 11:36:39 +0000439 ShouldBlockAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000440 constructor = nullptr;
441 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700442 result->SetL(constructor);
Andreas Gampe6039e562016-04-05 18:18:43 -0700443}
444
Andreas Gampeae78c262017-02-01 20:40:44 -0800445void UnstartedRuntime::UnstartedClassGetDeclaringClass(
446 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
447 StackHandleScope<1> hs(self);
448 Handle<mirror::Class> klass(hs.NewHandle(
449 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
450 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
451 result->SetL(nullptr);
452 return;
453 }
454 // Return null for anonymous classes.
455 JValue is_anon_result;
456 UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
457 if (is_anon_result.GetZ() != 0) {
458 result->SetL(nullptr);
459 return;
460 }
461 result->SetL(annotations::GetDeclaringClass(klass));
462}
463
Andreas Gampe633750c2016-02-19 10:49:50 -0800464void UnstartedRuntime::UnstartedClassGetEnclosingClass(
465 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
466 StackHandleScope<1> hs(self);
467 Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
468 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
469 result->SetL(nullptr);
470 }
David Sehr9323e6e2016-09-13 08:58:35 -0700471 result->SetL(annotations::GetEnclosingClass(klass));
Andreas Gampe633750c2016-02-19 10:49:50 -0800472}
473
Andreas Gampe715fdc22016-04-18 17:07:30 -0700474void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
475 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
476 StackHandleScope<1> hs(self);
477 Handle<mirror::Class> klass(hs.NewHandle(
478 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
479 const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
480 result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
481}
482
Andreas Gampe9486a162017-02-16 15:17:47 -0800483void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
484 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
485 StackHandleScope<1> hs(self);
486 Handle<mirror::Class> klass(hs.NewHandle(
487 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
488
489 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
490 result->SetL(nullptr);
491 return;
492 }
493
494 result->SetL(annotations::GetSignatureAnnotationForClass(klass));
495}
496
Andreas Gampeae78c262017-02-01 20:40:44 -0800497void UnstartedRuntime::UnstartedClassIsAnonymousClass(
498 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
499 StackHandleScope<1> hs(self);
500 Handle<mirror::Class> klass(hs.NewHandle(
501 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
502 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
503 result->SetZ(false);
504 return;
505 }
506 mirror::String* class_name = nullptr;
507 if (!annotations::GetInnerClass(klass, &class_name)) {
508 result->SetZ(false);
509 return;
510 }
511 result->SetZ(class_name == nullptr);
512}
513
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700514static std::unique_ptr<MemMap> FindAndExtractEntry(const std::string& jar_file,
515 const char* entry_name,
516 size_t* size,
517 std::string* error_msg) {
518 CHECK(size != nullptr);
519
520 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
521 if (zip_archive == nullptr) {
Mathieu Chartier6beced42016-11-15 15:51:31 -0800522 return nullptr;
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700523 }
524 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
525 if (zip_entry == nullptr) {
526 return nullptr;
527 }
528 std::unique_ptr<MemMap> tmp_map(
529 zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg));
530 if (tmp_map == nullptr) {
531 return nullptr;
532 }
533
534 // OK, from here everything seems fine.
535 *size = zip_entry->GetUncompressedLength();
536 return tmp_map;
537}
538
539static void GetResourceAsStream(Thread* self,
540 ShadowFrame* shadow_frame,
541 JValue* result,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700542 size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700543 mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
544 if (resource_obj == nullptr) {
545 AbortTransactionOrFail(self, "null name for getResourceAsStream");
546 return;
547 }
548 CHECK(resource_obj->IsString());
549 mirror::String* resource_name = resource_obj->AsString();
550
551 std::string resource_name_str = resource_name->ToModifiedUtf8();
552 if (resource_name_str.empty() || resource_name_str == "/") {
553 AbortTransactionOrFail(self,
554 "Unsupported name %s for getResourceAsStream",
555 resource_name_str.c_str());
556 return;
557 }
558 const char* resource_cstr = resource_name_str.c_str();
559 if (resource_cstr[0] == '/') {
560 resource_cstr++;
561 }
562
563 Runtime* runtime = Runtime::Current();
564
565 std::vector<std::string> split;
566 Split(runtime->GetBootClassPathString(), ':', &split);
567 if (split.empty()) {
568 AbortTransactionOrFail(self,
569 "Boot classpath not set or split error:: %s",
570 runtime->GetBootClassPathString().c_str());
571 return;
572 }
573
574 std::unique_ptr<MemMap> mem_map;
575 size_t map_size;
576 std::string last_error_msg; // Only store the last message (we could concatenate).
577
578 for (const std::string& jar_file : split) {
579 mem_map = FindAndExtractEntry(jar_file, resource_cstr, &map_size, &last_error_msg);
580 if (mem_map != nullptr) {
581 break;
582 }
583 }
584
585 if (mem_map == nullptr) {
586 // Didn't find it. There's a good chance this will be the same at runtime, but still
587 // conservatively abort the transaction here.
588 AbortTransactionOrFail(self,
589 "Could not find resource %s. Last error was %s.",
590 resource_name_str.c_str(),
591 last_error_msg.c_str());
592 return;
593 }
594
595 StackHandleScope<3> hs(self);
596
597 // Create byte array for content.
598 Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800599 if (h_array == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700600 AbortTransactionOrFail(self, "Could not find/create byte array class");
601 return;
602 }
603 // Copy in content.
604 memcpy(h_array->GetData(), mem_map->Begin(), map_size);
605 // Be proactive releasing memory.
Andreas Gampeeac4f282017-04-26 21:07:04 -0700606 mem_map.reset();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700607
608 // Create a ByteArrayInputStream.
609 Handle<mirror::Class> h_class(hs.NewHandle(
610 runtime->GetClassLinker()->FindClass(self,
611 "Ljava/io/ByteArrayInputStream;",
612 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800613 if (h_class == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700614 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
615 return;
616 }
617 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
618 AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
619 return;
620 }
621
622 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800623 if (h_obj == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700624 AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
625 return;
626 }
627
628 auto* cl = Runtime::Current()->GetClassLinker();
Vladimir Markoba118822017-06-12 15:41:56 +0100629 ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700630 if (constructor == nullptr) {
631 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
632 return;
633 }
634
635 uint32_t args[1];
636 args[0] = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_array.Get()));
637 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
638
639 if (self->IsExceptionPending()) {
640 AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
641 return;
642 }
643
644 result->SetL(h_obj.Get());
645}
646
647void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
648 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
649 {
650 mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
651 CHECK(this_obj != nullptr);
652 CHECK(this_obj->IsClassLoader());
653
654 StackHandleScope<1> hs(self);
655 Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
656
657 if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
658 this_classloader_class.Get()) {
659 AbortTransactionOrFail(self,
David Sehr709b0702016-10-13 09:12:37 -0700660 "Unsupported classloader type %s for getResourceAsStream",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700661 mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700662 return;
663 }
664 }
665
666 GetResourceAsStream(self, shadow_frame, result, arg_offset);
667}
668
Andreas Gampe85bef7e2017-02-16 18:13:26 -0800669void UnstartedRuntime::UnstartedConstructorNewInstance0(
670 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
671 // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
672 StackHandleScope<4> hs(self);
673 Handle<mirror::Constructor> m = hs.NewHandle(
674 reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
675 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
676 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
677 shadow_frame->GetVRegReference(arg_offset + 1)));
678 Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
679 if (UNLIKELY(c->IsAbstract())) {
680 AbortTransactionOrFail(self, "Cannot handle abstract classes");
681 return;
682 }
683 // Verify that we can access the class.
684 if (!m->IsAccessible() && !c->IsPublic()) {
685 // Go 2 frames back, this method is always called from newInstance0, which is called from
686 // Constructor.newInstance(Object... args).
687 ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
688 // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
689 // access checks anyways. TODO: Investigate if this the correct behavior.
690 if (caller != nullptr && !caller->CanAccess(c.Get())) {
691 AbortTransactionOrFail(self, "Cannot access class");
692 return;
693 }
694 }
695 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
696 DCHECK(self->IsExceptionPending());
697 return;
698 }
699 if (c->IsClassClass()) {
700 AbortTransactionOrFail(self, "new Class() is not supported");
701 return;
702 }
703
704 // String constructor is replaced by a StringFactory method in InvokeMethod.
705 if (c->IsStringClass()) {
706 // We don't support strings.
707 AbortTransactionOrFail(self, "String construction is not supported");
708 return;
709 }
710
711 Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
712 if (receiver == nullptr) {
713 AbortTransactionOrFail(self, "Could not allocate");
714 return;
715 }
716
717 // It's easier to use reflection to make the call, than create the uint32_t array.
718 {
719 ScopedObjectAccessUnchecked soa(self);
720 ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
721 soa.AddLocalReference<jobject>(m.Get()));
722 ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
723 soa.AddLocalReference<jobject>(receiver.Get()));
724 ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
725 soa.AddLocalReference<jobject>(args.Get()));
726 InvokeMethod(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
727 }
728 if (self->IsExceptionPending()) {
729 AbortTransactionOrFail(self, "Failed running constructor");
730 } else {
731 result->SetL(receiver.Get());
732 }
733}
734
Andreas Gampe799681b2015-05-15 19:24:12 -0700735void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700736 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700737 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
738 mirror::ClassLoader* class_loader =
739 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
740 StackHandleScope<2> hs(self);
741 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
742 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
743 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
744 "VMClassLoader.findLoadedClass", false, false);
745 // This might have an error pending. But semantics are to just return null.
746 if (self->IsExceptionPending()) {
747 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
David Sehr709b0702016-10-13 09:12:37 -0700748 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700749 if (type != "java.lang.InternalError") {
750 self->ClearException();
751 }
752 }
753}
754
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700755// Arraycopy emulation.
756// Note: we can't use any fast copy functions, as they are not available under transaction.
757
758template <typename T>
759static void PrimitiveArrayCopy(Thread* self,
760 mirror::Array* src_array, int32_t src_pos,
761 mirror::Array* dst_array, int32_t dst_pos,
762 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700763 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700764 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700765 AbortTransactionOrFail(self,
766 "Types mismatched in arraycopy: %s vs %s.",
767 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700768 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700769 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700770 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700771 return;
772 }
773 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
774 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
775 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
776 if (copy_forward) {
777 for (int32_t i = 0; i < length; ++i) {
778 dst->Set(dst_pos + i, src->Get(src_pos + i));
779 }
780 } else {
781 for (int32_t i = 1; i <= length; ++i) {
782 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
783 }
784 }
785}
786
Andreas Gampe799681b2015-05-15 19:24:12 -0700787void UnstartedRuntime::UnstartedSystemArraycopy(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700788 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700789 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700790 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
791 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700792 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700793
Andreas Gampe85a098a2016-03-31 13:30:53 -0700794 mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
795 mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
796 // Null checking. For simplicity, abort transaction.
797 if (src_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700798 AbortTransactionOrFail(self, "src is null in arraycopy.");
799 return;
800 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700801 if (dst_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700802 AbortTransactionOrFail(self, "dst is null in arraycopy.");
803 return;
804 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700805 // Test for arrayness. Throw ArrayStoreException.
806 if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
807 self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
808 return;
809 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700810
Andreas Gampe85a098a2016-03-31 13:30:53 -0700811 mirror::Array* src_array = src_obj->AsArray();
812 mirror::Array* dst_array = dst_obj->AsArray();
813
814 // Bounds checking. Throw IndexOutOfBoundsException.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700815 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
816 UNLIKELY(src_pos > src_array->GetLength() - length) ||
817 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700818 self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700819 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
820 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
821 length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700822 return;
823 }
824
825 // Type checking.
826 mirror::Class* src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
827 GetComponentType();
828
829 if (!src_type->IsPrimitive()) {
830 // Check that the second type is not primitive.
831 mirror::Class* trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
832 GetComponentType();
833 if (trg_type->IsPrimitiveInt()) {
834 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700835 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700836 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700837 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700838 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700839 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700840 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700841
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700842 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
843 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
844 if (src == dst) {
845 // Can overlap, but not have type mismatches.
Andreas Gampe85a098a2016-03-31 13:30:53 -0700846 // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700847 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
848 if (copy_forward) {
849 for (int32_t i = 0; i < length; ++i) {
850 dst->Set(dst_pos + i, src->Get(src_pos + i));
851 }
852 } else {
853 for (int32_t i = 1; i <= length; ++i) {
854 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
855 }
856 }
857 } else {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700858 // We're being lazy here. Optimally this could be a memcpy (if component types are
859 // assignable), but the ObjectArray implementation doesn't support transactions. The
860 // checking version, however, does.
861 if (Runtime::Current()->IsActiveTransaction()) {
862 dst->AssignableCheckingMemcpy<true>(
863 dst_pos, src, src_pos, length, true /* throw_exception */);
864 } else {
865 dst->AssignableCheckingMemcpy<false>(
866 dst_pos, src, src_pos, length, true /* throw_exception */);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700867 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700868 }
Andreas Gampe5c9af612016-04-05 14:16:10 -0700869 } else if (src_type->IsPrimitiveByte()) {
870 PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700871 } else if (src_type->IsPrimitiveChar()) {
872 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
873 } else if (src_type->IsPrimitiveInt()) {
874 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700875 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700876 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700877 src_type->PrettyDescriptor().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700878 }
879}
880
Andreas Gampe5c9af612016-04-05 14:16:10 -0700881void UnstartedRuntime::UnstartedSystemArraycopyByte(
882 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
883 // Just forward.
884 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
885}
886
Andreas Gampe799681b2015-05-15 19:24:12 -0700887void UnstartedRuntime::UnstartedSystemArraycopyChar(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700888 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700889 // Just forward.
890 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
891}
892
893void UnstartedRuntime::UnstartedSystemArraycopyInt(
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
Narayan Kamath34a316f2016-03-30 13:11:18 +0100899void UnstartedRuntime::UnstartedSystemGetSecurityManager(
900 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
901 JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
902 result->SetL(nullptr);
903}
904
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700905static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
906
907static void GetSystemProperty(Thread* self,
908 ShadowFrame* shadow_frame,
909 JValue* result,
910 size_t arg_offset,
911 bool is_default_version)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700912 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700913 StackHandleScope<4> hs(self);
914 Handle<mirror::String> h_key(
915 hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800916 if (h_key == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700917 AbortTransactionOrFail(self, "getProperty key was null");
918 return;
919 }
920
921 // This is overall inefficient, but reflecting the values here is not great, either. So
922 // for simplicity, and with the assumption that the number of getProperty calls is not
923 // too great, just iterate each time.
924
925 // Get the storage class.
926 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
927 Handle<mirror::Class> h_props_class(hs.NewHandle(
928 class_linker->FindClass(self,
929 "Ljava/lang/AndroidHardcodedSystemProperties;",
930 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800931 if (h_props_class == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700932 AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
933 return;
934 }
935 if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
936 AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
937 return;
938 }
939
940 // Get the storage array.
941 ArtField* static_properties =
942 h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
943 "[[Ljava/lang/String;");
944 if (static_properties == nullptr) {
945 AbortTransactionOrFail(self,
946 "Could not find %s field",
947 kAndroidHardcodedSystemPropertiesFieldName);
948 return;
949 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700950 ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
951 Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
952 props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800953 if (h_2string_array == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700954 AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
955 return;
956 }
957
958 // Iterate over it.
959 const int32_t prop_count = h_2string_array->GetLength();
960 // Use the third handle as mutable.
961 MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
962 hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
963 for (int32_t i = 0; i < prop_count; ++i) {
964 h_string_array.Assign(h_2string_array->Get(i));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800965 if (h_string_array == nullptr ||
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700966 h_string_array->GetLength() != 2 ||
967 h_string_array->Get(0) == nullptr) {
968 AbortTransactionOrFail(self,
969 "Unexpected content of %s",
970 kAndroidHardcodedSystemPropertiesFieldName);
971 return;
972 }
973 if (h_key->Equals(h_string_array->Get(0))) {
974 // Found a value.
975 if (h_string_array->Get(1) == nullptr && is_default_version) {
976 // Null is being delegated to the default map, and then resolved to the given default value.
977 // As there's no default map, return the given value.
978 result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
979 } else {
980 result->SetL(h_string_array->Get(1));
981 }
982 return;
983 }
984 }
985
986 // Key is not supported.
987 AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
988}
989
990void UnstartedRuntime::UnstartedSystemGetProperty(
991 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
992 GetSystemProperty(self, shadow_frame, result, arg_offset, false);
993}
994
995void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
996 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
997 GetSystemProperty(self, shadow_frame, result, arg_offset, true);
998}
999
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001000static std::string GetImmediateCaller(ShadowFrame* shadow_frame)
1001 REQUIRES_SHARED(Locks::mutator_lock_) {
1002 if (shadow_frame->GetLink() == nullptr) {
1003 return "<no caller>";
1004 }
1005 return ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1006}
1007
1008static bool CheckCallers(ShadowFrame* shadow_frame,
1009 std::initializer_list<std::string> allowed_call_stack)
1010 REQUIRES_SHARED(Locks::mutator_lock_) {
1011 for (const std::string& allowed_caller : allowed_call_stack) {
1012 if (shadow_frame->GetLink() == nullptr) {
1013 return false;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001014 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001015
1016 std::string found_caller = ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1017 if (allowed_caller != found_caller) {
1018 return false;
1019 }
1020
1021 shadow_frame = shadow_frame->GetLink();
1022 }
1023 return true;
1024}
1025
1026static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_descriptor)
1027 REQUIRES_SHARED(Locks::mutator_lock_) {
1028 // Find the requested class.
1029 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1030 ObjPtr<mirror::Class> klass =
1031 class_linker->FindClass(self, class_descriptor, ScopedNullHandle<mirror::ClassLoader>());
1032 if (klass == nullptr) {
1033 AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
1034 return nullptr;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001035 }
1036
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001037 StackHandleScope<2> hs(self);
1038 Handle<mirror::Class> h_class(hs.NewHandle(klass));
1039 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001040 if (h_obj != nullptr) {
Vladimir Markoba118822017-06-12 15:41:56 +01001041 ArtMethod* init_method = h_class->FindConstructor("()V", class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001042 if (init_method == nullptr) {
1043 AbortTransactionOrFail(self, "Could not find <init> for %s", class_descriptor);
1044 return nullptr;
1045 } else {
1046 JValue invoke_result;
1047 EnterInterpreterFromInvoke(self, init_method, h_obj.Get(), nullptr, nullptr);
1048 if (!self->IsExceptionPending()) {
1049 return h_obj.Get();
1050 }
1051 AbortTransactionOrFail(self, "Could not run <init> for %s", class_descriptor);
1052 }
1053 }
1054 AbortTransactionOrFail(self, "Could not allocate instance of %s", class_descriptor);
1055 return nullptr;
1056}
1057
1058void UnstartedRuntime::UnstartedThreadLocalGet(
1059 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1060 if (CheckCallers(shadow_frame, { "sun.misc.FloatingDecimal$BinaryToASCIIBuffer "
1061 "sun.misc.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1062 result->SetL(CreateInstanceOf(self, "Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;"));
1063 } else {
1064 AbortTransactionOrFail(self,
1065 "ThreadLocal.get() does not support %s",
1066 GetImmediateCaller(shadow_frame).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001067 }
1068}
1069
Andreas Gampebad529d2017-02-13 18:52:10 -08001070void UnstartedRuntime::UnstartedThreadCurrentThread(
1071 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1072 if (CheckCallers(shadow_frame,
1073 { "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1074 "java.lang.String, long)",
1075 "void java.lang.Thread.<init>()",
1076 "void java.util.logging.LogManager$Cleaner.<init>("
1077 "java.util.logging.LogManager)" })) {
1078 // Whitelist LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
1079 // Thread constructor only asks for the current thread to set up defaults and add the
1080 // thread as unstarted to the ThreadGroup. A faked-up main thread peer is good enough for
1081 // these purposes.
1082 Runtime::Current()->InitThreadGroups(self);
1083 jobject main_peer =
1084 self->CreateCompileTimePeer(self->GetJniEnv(),
1085 "main",
1086 false,
1087 Runtime::Current()->GetMainThreadGroup());
1088 if (main_peer == nullptr) {
1089 AbortTransactionOrFail(self, "Failed allocating peer");
1090 return;
1091 }
1092
1093 result->SetL(self->DecodeJObject(main_peer));
1094 self->GetJniEnv()->DeleteLocalRef(main_peer);
1095 } else {
1096 AbortTransactionOrFail(self,
1097 "Thread.currentThread() does not support %s",
1098 GetImmediateCaller(shadow_frame).c_str());
1099 }
1100}
1101
1102void UnstartedRuntime::UnstartedThreadGetNativeState(
1103 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1104 if (CheckCallers(shadow_frame,
1105 { "java.lang.Thread$State java.lang.Thread.getState()",
1106 "java.lang.ThreadGroup java.lang.Thread.getThreadGroup()",
1107 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1108 "java.lang.String, long)",
1109 "void java.lang.Thread.<init>()",
1110 "void java.util.logging.LogManager$Cleaner.<init>("
1111 "java.util.logging.LogManager)" })) {
1112 // Whitelist reading the state of the "main" thread when creating another (unstarted) thread
1113 // for LogManager. Report the thread as "new" (it really only counts that it isn't terminated).
1114 constexpr int32_t kJavaRunnable = 1;
1115 result->SetI(kJavaRunnable);
1116 } else {
1117 AbortTransactionOrFail(self,
1118 "Thread.getNativeState() does not support %s",
1119 GetImmediateCaller(shadow_frame).c_str());
1120 }
1121}
1122
Sergio Giro83261202016-04-11 20:49:20 +01001123void UnstartedRuntime::UnstartedMathCeil(
1124 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001125 result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
Sergio Giro83261202016-04-11 20:49:20 +01001126}
1127
1128void UnstartedRuntime::UnstartedMathFloor(
1129 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001130 result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001131}
1132
Andreas Gampeb8a00f92016-04-18 20:51:13 -07001133void UnstartedRuntime::UnstartedMathSin(
1134 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1135 result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
1136}
1137
1138void UnstartedRuntime::UnstartedMathCos(
1139 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1140 result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
1141}
1142
1143void UnstartedRuntime::UnstartedMathPow(
1144 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1145 result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
1146 shadow_frame->GetVRegDouble(arg_offset + 2)));
1147}
1148
Andreas Gampe799681b2015-05-15 19:24:12 -07001149void UnstartedRuntime::UnstartedObjectHashCode(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001150 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001151 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1152 result->SetI(obj->IdentityHashCode());
1153}
1154
Andreas Gampe799681b2015-05-15 19:24:12 -07001155void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
Andreas Gampedd9d0552015-03-09 12:57:41 -07001156 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001157 double in = shadow_frame->GetVRegDouble(arg_offset);
Roland Levillainda4d79b2015-03-24 14:36:11 +00001158 result->SetJ(bit_cast<int64_t, double>(in));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001159}
1160
Andreas Gampedd9d0552015-03-09 12:57:41 -07001161static void UnstartedMemoryPeek(
1162 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1163 int64_t address = shadow_frame->GetVRegLong(arg_offset);
1164 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
1165 // aborting the transaction.
1166
1167 switch (type) {
1168 case Primitive::kPrimByte: {
1169 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
1170 return;
1171 }
1172
1173 case Primitive::kPrimShort: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001174 typedef int16_t unaligned_short __attribute__ ((aligned (1)));
1175 result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001176 return;
1177 }
1178
1179 case Primitive::kPrimInt: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001180 typedef int32_t unaligned_int __attribute__ ((aligned (1)));
1181 result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001182 return;
1183 }
1184
1185 case Primitive::kPrimLong: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001186 typedef int64_t unaligned_long __attribute__ ((aligned (1)));
1187 result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001188 return;
1189 }
1190
1191 case Primitive::kPrimBoolean:
1192 case Primitive::kPrimChar:
1193 case Primitive::kPrimFloat:
1194 case Primitive::kPrimDouble:
1195 case Primitive::kPrimVoid:
1196 case Primitive::kPrimNot:
1197 LOG(FATAL) << "Not in the Memory API: " << type;
1198 UNREACHABLE();
1199 }
1200 LOG(FATAL) << "Should not reach here";
1201 UNREACHABLE();
1202}
1203
Andreas Gampe799681b2015-05-15 19:24:12 -07001204void UnstartedRuntime::UnstartedMemoryPeekByte(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001205 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001206 UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
1207}
1208
1209void UnstartedRuntime::UnstartedMemoryPeekShort(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001210 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001211 UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
1212}
1213
1214void UnstartedRuntime::UnstartedMemoryPeekInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001215 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001216 UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
1217}
1218
1219void UnstartedRuntime::UnstartedMemoryPeekLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001220 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001221 UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001222}
1223
1224static void UnstartedMemoryPeekArray(
1225 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001226 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampedd9d0552015-03-09 12:57:41 -07001227 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1228 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1229 if (obj == nullptr) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001230 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
Andreas Gampedd9d0552015-03-09 12:57:41 -07001231 return;
1232 }
1233 mirror::Array* array = obj->AsArray();
1234
1235 int offset = shadow_frame->GetVReg(arg_offset + 3);
1236 int count = shadow_frame->GetVReg(arg_offset + 4);
1237 if (offset < 0 || offset + count > array->GetLength()) {
1238 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
1239 offset, count, array->GetLength()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001240 Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
Andreas Gampedd9d0552015-03-09 12:57:41 -07001241 return;
1242 }
1243
1244 switch (type) {
1245 case Primitive::kPrimByte: {
1246 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
1247 mirror::ByteArray* byte_array = array->AsByteArray();
1248 for (int32_t i = 0; i < count; ++i, ++address) {
1249 byte_array->SetWithoutChecks<true>(i + offset, *address);
1250 }
1251 return;
1252 }
1253
1254 case Primitive::kPrimShort:
1255 case Primitive::kPrimInt:
1256 case Primitive::kPrimLong:
1257 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1258 UNREACHABLE();
1259
1260 case Primitive::kPrimBoolean:
1261 case Primitive::kPrimChar:
1262 case Primitive::kPrimFloat:
1263 case Primitive::kPrimDouble:
1264 case Primitive::kPrimVoid:
1265 case Primitive::kPrimNot:
1266 LOG(FATAL) << "Not in the Memory API: " << type;
1267 UNREACHABLE();
1268 }
1269 LOG(FATAL) << "Should not reach here";
1270 UNREACHABLE();
1271}
1272
Andreas Gampe799681b2015-05-15 19:24:12 -07001273void UnstartedRuntime::UnstartedMemoryPeekByteArray(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001274 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001275 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001276}
1277
Kenny Root1c9e61c2015-05-14 15:58:17 -07001278// This allows reading the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001279void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001280 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001281 jint start = shadow_frame->GetVReg(arg_offset + 1);
1282 jint end = shadow_frame->GetVReg(arg_offset + 2);
1283 jint index = shadow_frame->GetVReg(arg_offset + 4);
1284 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1285 if (string == nullptr) {
1286 AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1287 return;
1288 }
Kenny Root57f91e82015-05-14 15:58:17 -07001289 DCHECK_GE(start, 0);
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001290 DCHECK_LE(start, end);
1291 DCHECK_LE(end, string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001292 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001293 Handle<mirror::CharArray> h_char_array(
1294 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001295 DCHECK_GE(index, 0);
Kenny Root57f91e82015-05-14 15:58:17 -07001296 DCHECK_LE(index, h_char_array->GetLength());
1297 DCHECK_LE(end - start, h_char_array->GetLength() - index);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001298 string->GetChars(start, end, h_char_array, index);
1299}
1300
1301// This allows reading chars from the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001302void UnstartedRuntime::UnstartedStringCharAt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001303 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001304 jint index = shadow_frame->GetVReg(arg_offset + 1);
1305 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1306 if (string == nullptr) {
1307 AbortTransactionOrFail(self, "String.charAt with null object");
1308 return;
1309 }
1310 result->SetC(string->CharAt(index));
1311}
1312
Vladimir Marko92907f32017-02-20 14:08:30 +00001313// This allows creating String objects with replaced characters during compilation.
1314// String.doReplace(char, char) is called from String.replace(char, char) when there is a match.
1315void UnstartedRuntime::UnstartedStringDoReplace(
1316 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1317 jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
1318 jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001319 StackHandleScope<1> hs(self);
1320 Handle<mirror::String> string =
1321 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
Kenny Root57f91e82015-05-14 15:58:17 -07001322 if (string == nullptr) {
Vladimir Marko92907f32017-02-20 14:08:30 +00001323 AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
Kenny Root57f91e82015-05-14 15:58:17 -07001324 return;
1325 }
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001326 result->SetL(mirror::String::DoReplace(self, string, old_c, new_c));
Kenny Root57f91e82015-05-14 15:58:17 -07001327}
1328
Kenny Root1c9e61c2015-05-14 15:58:17 -07001329// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001330void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001331 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001332 jint offset = shadow_frame->GetVReg(arg_offset);
1333 jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1334 DCHECK_GE(char_count, 0);
1335 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001336 Handle<mirror::CharArray> h_char_array(
1337 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
Kenny Root1c9e61c2015-05-14 15:58:17 -07001338 Runtime* runtime = Runtime::Current();
1339 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1340 result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator));
1341}
1342
1343// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001344void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001345 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root57f91e82015-05-14 15:58:17 -07001346 mirror::String* to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1347 if (to_copy == nullptr) {
1348 AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1349 return;
1350 }
1351 StackHandleScope<1> hs(self);
1352 Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1353 Runtime* runtime = Runtime::Current();
1354 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1355 result->SetL(mirror::String::AllocFromString<true>(self, h_string->GetLength(), h_string, 0,
1356 allocator));
1357}
1358
Andreas Gampe799681b2015-05-15 19:24:12 -07001359void UnstartedRuntime::UnstartedStringFastSubstring(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001360 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001361 jint start = shadow_frame->GetVReg(arg_offset + 1);
1362 jint length = shadow_frame->GetVReg(arg_offset + 2);
Kenny Root57f91e82015-05-14 15:58:17 -07001363 DCHECK_GE(start, 0);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001364 DCHECK_GE(length, 0);
1365 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001366 Handle<mirror::String> h_string(
1367 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
Kenny Root57f91e82015-05-14 15:58:17 -07001368 DCHECK_LE(start, h_string->GetLength());
1369 DCHECK_LE(start + length, h_string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001370 Runtime* runtime = Runtime::Current();
1371 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1372 result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator));
1373}
1374
Kenny Root57f91e82015-05-14 15:58:17 -07001375// This allows getting the char array for new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001376void UnstartedRuntime::UnstartedStringToCharArray(
Kenny Root57f91e82015-05-14 15:58:17 -07001377 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001378 REQUIRES_SHARED(Locks::mutator_lock_) {
Kenny Root57f91e82015-05-14 15:58:17 -07001379 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1380 if (string == nullptr) {
1381 AbortTransactionOrFail(self, "String.charAt with null object");
1382 return;
1383 }
1384 result->SetL(string->ToCharArray(self));
1385}
1386
Andreas Gampebc4d2182016-02-22 10:03:12 -08001387// This allows statically initializing ConcurrentHashMap and SynchronousQueue.
1388void UnstartedRuntime::UnstartedReferenceGetReferent(
1389 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001390 ObjPtr<mirror::Reference> const ref = down_cast<mirror::Reference*>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001391 shadow_frame->GetVRegReference(arg_offset));
1392 if (ref == nullptr) {
1393 AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1394 return;
1395 }
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001396 ObjPtr<mirror::Object> const referent =
Andreas Gampebc4d2182016-02-22 10:03:12 -08001397 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1398 result->SetL(referent);
1399}
1400
1401// This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1402// conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1403// where we can predict the behavior (somewhat).
1404// Note: this is required (instead of lazy initialization) as these classes are used in the static
1405// initialization of other classes, so will *use* the value.
1406void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1407 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001408 if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001409 // SynchronousQueue really only separates between single- and multiprocessor case. Return
1410 // 8 as a conservative upper approximation.
1411 result->SetI(8);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001412 } else if (CheckCallers(shadow_frame,
1413 { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001414 // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1415 // a good upper bound.
1416 // TODO: Consider resetting in the zygote?
1417 result->SetI(8);
1418 } else {
1419 // Not supported.
1420 AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1421 }
1422}
1423
1424// This allows accessing ConcurrentHashMap/SynchronousQueue.
1425
1426void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1427 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1428 // Argument 0 is the Unsafe instance, skip.
1429 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1430 if (obj == nullptr) {
1431 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1432 return;
1433 }
1434 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1435 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1436 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001437 bool success;
1438 // Check whether we're in a transaction, call accordingly.
1439 if (Runtime::Current()->IsActiveTransaction()) {
1440 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1441 expectedValue,
1442 newValue);
1443 } else {
1444 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1445 expectedValue,
1446 newValue);
1447 }
1448 result->SetZ(success ? 1 : 0);
1449}
1450
1451void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1452 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1453 // Argument 0 is the Unsafe instance, skip.
1454 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1455 if (obj == nullptr) {
1456 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1457 return;
1458 }
1459 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1460 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1461 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 5);
1462
1463 // Must use non transactional mode.
1464 if (kUseReadBarrier) {
1465 // Need to make sure the reference stored in the field is a to-space one before attempting the
1466 // CAS or the CAS could fail incorrectly.
1467 mirror::HeapReference<mirror::Object>* field_addr =
1468 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1469 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001470 ReadBarrier::Barrier<
1471 mirror::Object,
1472 /* kIsVolatile */ false,
1473 kWithReadBarrier,
1474 /* kAlwaysUpdateField */ true>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001475 obj,
1476 MemberOffset(offset),
1477 field_addr);
1478 }
1479 bool success;
1480 // Check whether we're in a transaction, call accordingly.
1481 if (Runtime::Current()->IsActiveTransaction()) {
1482 success = obj->CasFieldStrongSequentiallyConsistentObject<true>(MemberOffset(offset),
1483 expected_value,
1484 newValue);
1485 } else {
1486 success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
1487 expected_value,
1488 newValue);
1489 }
1490 result->SetZ(success ? 1 : 0);
1491}
1492
1493void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1494 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001495 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001496 // Argument 0 is the Unsafe instance, skip.
1497 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1498 if (obj == nullptr) {
1499 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1500 return;
1501 }
1502 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1503 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1504 result->SetL(value);
1505}
1506
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001507void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1508 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001509 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001510 // Argument 0 is the Unsafe instance, skip.
1511 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1512 if (obj == nullptr) {
1513 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1514 return;
1515 }
1516 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1517 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1518 if (Runtime::Current()->IsActiveTransaction()) {
1519 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1520 } else {
1521 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1522 }
1523}
1524
Andreas Gampebc4d2182016-02-22 10:03:12 -08001525void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1526 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001527 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001528 // Argument 0 is the Unsafe instance, skip.
1529 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1530 if (obj == nullptr) {
1531 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1532 return;
1533 }
1534 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1535 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 4);
1536 QuasiAtomic::ThreadFenceRelease();
1537 if (Runtime::Current()->IsActiveTransaction()) {
1538 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1539 } else {
1540 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1541 }
1542}
1543
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001544// A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1545// of correctly handling the corner cases.
1546void UnstartedRuntime::UnstartedIntegerParseInt(
1547 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001548 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001549 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1550 if (obj == nullptr) {
1551 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1552 return;
1553 }
1554
1555 std::string string_value = obj->AsString()->ToModifiedUtf8();
1556 if (string_value.empty()) {
1557 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1558 return;
1559 }
1560
1561 const char* c_str = string_value.c_str();
1562 char *end;
1563 // Can we set errno to 0? Is this always a variable, and not a macro?
1564 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1565 int64_t l = strtol(c_str, &end, 10);
1566
1567 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1568 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1569 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1570 return;
1571 }
1572 if (l == 0) {
1573 // Check whether the string wasn't exactly zero.
1574 if (string_value != "0") {
1575 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1576 return;
1577 }
1578 } else if (*end != '\0') {
1579 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1580 return;
1581 }
1582
1583 result->SetI(static_cast<int32_t>(l));
1584}
1585
1586// A cutout for Long.parseLong.
1587//
1588// Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1589// well.
1590void UnstartedRuntime::UnstartedLongParseLong(
1591 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001592 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001593 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1594 if (obj == nullptr) {
1595 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1596 return;
1597 }
1598
1599 std::string string_value = obj->AsString()->ToModifiedUtf8();
1600 if (string_value.empty()) {
1601 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1602 return;
1603 }
1604
1605 const char* c_str = string_value.c_str();
1606 char *end;
1607 // Can we set errno to 0? Is this always a variable, and not a macro?
1608 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1609 int64_t l = strtol(c_str, &end, 10);
1610
1611 // Note: comparing against int32_t min/max is intentional here.
1612 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1613 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1614 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1615 return;
1616 }
1617 if (l == 0) {
1618 // Check whether the string wasn't exactly zero.
1619 if (string_value != "0") {
1620 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1621 return;
1622 }
1623 } else if (*end != '\0') {
1624 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1625 return;
1626 }
1627
1628 result->SetJ(l);
1629}
1630
Andreas Gampe715fdc22016-04-18 17:07:30 -07001631void UnstartedRuntime::UnstartedMethodInvoke(
1632 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001633 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe715fdc22016-04-18 17:07:30 -07001634 JNIEnvExt* env = self->GetJniEnv();
1635 ScopedObjectAccessUnchecked soa(self);
1636
Mathieu Chartier8778c522016-10-04 19:06:30 -07001637 ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001638 ScopedLocalRef<jobject> java_method(env,
Roland Levillain5e8d5f02016-10-18 18:03:43 +01001639 java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001640
Mathieu Chartier8778c522016-10-04 19:06:30 -07001641 ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001642 ScopedLocalRef<jobject> java_receiver(env,
1643 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1644
Mathieu Chartier8778c522016-10-04 19:06:30 -07001645 ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001646 ScopedLocalRef<jobject> java_args(env,
1647 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1648
1649 ScopedLocalRef<jobject> result_jobj(env,
1650 InvokeMethod(soa, java_method.get(), java_receiver.get(), java_args.get()));
1651
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001652 result->SetL(self->DecodeJObject(result_jobj.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001653
1654 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1655 // InvocationTargetExceptions.
1656 if (self->IsExceptionPending()) {
1657 AbortTransactionOrFail(self, "Failed Method.invoke");
1658 }
1659}
1660
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001661void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1662 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1663 REQUIRES_SHARED(Locks::mutator_lock_) {
1664 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1665 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1666}
Andreas Gampebc4d2182016-02-22 10:03:12 -08001667
Orion Hodson43f0cdb2017-10-10 14:47:32 +01001668// Checks whether the runtime is s64-bit. This is needed for the clinit of
1669// java.lang.invoke.VarHandle clinit. The clinit determines sets of
1670// available VarHandle accessors and these differ based on machine
1671// word size.
1672void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1673 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1674 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1675 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1676 jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1677 result->SetZ(is64bit);
1678}
1679
Mathieu Chartiere401d142015-04-22 13:56:20 -07001680void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
1681 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1682 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001683 int32_t length = args[1];
1684 DCHECK_GE(length, 0);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001685 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001686 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001687 ObjPtr<mirror::Class> array_class =
1688 runtime->GetClassLinker()->FindArrayClass(self, &element_class);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001689 DCHECK(array_class != nullptr);
1690 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001691 result->SetL(mirror::Array::Alloc<true, true>(self,
1692 array_class,
1693 length,
1694 array_class->GetComponentSizeShift(),
1695 allocator));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001696}
1697
Mathieu Chartiere401d142015-04-22 13:56:20 -07001698void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1699 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1700 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001701 result->SetL(nullptr);
1702}
1703
Mathieu Chartiere401d142015-04-22 13:56:20 -07001704void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1705 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1706 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001707 NthCallerVisitor visitor(self, 3);
1708 visitor.WalkStack();
1709 if (visitor.caller != nullptr) {
1710 result->SetL(visitor.caller->GetDeclaringClass());
1711 }
1712}
1713
Mathieu Chartiere401d142015-04-22 13:56:20 -07001714void UnstartedRuntime::UnstartedJNIMathLog(
1715 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1716 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001717 JValue value;
1718 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1719 result->SetD(log(value.GetD()));
1720}
1721
Mathieu Chartiere401d142015-04-22 13:56:20 -07001722void UnstartedRuntime::UnstartedJNIMathExp(
1723 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1724 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001725 JValue value;
1726 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1727 result->SetD(exp(value.GetD()));
1728}
1729
Andreas Gampebc4d2182016-02-22 10:03:12 -08001730void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1731 Thread* self ATTRIBUTE_UNUSED,
1732 ArtMethod* method ATTRIBUTE_UNUSED,
1733 mirror::Object* receiver ATTRIBUTE_UNUSED,
1734 uint32_t* args ATTRIBUTE_UNUSED,
1735 JValue* result) {
1736 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1737 ? 0
1738 : 1);
1739}
1740
Mathieu Chartiere401d142015-04-22 13:56:20 -07001741void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1742 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1743 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001744 StackHandleScope<1> hs(self);
1745 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1746}
1747
Andreas Gampebc4d2182016-02-22 10:03:12 -08001748void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1749 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1750 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1751 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1752 result->SetD(bit_cast<double>(long_input));
1753}
1754
Mathieu Chartiere401d142015-04-22 13:56:20 -07001755void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1756 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1757 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001758 result->SetI(args[0]);
1759}
1760
Mathieu Chartiere401d142015-04-22 13:56:20 -07001761void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
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::UnstartedJNIObjectInternalClone(
1768 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1769 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001770 result->SetL(receiver->Clone(self));
1771}
1772
Mathieu Chartiere401d142015-04-22 13:56:20 -07001773void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1774 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1775 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001776 receiver->NotifyAll(self);
1777}
1778
Mathieu Chartiere401d142015-04-22 13:56:20 -07001779void UnstartedRuntime::UnstartedJNIStringCompareTo(
1780 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver, uint32_t* args,
1781 JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001782 mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
1783 if (rhs == nullptr) {
Andreas Gampe068b0c02015-03-11 12:44:47 -07001784 AbortTransactionOrFail(self, "String.compareTo with null object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001785 }
1786 result->SetI(receiver->AsString()->CompareTo(rhs));
1787}
1788
Mathieu Chartiere401d142015-04-22 13:56:20 -07001789void UnstartedRuntime::UnstartedJNIStringIntern(
1790 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1791 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001792 result->SetL(receiver->AsString()->Intern());
1793}
1794
Mathieu Chartiere401d142015-04-22 13:56:20 -07001795void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1796 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1797 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001798 StackHandleScope<2> hs(self);
1799 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1800 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1801 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1802}
1803
Mathieu Chartiere401d142015-04-22 13:56:20 -07001804void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1805 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1806 uint32_t* args, JValue* result) {
Andreas Gampee598e042015-04-10 14:57:10 -07001807 int32_t length = static_cast<int32_t>(args[1]);
1808 if (length < 0) {
1809 ThrowNegativeArraySizeException(length);
1810 return;
1811 }
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001812 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
Andreas Gampee598e042015-04-10 14:57:10 -07001813 Runtime* runtime = Runtime::Current();
1814 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001815 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, &element_class);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001816 if (UNLIKELY(array_class == nullptr)) {
Andreas Gampee598e042015-04-10 14:57:10 -07001817 CHECK(self->IsExceptionPending());
1818 return;
1819 }
1820 DCHECK(array_class->IsObjectArrayClass());
1821 mirror::Array* new_array = mirror::ObjectArray<mirror::Object*>::Alloc(
1822 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1823 result->SetL(new_array);
1824}
1825
Mathieu Chartiere401d142015-04-22 13:56:20 -07001826void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1827 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1828 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001829 ScopedObjectAccessUnchecked soa(self);
1830 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001831 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<true>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001832 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001833 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<false>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001834 }
1835}
1836
Mathieu Chartiere401d142015-04-22 13:56:20 -07001837void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
1838 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1839 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001840 result->SetZ(JNI_TRUE);
1841}
1842
Mathieu Chartiere401d142015-04-22 13:56:20 -07001843void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
1844 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1845 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001846 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1847 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1848 jint expectedValue = args[3];
1849 jint newValue = args[4];
1850 bool success;
1851 if (Runtime::Current()->IsActiveTransaction()) {
1852 success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
1853 expectedValue, newValue);
1854 } else {
1855 success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
1856 expectedValue, newValue);
1857 }
1858 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1859}
1860
Narayan Kamath34a316f2016-03-30 13:11:18 +01001861void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(
1862 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1863 uint32_t* args, JValue* result) {
1864 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1865 if (obj == nullptr) {
1866 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1867 return;
1868 }
1869
1870 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1871 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1872}
1873
Mathieu Chartiere401d142015-04-22 13:56:20 -07001874void UnstartedRuntime::UnstartedJNIUnsafePutObject(
1875 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1876 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001877 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1878 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1879 mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
1880 if (Runtime::Current()->IsActiveTransaction()) {
1881 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1882 } else {
1883 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1884 }
1885}
1886
Andreas Gampe799681b2015-05-15 19:24:12 -07001887void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001888 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1889 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001890 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1891 Primitive::Type primitive_type = component->GetPrimitiveType();
1892 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1893}
1894
Andreas Gampe799681b2015-05-15 19:24:12 -07001895void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001896 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1897 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001898 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1899 Primitive::Type primitive_type = component->GetPrimitiveType();
1900 result->SetI(Primitive::ComponentSize(primitive_type));
1901}
1902
Andreas Gampedd9d0552015-03-09 12:57:41 -07001903typedef void (*InvokeHandler)(Thread* self, ShadowFrame* shadow_frame, JValue* result,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001904 size_t arg_size);
1905
Mathieu Chartiere401d142015-04-22 13:56:20 -07001906typedef void (*JNIHandler)(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001907 uint32_t* args, JValue* result);
1908
1909static bool tables_initialized_ = false;
1910static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
1911static std::unordered_map<std::string, JNIHandler> jni_handlers_;
1912
Andreas Gampe799681b2015-05-15 19:24:12 -07001913void UnstartedRuntime::InitializeInvokeHandlers() {
1914#define UNSTARTED_DIRECT(ShortName, Sig) \
1915 invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
1916#include "unstarted_runtime_list.h"
1917 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
1918#undef UNSTARTED_RUNTIME_DIRECT_LIST
1919#undef UNSTARTED_RUNTIME_JNI_LIST
1920#undef UNSTARTED_DIRECT
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001921}
1922
Andreas Gampe799681b2015-05-15 19:24:12 -07001923void UnstartedRuntime::InitializeJNIHandlers() {
1924#define UNSTARTED_JNI(ShortName, Sig) \
1925 jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
1926#include "unstarted_runtime_list.h"
1927 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
1928#undef UNSTARTED_RUNTIME_DIRECT_LIST
1929#undef UNSTARTED_RUNTIME_JNI_LIST
1930#undef UNSTARTED_JNI
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001931}
1932
Andreas Gampe799681b2015-05-15 19:24:12 -07001933void UnstartedRuntime::Initialize() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001934 CHECK(!tables_initialized_);
1935
Andreas Gampe799681b2015-05-15 19:24:12 -07001936 InitializeInvokeHandlers();
1937 InitializeJNIHandlers();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001938
1939 tables_initialized_ = true;
1940}
1941
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001942void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
Andreas Gampe799681b2015-05-15 19:24:12 -07001943 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001944 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
1945 // problems in core libraries.
1946 CHECK(tables_initialized_);
1947
David Sehr709b0702016-10-13 09:12:37 -07001948 std::string name(ArtMethod::PrettyMethod(shadow_frame->GetMethod()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001949 const auto& iter = invoke_handlers_.find(name);
1950 if (iter != invoke_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001951 // Clear out the result in case it's not zeroed out.
1952 result->SetL(0);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001953
1954 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
1955 self->PushShadowFrame(shadow_frame);
1956
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001957 (*iter->second)(self, shadow_frame, result, arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001958
1959 self->PopShadowFrame();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001960 } else {
1961 // Not special, continue with regular interpreter execution.
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001962 ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001963 }
1964}
1965
1966// 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 -07001967void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe799681b2015-05-15 19:24:12 -07001968 uint32_t* args, JValue* result) {
David Sehr709b0702016-10-13 09:12:37 -07001969 std::string name(ArtMethod::PrettyMethod(method));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001970 const auto& iter = jni_handlers_.find(name);
1971 if (iter != jni_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001972 // Clear out the result in case it's not zeroed out.
1973 result->SetL(0);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001974 (*iter->second)(self, method, receiver, args, result);
1975 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02001976 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
1977 name.c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001978 } else {
David Sehr709b0702016-10-13 09:12:37 -07001979 LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001980 "non-transactional runtime";
1981 }
1982}
1983
1984} // namespace interpreter
1985} // namespace art