blob: b9b00519d1884760b38d2d0682c6ba55a8751dc8 [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
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800179void UnstartedRuntime::UnstartedClassForNameCommon(Thread* self,
180 ShadowFrame* shadow_frame,
181 JValue* result,
182 size_t arg_offset,
183 bool long_form,
184 const char* caller) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700185 mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
186 if (class_name == nullptr) {
187 return;
188 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800189 bool initialize_class;
190 mirror::ClassLoader* class_loader;
191 if (long_form) {
192 initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
193 class_loader = down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
194 } else {
195 initialize_class = true;
196 // TODO: This is really only correct for the boot classpath, and for robustness we should
197 // check the caller.
198 class_loader = nullptr;
199 }
200
201 ScopedObjectAccessUnchecked soa(self);
202 if (class_loader != nullptr && !ClassLinker::IsBootClassLoader(soa, class_loader)) {
203 AbortTransactionOrFail(self,
204 "Only the boot classloader is supported: %s",
205 mirror::Object::PrettyTypeOf(class_loader).c_str());
206 return;
207 }
208
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700209 StackHandleScope<1> hs(self);
210 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800211 UnstartedRuntimeFindClass(self,
212 h_class_name,
213 ScopedNullHandle<mirror::ClassLoader>(),
214 result,
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800215 caller,
216 initialize_class,
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800217 false);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700218 CheckExceptionGenerateClassNotFound(self);
219}
220
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800221void UnstartedRuntime::UnstartedClassForName(
222 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
223 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, false, "Class.forName");
224}
225
Andreas Gampe799681b2015-05-15 19:24:12 -0700226void UnstartedRuntime::UnstartedClassForNameLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700227 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800228 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.forName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700229}
230
Andreas Gampe799681b2015-05-15 19:24:12 -0700231void UnstartedRuntime::UnstartedClassClassForName(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700232 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800233 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.classForName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700234}
235
Andreas Gampe799681b2015-05-15 19:24:12 -0700236void UnstartedRuntime::UnstartedClassNewInstance(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700237 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
238 StackHandleScope<2> hs(self); // Class, constructor, object.
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700239 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
240 if (param == nullptr) {
241 AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
242 return;
243 }
244 mirror::Class* klass = param->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700245 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700246
247 // Check that it's not null.
Andreas Gampefa4333d2017-02-14 11:10:34 -0800248 if (h_klass == nullptr) {
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700249 AbortTransactionOrFail(self, "Class reference is null for newInstance");
250 return;
251 }
252
253 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
254 if (Runtime::Current()->IsActiveTransaction()) {
255 if (h_klass.Get()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200256 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700257 h_klass->PrettyClass().c_str());
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700258 return;
259 }
260 }
261
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700262 // There are two situations in which we'll abort this run.
263 // 1) If the class isn't yet initialized and initialization fails.
264 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
265 // Note that 2) could likely be handled here, but for safety abort the transaction.
266 bool ok = false;
Mathieu Chartiere401d142015-04-22 13:56:20 -0700267 auto* cl = Runtime::Current()->GetClassLinker();
268 if (cl->EnsureInitialized(self, h_klass, true, true)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000269 ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
270 if (cons != nullptr &&
271 hiddenapi::ShouldBlockAccessToMember(cons, shadow_frame->GetMethod())) {
272 cons = nullptr;
273 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700274 if (cons != nullptr) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700275 Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800276 CHECK(h_obj != nullptr); // We don't expect OOM at compile-time.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700277 EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700278 if (!self->IsExceptionPending()) {
279 result->SetL(h_obj.Get());
280 ok = true;
281 }
282 } else {
283 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
284 "Could not find default constructor for '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700285 h_klass->PrettyClass().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700286 }
287 }
288 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700289 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
David Sehr709b0702016-10-13 09:12:37 -0700290 h_klass->PrettyClass().c_str(),
291 mirror::Object::PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700292 }
293}
294
Andreas Gampe799681b2015-05-15 19:24:12 -0700295void UnstartedRuntime::UnstartedClassGetDeclaredField(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700296 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700297 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
298 // going the reflective Dex way.
299 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
300 mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700301 ArtField* found = nullptr;
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700302 for (ArtField& field : klass->GetIFields()) {
303 if (name2->Equals(field.GetName())) {
304 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700305 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700306 }
307 }
308 if (found == nullptr) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700309 for (ArtField& field : klass->GetSFields()) {
310 if (name2->Equals(field.GetName())) {
311 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700312 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700313 }
314 }
315 }
David Brazdil5a61bb72018-01-19 16:59:46 +0000316 if (found != nullptr &&
317 hiddenapi::ShouldBlockAccessToMember(found, shadow_frame->GetMethod())) {
318 found = nullptr;
319 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700320 if (found == nullptr) {
321 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
322 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
David Sehr709b0702016-10-13 09:12:37 -0700323 klass->PrettyDescriptor().c_str());
Andreas Gampe068b0c02015-03-11 12:44:47 -0700324 return;
325 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700326 Runtime* runtime = Runtime::Current();
Andreas Gampe542451c2016-07-26 09:02:02 -0700327 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Andreas Gampee01e3642016-07-25 13:06:04 -0700328 mirror::Field* field;
329 if (runtime->IsActiveTransaction()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700330 if (pointer_size == PointerSize::k64) {
331 field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
332 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700333 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700334 field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
335 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700336 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700337 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700338 if (pointer_size == PointerSize::k64) {
339 field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
340 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700341 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700342 field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
343 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700344 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700345 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700346 result->SetL(field);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700347}
348
Andreas Gampebc4d2182016-02-22 10:03:12 -0800349// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
350void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
351 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
352 // Special managed code cut-out to allow method lookup in a un-started runtime.
353 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
354 if (klass == nullptr) {
355 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
356 return;
357 }
358 mirror::String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
359 mirror::ObjectArray<mirror::Class>* args =
360 shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700361 Runtime* runtime = Runtime::Current();
362 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700363 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700364 ObjPtr<mirror::Method> method;
Andreas Gampee01e3642016-07-25 13:06:04 -0700365 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700366 if (pointer_size == PointerSize::k64) {
367 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
368 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700369 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700370 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
371 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700372 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800373 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700374 if (pointer_size == PointerSize::k64) {
375 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
376 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700377 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700378 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
379 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700380 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800381 }
David Brazdil5a61bb72018-01-19 16:59:46 +0000382 if (method != nullptr &&
383 hiddenapi::ShouldBlockAccessToMember(method->GetArtMethod(), shadow_frame->GetMethod())) {
384 method = nullptr;
385 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700386 result->SetL(method);
Andreas Gampebc4d2182016-02-22 10:03:12 -0800387}
388
Andreas Gampe6039e562016-04-05 18:18:43 -0700389// Special managed code cut-out to allow constructor lookup in a un-started runtime.
390void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
391 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
392 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
393 if (klass == nullptr) {
394 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
395 return;
396 }
397 mirror::ObjectArray<mirror::Class>* args =
398 shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700399 Runtime* runtime = Runtime::Current();
400 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700401 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700402 ObjPtr<mirror::Constructor> constructor;
Andreas Gampee01e3642016-07-25 13:06:04 -0700403 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700404 if (pointer_size == PointerSize::k64) {
405 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
406 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700407 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700408 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
409 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700410 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700411 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700412 if (pointer_size == PointerSize::k64) {
413 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
414 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700415 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700416 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
417 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700418 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700419 }
David Brazdil5a61bb72018-01-19 16:59:46 +0000420 if (constructor != nullptr &&
421 hiddenapi::ShouldBlockAccessToMember(
422 constructor->GetArtMethod(), shadow_frame->GetMethod())) {
423 constructor = nullptr;
424 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700425 result->SetL(constructor);
Andreas Gampe6039e562016-04-05 18:18:43 -0700426}
427
Andreas Gampeae78c262017-02-01 20:40:44 -0800428void UnstartedRuntime::UnstartedClassGetDeclaringClass(
429 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
430 StackHandleScope<1> hs(self);
431 Handle<mirror::Class> klass(hs.NewHandle(
432 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
433 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
434 result->SetL(nullptr);
435 return;
436 }
437 // Return null for anonymous classes.
438 JValue is_anon_result;
439 UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
440 if (is_anon_result.GetZ() != 0) {
441 result->SetL(nullptr);
442 return;
443 }
444 result->SetL(annotations::GetDeclaringClass(klass));
445}
446
Andreas Gampe633750c2016-02-19 10:49:50 -0800447void UnstartedRuntime::UnstartedClassGetEnclosingClass(
448 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
449 StackHandleScope<1> hs(self);
450 Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
451 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
452 result->SetL(nullptr);
453 }
David Sehr9323e6e2016-09-13 08:58:35 -0700454 result->SetL(annotations::GetEnclosingClass(klass));
Andreas Gampe633750c2016-02-19 10:49:50 -0800455}
456
Andreas Gampe715fdc22016-04-18 17:07:30 -0700457void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
458 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
459 StackHandleScope<1> hs(self);
460 Handle<mirror::Class> klass(hs.NewHandle(
461 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
462 const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
463 result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
464}
465
Andreas Gampe9486a162017-02-16 15:17:47 -0800466void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
467 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
468 StackHandleScope<1> hs(self);
469 Handle<mirror::Class> klass(hs.NewHandle(
470 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
471
472 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
473 result->SetL(nullptr);
474 return;
475 }
476
477 result->SetL(annotations::GetSignatureAnnotationForClass(klass));
478}
479
Andreas Gampeae78c262017-02-01 20:40:44 -0800480void UnstartedRuntime::UnstartedClassIsAnonymousClass(
481 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
482 StackHandleScope<1> hs(self);
483 Handle<mirror::Class> klass(hs.NewHandle(
484 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
485 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
486 result->SetZ(false);
487 return;
488 }
489 mirror::String* class_name = nullptr;
490 if (!annotations::GetInnerClass(klass, &class_name)) {
491 result->SetZ(false);
492 return;
493 }
494 result->SetZ(class_name == nullptr);
495}
496
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700497static std::unique_ptr<MemMap> FindAndExtractEntry(const std::string& jar_file,
498 const char* entry_name,
499 size_t* size,
500 std::string* error_msg) {
501 CHECK(size != nullptr);
502
503 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
504 if (zip_archive == nullptr) {
Mathieu Chartier6beced42016-11-15 15:51:31 -0800505 return nullptr;
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700506 }
507 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
508 if (zip_entry == nullptr) {
509 return nullptr;
510 }
511 std::unique_ptr<MemMap> tmp_map(
512 zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg));
513 if (tmp_map == nullptr) {
514 return nullptr;
515 }
516
517 // OK, from here everything seems fine.
518 *size = zip_entry->GetUncompressedLength();
519 return tmp_map;
520}
521
522static void GetResourceAsStream(Thread* self,
523 ShadowFrame* shadow_frame,
524 JValue* result,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700525 size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700526 mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
527 if (resource_obj == nullptr) {
528 AbortTransactionOrFail(self, "null name for getResourceAsStream");
529 return;
530 }
531 CHECK(resource_obj->IsString());
532 mirror::String* resource_name = resource_obj->AsString();
533
534 std::string resource_name_str = resource_name->ToModifiedUtf8();
535 if (resource_name_str.empty() || resource_name_str == "/") {
536 AbortTransactionOrFail(self,
537 "Unsupported name %s for getResourceAsStream",
538 resource_name_str.c_str());
539 return;
540 }
541 const char* resource_cstr = resource_name_str.c_str();
542 if (resource_cstr[0] == '/') {
543 resource_cstr++;
544 }
545
546 Runtime* runtime = Runtime::Current();
547
548 std::vector<std::string> split;
549 Split(runtime->GetBootClassPathString(), ':', &split);
550 if (split.empty()) {
551 AbortTransactionOrFail(self,
552 "Boot classpath not set or split error:: %s",
553 runtime->GetBootClassPathString().c_str());
554 return;
555 }
556
557 std::unique_ptr<MemMap> mem_map;
558 size_t map_size;
559 std::string last_error_msg; // Only store the last message (we could concatenate).
560
561 for (const std::string& jar_file : split) {
562 mem_map = FindAndExtractEntry(jar_file, resource_cstr, &map_size, &last_error_msg);
563 if (mem_map != nullptr) {
564 break;
565 }
566 }
567
568 if (mem_map == nullptr) {
569 // Didn't find it. There's a good chance this will be the same at runtime, but still
570 // conservatively abort the transaction here.
571 AbortTransactionOrFail(self,
572 "Could not find resource %s. Last error was %s.",
573 resource_name_str.c_str(),
574 last_error_msg.c_str());
575 return;
576 }
577
578 StackHandleScope<3> hs(self);
579
580 // Create byte array for content.
581 Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800582 if (h_array == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700583 AbortTransactionOrFail(self, "Could not find/create byte array class");
584 return;
585 }
586 // Copy in content.
587 memcpy(h_array->GetData(), mem_map->Begin(), map_size);
588 // Be proactive releasing memory.
Andreas Gampeeac4f282017-04-26 21:07:04 -0700589 mem_map.reset();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700590
591 // Create a ByteArrayInputStream.
592 Handle<mirror::Class> h_class(hs.NewHandle(
593 runtime->GetClassLinker()->FindClass(self,
594 "Ljava/io/ByteArrayInputStream;",
595 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800596 if (h_class == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700597 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
598 return;
599 }
600 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
601 AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
602 return;
603 }
604
605 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800606 if (h_obj == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700607 AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
608 return;
609 }
610
611 auto* cl = Runtime::Current()->GetClassLinker();
Vladimir Markoba118822017-06-12 15:41:56 +0100612 ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700613 if (constructor == nullptr) {
614 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
615 return;
616 }
617
618 uint32_t args[1];
619 args[0] = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_array.Get()));
620 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
621
622 if (self->IsExceptionPending()) {
623 AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
624 return;
625 }
626
627 result->SetL(h_obj.Get());
628}
629
630void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
631 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
632 {
633 mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
634 CHECK(this_obj != nullptr);
635 CHECK(this_obj->IsClassLoader());
636
637 StackHandleScope<1> hs(self);
638 Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
639
640 if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
641 this_classloader_class.Get()) {
642 AbortTransactionOrFail(self,
David Sehr709b0702016-10-13 09:12:37 -0700643 "Unsupported classloader type %s for getResourceAsStream",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700644 mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700645 return;
646 }
647 }
648
649 GetResourceAsStream(self, shadow_frame, result, arg_offset);
650}
651
Andreas Gampe85bef7e2017-02-16 18:13:26 -0800652void UnstartedRuntime::UnstartedConstructorNewInstance0(
653 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
654 // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
655 StackHandleScope<4> hs(self);
656 Handle<mirror::Constructor> m = hs.NewHandle(
657 reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
658 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
659 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
660 shadow_frame->GetVRegReference(arg_offset + 1)));
661 Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
662 if (UNLIKELY(c->IsAbstract())) {
663 AbortTransactionOrFail(self, "Cannot handle abstract classes");
664 return;
665 }
666 // Verify that we can access the class.
667 if (!m->IsAccessible() && !c->IsPublic()) {
668 // Go 2 frames back, this method is always called from newInstance0, which is called from
669 // Constructor.newInstance(Object... args).
670 ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
671 // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
672 // access checks anyways. TODO: Investigate if this the correct behavior.
673 if (caller != nullptr && !caller->CanAccess(c.Get())) {
674 AbortTransactionOrFail(self, "Cannot access class");
675 return;
676 }
677 }
678 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
679 DCHECK(self->IsExceptionPending());
680 return;
681 }
682 if (c->IsClassClass()) {
683 AbortTransactionOrFail(self, "new Class() is not supported");
684 return;
685 }
686
687 // String constructor is replaced by a StringFactory method in InvokeMethod.
688 if (c->IsStringClass()) {
689 // We don't support strings.
690 AbortTransactionOrFail(self, "String construction is not supported");
691 return;
692 }
693
694 Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
695 if (receiver == nullptr) {
696 AbortTransactionOrFail(self, "Could not allocate");
697 return;
698 }
699
700 // It's easier to use reflection to make the call, than create the uint32_t array.
701 {
702 ScopedObjectAccessUnchecked soa(self);
703 ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
704 soa.AddLocalReference<jobject>(m.Get()));
705 ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
706 soa.AddLocalReference<jobject>(receiver.Get()));
707 ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
708 soa.AddLocalReference<jobject>(args.Get()));
709 InvokeMethod(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
710 }
711 if (self->IsExceptionPending()) {
712 AbortTransactionOrFail(self, "Failed running constructor");
713 } else {
714 result->SetL(receiver.Get());
715 }
716}
717
Andreas Gampe799681b2015-05-15 19:24:12 -0700718void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700719 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700720 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
721 mirror::ClassLoader* class_loader =
722 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
723 StackHandleScope<2> hs(self);
724 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
725 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
726 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
727 "VMClassLoader.findLoadedClass", false, false);
728 // This might have an error pending. But semantics are to just return null.
729 if (self->IsExceptionPending()) {
730 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
David Sehr709b0702016-10-13 09:12:37 -0700731 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700732 if (type != "java.lang.InternalError") {
733 self->ClearException();
734 }
735 }
736}
737
Mathieu Chartiere401d142015-04-22 13:56:20 -0700738void UnstartedRuntime::UnstartedVoidLookupType(
739 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED, JValue* result,
740 size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700741 result->SetL(Runtime::Current()->GetClassLinker()->FindPrimitiveClass('V'));
742}
743
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700744// Arraycopy emulation.
745// Note: we can't use any fast copy functions, as they are not available under transaction.
746
747template <typename T>
748static void PrimitiveArrayCopy(Thread* self,
749 mirror::Array* src_array, int32_t src_pos,
750 mirror::Array* dst_array, int32_t dst_pos,
751 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700752 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700753 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700754 AbortTransactionOrFail(self,
755 "Types mismatched in arraycopy: %s vs %s.",
756 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700757 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700758 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700759 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700760 return;
761 }
762 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
763 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
764 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
765 if (copy_forward) {
766 for (int32_t i = 0; i < length; ++i) {
767 dst->Set(dst_pos + i, src->Get(src_pos + i));
768 }
769 } else {
770 for (int32_t i = 1; i <= length; ++i) {
771 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
772 }
773 }
774}
775
Andreas Gampe799681b2015-05-15 19:24:12 -0700776void UnstartedRuntime::UnstartedSystemArraycopy(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700777 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700778 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700779 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
780 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700781 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700782
Andreas Gampe85a098a2016-03-31 13:30:53 -0700783 mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
784 mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
785 // Null checking. For simplicity, abort transaction.
786 if (src_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700787 AbortTransactionOrFail(self, "src is null in arraycopy.");
788 return;
789 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700790 if (dst_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700791 AbortTransactionOrFail(self, "dst is null in arraycopy.");
792 return;
793 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700794 // Test for arrayness. Throw ArrayStoreException.
795 if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
796 self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
797 return;
798 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700799
Andreas Gampe85a098a2016-03-31 13:30:53 -0700800 mirror::Array* src_array = src_obj->AsArray();
801 mirror::Array* dst_array = dst_obj->AsArray();
802
803 // Bounds checking. Throw IndexOutOfBoundsException.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700804 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
805 UNLIKELY(src_pos > src_array->GetLength() - length) ||
806 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700807 self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700808 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
809 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
810 length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700811 return;
812 }
813
814 // Type checking.
815 mirror::Class* src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
816 GetComponentType();
817
818 if (!src_type->IsPrimitive()) {
819 // Check that the second type is not primitive.
820 mirror::Class* trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
821 GetComponentType();
822 if (trg_type->IsPrimitiveInt()) {
823 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700824 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700825 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700826 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700827 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700828 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700829 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700830
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700831 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
832 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
833 if (src == dst) {
834 // Can overlap, but not have type mismatches.
Andreas Gampe85a098a2016-03-31 13:30:53 -0700835 // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700836 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
837 if (copy_forward) {
838 for (int32_t i = 0; i < length; ++i) {
839 dst->Set(dst_pos + i, src->Get(src_pos + i));
840 }
841 } else {
842 for (int32_t i = 1; i <= length; ++i) {
843 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
844 }
845 }
846 } else {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700847 // We're being lazy here. Optimally this could be a memcpy (if component types are
848 // assignable), but the ObjectArray implementation doesn't support transactions. The
849 // checking version, however, does.
850 if (Runtime::Current()->IsActiveTransaction()) {
851 dst->AssignableCheckingMemcpy<true>(
852 dst_pos, src, src_pos, length, true /* throw_exception */);
853 } else {
854 dst->AssignableCheckingMemcpy<false>(
855 dst_pos, src, src_pos, length, true /* throw_exception */);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700856 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700857 }
Andreas Gampe5c9af612016-04-05 14:16:10 -0700858 } else if (src_type->IsPrimitiveByte()) {
859 PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700860 } else if (src_type->IsPrimitiveChar()) {
861 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
862 } else if (src_type->IsPrimitiveInt()) {
863 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700864 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700865 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700866 src_type->PrettyDescriptor().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700867 }
868}
869
Andreas Gampe5c9af612016-04-05 14:16:10 -0700870void UnstartedRuntime::UnstartedSystemArraycopyByte(
871 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
872 // Just forward.
873 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
874}
875
Andreas Gampe799681b2015-05-15 19:24:12 -0700876void UnstartedRuntime::UnstartedSystemArraycopyChar(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700877 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700878 // Just forward.
879 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
880}
881
882void UnstartedRuntime::UnstartedSystemArraycopyInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700883 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700884 // Just forward.
885 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
886}
887
Narayan Kamath34a316f2016-03-30 13:11:18 +0100888void UnstartedRuntime::UnstartedSystemGetSecurityManager(
889 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
890 JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
891 result->SetL(nullptr);
892}
893
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700894static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
895
896static void GetSystemProperty(Thread* self,
897 ShadowFrame* shadow_frame,
898 JValue* result,
899 size_t arg_offset,
900 bool is_default_version)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700901 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700902 StackHandleScope<4> hs(self);
903 Handle<mirror::String> h_key(
904 hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800905 if (h_key == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700906 AbortTransactionOrFail(self, "getProperty key was null");
907 return;
908 }
909
910 // This is overall inefficient, but reflecting the values here is not great, either. So
911 // for simplicity, and with the assumption that the number of getProperty calls is not
912 // too great, just iterate each time.
913
914 // Get the storage class.
915 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
916 Handle<mirror::Class> h_props_class(hs.NewHandle(
917 class_linker->FindClass(self,
918 "Ljava/lang/AndroidHardcodedSystemProperties;",
919 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800920 if (h_props_class == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700921 AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
922 return;
923 }
924 if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
925 AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
926 return;
927 }
928
929 // Get the storage array.
930 ArtField* static_properties =
931 h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
932 "[[Ljava/lang/String;");
933 if (static_properties == nullptr) {
934 AbortTransactionOrFail(self,
935 "Could not find %s field",
936 kAndroidHardcodedSystemPropertiesFieldName);
937 return;
938 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700939 ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
940 Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
941 props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800942 if (h_2string_array == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700943 AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
944 return;
945 }
946
947 // Iterate over it.
948 const int32_t prop_count = h_2string_array->GetLength();
949 // Use the third handle as mutable.
950 MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
951 hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
952 for (int32_t i = 0; i < prop_count; ++i) {
953 h_string_array.Assign(h_2string_array->Get(i));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800954 if (h_string_array == nullptr ||
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700955 h_string_array->GetLength() != 2 ||
956 h_string_array->Get(0) == nullptr) {
957 AbortTransactionOrFail(self,
958 "Unexpected content of %s",
959 kAndroidHardcodedSystemPropertiesFieldName);
960 return;
961 }
962 if (h_key->Equals(h_string_array->Get(0))) {
963 // Found a value.
964 if (h_string_array->Get(1) == nullptr && is_default_version) {
965 // Null is being delegated to the default map, and then resolved to the given default value.
966 // As there's no default map, return the given value.
967 result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
968 } else {
969 result->SetL(h_string_array->Get(1));
970 }
971 return;
972 }
973 }
974
975 // Key is not supported.
976 AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
977}
978
979void UnstartedRuntime::UnstartedSystemGetProperty(
980 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
981 GetSystemProperty(self, shadow_frame, result, arg_offset, false);
982}
983
984void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
985 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
986 GetSystemProperty(self, shadow_frame, result, arg_offset, true);
987}
988
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800989static std::string GetImmediateCaller(ShadowFrame* shadow_frame)
990 REQUIRES_SHARED(Locks::mutator_lock_) {
991 if (shadow_frame->GetLink() == nullptr) {
992 return "<no caller>";
993 }
994 return ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
995}
996
997static bool CheckCallers(ShadowFrame* shadow_frame,
998 std::initializer_list<std::string> allowed_call_stack)
999 REQUIRES_SHARED(Locks::mutator_lock_) {
1000 for (const std::string& allowed_caller : allowed_call_stack) {
1001 if (shadow_frame->GetLink() == nullptr) {
1002 return false;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001003 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001004
1005 std::string found_caller = ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1006 if (allowed_caller != found_caller) {
1007 return false;
1008 }
1009
1010 shadow_frame = shadow_frame->GetLink();
1011 }
1012 return true;
1013}
1014
1015static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_descriptor)
1016 REQUIRES_SHARED(Locks::mutator_lock_) {
1017 // Find the requested class.
1018 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1019 ObjPtr<mirror::Class> klass =
1020 class_linker->FindClass(self, class_descriptor, ScopedNullHandle<mirror::ClassLoader>());
1021 if (klass == nullptr) {
1022 AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
1023 return nullptr;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001024 }
1025
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001026 StackHandleScope<2> hs(self);
1027 Handle<mirror::Class> h_class(hs.NewHandle(klass));
1028 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001029 if (h_obj != nullptr) {
Vladimir Markoba118822017-06-12 15:41:56 +01001030 ArtMethod* init_method = h_class->FindConstructor("()V", class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001031 if (init_method == nullptr) {
1032 AbortTransactionOrFail(self, "Could not find <init> for %s", class_descriptor);
1033 return nullptr;
1034 } else {
1035 JValue invoke_result;
1036 EnterInterpreterFromInvoke(self, init_method, h_obj.Get(), nullptr, nullptr);
1037 if (!self->IsExceptionPending()) {
1038 return h_obj.Get();
1039 }
1040 AbortTransactionOrFail(self, "Could not run <init> for %s", class_descriptor);
1041 }
1042 }
1043 AbortTransactionOrFail(self, "Could not allocate instance of %s", class_descriptor);
1044 return nullptr;
1045}
1046
1047void UnstartedRuntime::UnstartedThreadLocalGet(
1048 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1049 if (CheckCallers(shadow_frame, { "sun.misc.FloatingDecimal$BinaryToASCIIBuffer "
1050 "sun.misc.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1051 result->SetL(CreateInstanceOf(self, "Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;"));
1052 } else {
1053 AbortTransactionOrFail(self,
1054 "ThreadLocal.get() does not support %s",
1055 GetImmediateCaller(shadow_frame).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001056 }
1057}
1058
Andreas Gampebad529d2017-02-13 18:52:10 -08001059void UnstartedRuntime::UnstartedThreadCurrentThread(
1060 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1061 if (CheckCallers(shadow_frame,
1062 { "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1063 "java.lang.String, long)",
1064 "void java.lang.Thread.<init>()",
1065 "void java.util.logging.LogManager$Cleaner.<init>("
1066 "java.util.logging.LogManager)" })) {
1067 // Whitelist LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
1068 // Thread constructor only asks for the current thread to set up defaults and add the
1069 // thread as unstarted to the ThreadGroup. A faked-up main thread peer is good enough for
1070 // these purposes.
1071 Runtime::Current()->InitThreadGroups(self);
1072 jobject main_peer =
1073 self->CreateCompileTimePeer(self->GetJniEnv(),
1074 "main",
1075 false,
1076 Runtime::Current()->GetMainThreadGroup());
1077 if (main_peer == nullptr) {
1078 AbortTransactionOrFail(self, "Failed allocating peer");
1079 return;
1080 }
1081
1082 result->SetL(self->DecodeJObject(main_peer));
1083 self->GetJniEnv()->DeleteLocalRef(main_peer);
1084 } else {
1085 AbortTransactionOrFail(self,
1086 "Thread.currentThread() does not support %s",
1087 GetImmediateCaller(shadow_frame).c_str());
1088 }
1089}
1090
1091void UnstartedRuntime::UnstartedThreadGetNativeState(
1092 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1093 if (CheckCallers(shadow_frame,
1094 { "java.lang.Thread$State java.lang.Thread.getState()",
1095 "java.lang.ThreadGroup java.lang.Thread.getThreadGroup()",
1096 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1097 "java.lang.String, long)",
1098 "void java.lang.Thread.<init>()",
1099 "void java.util.logging.LogManager$Cleaner.<init>("
1100 "java.util.logging.LogManager)" })) {
1101 // Whitelist reading the state of the "main" thread when creating another (unstarted) thread
1102 // for LogManager. Report the thread as "new" (it really only counts that it isn't terminated).
1103 constexpr int32_t kJavaRunnable = 1;
1104 result->SetI(kJavaRunnable);
1105 } else {
1106 AbortTransactionOrFail(self,
1107 "Thread.getNativeState() does not support %s",
1108 GetImmediateCaller(shadow_frame).c_str());
1109 }
1110}
1111
Sergio Giro83261202016-04-11 20:49:20 +01001112void UnstartedRuntime::UnstartedMathCeil(
1113 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001114 result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
Sergio Giro83261202016-04-11 20:49:20 +01001115}
1116
1117void UnstartedRuntime::UnstartedMathFloor(
1118 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001119 result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001120}
1121
Andreas Gampeb8a00f92016-04-18 20:51:13 -07001122void UnstartedRuntime::UnstartedMathSin(
1123 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1124 result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
1125}
1126
1127void UnstartedRuntime::UnstartedMathCos(
1128 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1129 result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
1130}
1131
1132void UnstartedRuntime::UnstartedMathPow(
1133 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1134 result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
1135 shadow_frame->GetVRegDouble(arg_offset + 2)));
1136}
1137
Andreas Gampe799681b2015-05-15 19:24:12 -07001138void UnstartedRuntime::UnstartedObjectHashCode(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001139 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001140 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1141 result->SetI(obj->IdentityHashCode());
1142}
1143
Andreas Gampe799681b2015-05-15 19:24:12 -07001144void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
Andreas Gampedd9d0552015-03-09 12:57:41 -07001145 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001146 double in = shadow_frame->GetVRegDouble(arg_offset);
Roland Levillainda4d79b2015-03-24 14:36:11 +00001147 result->SetJ(bit_cast<int64_t, double>(in));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001148}
1149
Andreas Gampedd9d0552015-03-09 12:57:41 -07001150static void UnstartedMemoryPeek(
1151 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1152 int64_t address = shadow_frame->GetVRegLong(arg_offset);
1153 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
1154 // aborting the transaction.
1155
1156 switch (type) {
1157 case Primitive::kPrimByte: {
1158 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
1159 return;
1160 }
1161
1162 case Primitive::kPrimShort: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001163 typedef int16_t unaligned_short __attribute__ ((aligned (1)));
1164 result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001165 return;
1166 }
1167
1168 case Primitive::kPrimInt: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001169 typedef int32_t unaligned_int __attribute__ ((aligned (1)));
1170 result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001171 return;
1172 }
1173
1174 case Primitive::kPrimLong: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001175 typedef int64_t unaligned_long __attribute__ ((aligned (1)));
1176 result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001177 return;
1178 }
1179
1180 case Primitive::kPrimBoolean:
1181 case Primitive::kPrimChar:
1182 case Primitive::kPrimFloat:
1183 case Primitive::kPrimDouble:
1184 case Primitive::kPrimVoid:
1185 case Primitive::kPrimNot:
1186 LOG(FATAL) << "Not in the Memory API: " << type;
1187 UNREACHABLE();
1188 }
1189 LOG(FATAL) << "Should not reach here";
1190 UNREACHABLE();
1191}
1192
Andreas Gampe799681b2015-05-15 19:24:12 -07001193void UnstartedRuntime::UnstartedMemoryPeekByte(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001194 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001195 UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
1196}
1197
1198void UnstartedRuntime::UnstartedMemoryPeekShort(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001199 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001200 UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
1201}
1202
1203void UnstartedRuntime::UnstartedMemoryPeekInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001204 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001205 UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
1206}
1207
1208void UnstartedRuntime::UnstartedMemoryPeekLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001209 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001210 UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001211}
1212
1213static void UnstartedMemoryPeekArray(
1214 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001215 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampedd9d0552015-03-09 12:57:41 -07001216 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1217 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1218 if (obj == nullptr) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001219 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
Andreas Gampedd9d0552015-03-09 12:57:41 -07001220 return;
1221 }
1222 mirror::Array* array = obj->AsArray();
1223
1224 int offset = shadow_frame->GetVReg(arg_offset + 3);
1225 int count = shadow_frame->GetVReg(arg_offset + 4);
1226 if (offset < 0 || offset + count > array->GetLength()) {
1227 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
1228 offset, count, array->GetLength()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001229 Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
Andreas Gampedd9d0552015-03-09 12:57:41 -07001230 return;
1231 }
1232
1233 switch (type) {
1234 case Primitive::kPrimByte: {
1235 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
1236 mirror::ByteArray* byte_array = array->AsByteArray();
1237 for (int32_t i = 0; i < count; ++i, ++address) {
1238 byte_array->SetWithoutChecks<true>(i + offset, *address);
1239 }
1240 return;
1241 }
1242
1243 case Primitive::kPrimShort:
1244 case Primitive::kPrimInt:
1245 case Primitive::kPrimLong:
1246 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1247 UNREACHABLE();
1248
1249 case Primitive::kPrimBoolean:
1250 case Primitive::kPrimChar:
1251 case Primitive::kPrimFloat:
1252 case Primitive::kPrimDouble:
1253 case Primitive::kPrimVoid:
1254 case Primitive::kPrimNot:
1255 LOG(FATAL) << "Not in the Memory API: " << type;
1256 UNREACHABLE();
1257 }
1258 LOG(FATAL) << "Should not reach here";
1259 UNREACHABLE();
1260}
1261
Andreas Gampe799681b2015-05-15 19:24:12 -07001262void UnstartedRuntime::UnstartedMemoryPeekByteArray(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001263 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001264 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001265}
1266
Kenny Root1c9e61c2015-05-14 15:58:17 -07001267// This allows reading the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001268void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001269 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001270 jint start = shadow_frame->GetVReg(arg_offset + 1);
1271 jint end = shadow_frame->GetVReg(arg_offset + 2);
1272 jint index = shadow_frame->GetVReg(arg_offset + 4);
1273 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1274 if (string == nullptr) {
1275 AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1276 return;
1277 }
Kenny Root57f91e82015-05-14 15:58:17 -07001278 DCHECK_GE(start, 0);
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001279 DCHECK_LE(start, end);
1280 DCHECK_LE(end, string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001281 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001282 Handle<mirror::CharArray> h_char_array(
1283 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001284 DCHECK_GE(index, 0);
Kenny Root57f91e82015-05-14 15:58:17 -07001285 DCHECK_LE(index, h_char_array->GetLength());
1286 DCHECK_LE(end - start, h_char_array->GetLength() - index);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001287 string->GetChars(start, end, h_char_array, index);
1288}
1289
1290// This allows reading chars from the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001291void UnstartedRuntime::UnstartedStringCharAt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001292 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001293 jint index = shadow_frame->GetVReg(arg_offset + 1);
1294 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1295 if (string == nullptr) {
1296 AbortTransactionOrFail(self, "String.charAt with null object");
1297 return;
1298 }
1299 result->SetC(string->CharAt(index));
1300}
1301
Vladimir Marko92907f32017-02-20 14:08:30 +00001302// This allows creating String objects with replaced characters during compilation.
1303// String.doReplace(char, char) is called from String.replace(char, char) when there is a match.
1304void UnstartedRuntime::UnstartedStringDoReplace(
1305 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1306 jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
1307 jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001308 StackHandleScope<1> hs(self);
1309 Handle<mirror::String> string =
1310 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
Kenny Root57f91e82015-05-14 15:58:17 -07001311 if (string == nullptr) {
Vladimir Marko92907f32017-02-20 14:08:30 +00001312 AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
Kenny Root57f91e82015-05-14 15:58:17 -07001313 return;
1314 }
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001315 result->SetL(mirror::String::DoReplace(self, string, old_c, new_c));
Kenny Root57f91e82015-05-14 15:58:17 -07001316}
1317
Kenny Root1c9e61c2015-05-14 15:58:17 -07001318// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001319void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001320 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001321 jint offset = shadow_frame->GetVReg(arg_offset);
1322 jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1323 DCHECK_GE(char_count, 0);
1324 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001325 Handle<mirror::CharArray> h_char_array(
1326 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
Kenny Root1c9e61c2015-05-14 15:58:17 -07001327 Runtime* runtime = Runtime::Current();
1328 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1329 result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator));
1330}
1331
1332// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001333void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001334 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root57f91e82015-05-14 15:58:17 -07001335 mirror::String* to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1336 if (to_copy == nullptr) {
1337 AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1338 return;
1339 }
1340 StackHandleScope<1> hs(self);
1341 Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1342 Runtime* runtime = Runtime::Current();
1343 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1344 result->SetL(mirror::String::AllocFromString<true>(self, h_string->GetLength(), h_string, 0,
1345 allocator));
1346}
1347
Andreas Gampe799681b2015-05-15 19:24:12 -07001348void UnstartedRuntime::UnstartedStringFastSubstring(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001349 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001350 jint start = shadow_frame->GetVReg(arg_offset + 1);
1351 jint length = shadow_frame->GetVReg(arg_offset + 2);
Kenny Root57f91e82015-05-14 15:58:17 -07001352 DCHECK_GE(start, 0);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001353 DCHECK_GE(length, 0);
1354 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001355 Handle<mirror::String> h_string(
1356 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
Kenny Root57f91e82015-05-14 15:58:17 -07001357 DCHECK_LE(start, h_string->GetLength());
1358 DCHECK_LE(start + length, h_string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001359 Runtime* runtime = Runtime::Current();
1360 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1361 result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator));
1362}
1363
Kenny Root57f91e82015-05-14 15:58:17 -07001364// This allows getting the char array for new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001365void UnstartedRuntime::UnstartedStringToCharArray(
Kenny Root57f91e82015-05-14 15:58:17 -07001366 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001367 REQUIRES_SHARED(Locks::mutator_lock_) {
Kenny Root57f91e82015-05-14 15:58:17 -07001368 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1369 if (string == nullptr) {
1370 AbortTransactionOrFail(self, "String.charAt with null object");
1371 return;
1372 }
1373 result->SetL(string->ToCharArray(self));
1374}
1375
Andreas Gampebc4d2182016-02-22 10:03:12 -08001376// This allows statically initializing ConcurrentHashMap and SynchronousQueue.
1377void UnstartedRuntime::UnstartedReferenceGetReferent(
1378 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001379 ObjPtr<mirror::Reference> const ref = down_cast<mirror::Reference*>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001380 shadow_frame->GetVRegReference(arg_offset));
1381 if (ref == nullptr) {
1382 AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1383 return;
1384 }
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001385 ObjPtr<mirror::Object> const referent =
Andreas Gampebc4d2182016-02-22 10:03:12 -08001386 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1387 result->SetL(referent);
1388}
1389
1390// This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1391// conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1392// where we can predict the behavior (somewhat).
1393// Note: this is required (instead of lazy initialization) as these classes are used in the static
1394// initialization of other classes, so will *use* the value.
1395void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1396 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001397 if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001398 // SynchronousQueue really only separates between single- and multiprocessor case. Return
1399 // 8 as a conservative upper approximation.
1400 result->SetI(8);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001401 } else if (CheckCallers(shadow_frame,
1402 { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001403 // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1404 // a good upper bound.
1405 // TODO: Consider resetting in the zygote?
1406 result->SetI(8);
1407 } else {
1408 // Not supported.
1409 AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1410 }
1411}
1412
1413// This allows accessing ConcurrentHashMap/SynchronousQueue.
1414
1415void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1416 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1417 // Argument 0 is the Unsafe instance, skip.
1418 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1419 if (obj == nullptr) {
1420 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1421 return;
1422 }
1423 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1424 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1425 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001426 bool success;
1427 // Check whether we're in a transaction, call accordingly.
1428 if (Runtime::Current()->IsActiveTransaction()) {
1429 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1430 expectedValue,
1431 newValue);
1432 } else {
1433 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1434 expectedValue,
1435 newValue);
1436 }
1437 result->SetZ(success ? 1 : 0);
1438}
1439
1440void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1441 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1442 // Argument 0 is the Unsafe instance, skip.
1443 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1444 if (obj == nullptr) {
1445 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1446 return;
1447 }
1448 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1449 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1450 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 5);
1451
1452 // Must use non transactional mode.
1453 if (kUseReadBarrier) {
1454 // Need to make sure the reference stored in the field is a to-space one before attempting the
1455 // CAS or the CAS could fail incorrectly.
1456 mirror::HeapReference<mirror::Object>* field_addr =
1457 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1458 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001459 ReadBarrier::Barrier<
1460 mirror::Object,
1461 /* kIsVolatile */ false,
1462 kWithReadBarrier,
1463 /* kAlwaysUpdateField */ true>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001464 obj,
1465 MemberOffset(offset),
1466 field_addr);
1467 }
1468 bool success;
1469 // Check whether we're in a transaction, call accordingly.
1470 if (Runtime::Current()->IsActiveTransaction()) {
1471 success = obj->CasFieldStrongSequentiallyConsistentObject<true>(MemberOffset(offset),
1472 expected_value,
1473 newValue);
1474 } else {
1475 success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
1476 expected_value,
1477 newValue);
1478 }
1479 result->SetZ(success ? 1 : 0);
1480}
1481
1482void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1483 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001484 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001485 // Argument 0 is the Unsafe instance, skip.
1486 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1487 if (obj == nullptr) {
1488 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1489 return;
1490 }
1491 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1492 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1493 result->SetL(value);
1494}
1495
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001496void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1497 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001498 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001499 // Argument 0 is the Unsafe instance, skip.
1500 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1501 if (obj == nullptr) {
1502 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1503 return;
1504 }
1505 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1506 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1507 if (Runtime::Current()->IsActiveTransaction()) {
1508 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1509 } else {
1510 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1511 }
1512}
1513
Andreas Gampebc4d2182016-02-22 10:03:12 -08001514void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1515 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001516 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001517 // Argument 0 is the Unsafe instance, skip.
1518 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1519 if (obj == nullptr) {
1520 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1521 return;
1522 }
1523 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1524 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 4);
1525 QuasiAtomic::ThreadFenceRelease();
1526 if (Runtime::Current()->IsActiveTransaction()) {
1527 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1528 } else {
1529 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1530 }
1531}
1532
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001533// A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1534// of correctly handling the corner cases.
1535void UnstartedRuntime::UnstartedIntegerParseInt(
1536 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001537 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001538 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1539 if (obj == nullptr) {
1540 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1541 return;
1542 }
1543
1544 std::string string_value = obj->AsString()->ToModifiedUtf8();
1545 if (string_value.empty()) {
1546 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1547 return;
1548 }
1549
1550 const char* c_str = string_value.c_str();
1551 char *end;
1552 // Can we set errno to 0? Is this always a variable, and not a macro?
1553 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1554 int64_t l = strtol(c_str, &end, 10);
1555
1556 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1557 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1558 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1559 return;
1560 }
1561 if (l == 0) {
1562 // Check whether the string wasn't exactly zero.
1563 if (string_value != "0") {
1564 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1565 return;
1566 }
1567 } else if (*end != '\0') {
1568 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1569 return;
1570 }
1571
1572 result->SetI(static_cast<int32_t>(l));
1573}
1574
1575// A cutout for Long.parseLong.
1576//
1577// Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1578// well.
1579void UnstartedRuntime::UnstartedLongParseLong(
1580 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001581 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001582 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1583 if (obj == nullptr) {
1584 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1585 return;
1586 }
1587
1588 std::string string_value = obj->AsString()->ToModifiedUtf8();
1589 if (string_value.empty()) {
1590 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1591 return;
1592 }
1593
1594 const char* c_str = string_value.c_str();
1595 char *end;
1596 // Can we set errno to 0? Is this always a variable, and not a macro?
1597 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1598 int64_t l = strtol(c_str, &end, 10);
1599
1600 // Note: comparing against int32_t min/max is intentional here.
1601 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1602 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1603 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1604 return;
1605 }
1606 if (l == 0) {
1607 // Check whether the string wasn't exactly zero.
1608 if (string_value != "0") {
1609 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1610 return;
1611 }
1612 } else if (*end != '\0') {
1613 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1614 return;
1615 }
1616
1617 result->SetJ(l);
1618}
1619
Andreas Gampe715fdc22016-04-18 17:07:30 -07001620void UnstartedRuntime::UnstartedMethodInvoke(
1621 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001622 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe715fdc22016-04-18 17:07:30 -07001623 JNIEnvExt* env = self->GetJniEnv();
1624 ScopedObjectAccessUnchecked soa(self);
1625
Mathieu Chartier8778c522016-10-04 19:06:30 -07001626 ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001627 ScopedLocalRef<jobject> java_method(env,
Roland Levillain5e8d5f02016-10-18 18:03:43 +01001628 java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001629
Mathieu Chartier8778c522016-10-04 19:06:30 -07001630 ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001631 ScopedLocalRef<jobject> java_receiver(env,
1632 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1633
Mathieu Chartier8778c522016-10-04 19:06:30 -07001634 ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001635 ScopedLocalRef<jobject> java_args(env,
1636 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1637
1638 ScopedLocalRef<jobject> result_jobj(env,
1639 InvokeMethod(soa, java_method.get(), java_receiver.get(), java_args.get()));
1640
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001641 result->SetL(self->DecodeJObject(result_jobj.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001642
1643 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1644 // InvocationTargetExceptions.
1645 if (self->IsExceptionPending()) {
1646 AbortTransactionOrFail(self, "Failed Method.invoke");
1647 }
1648}
1649
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001650void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1651 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1652 REQUIRES_SHARED(Locks::mutator_lock_) {
1653 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1654 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1655}
Andreas Gampebc4d2182016-02-22 10:03:12 -08001656
Orion Hodson43f0cdb2017-10-10 14:47:32 +01001657// Checks whether the runtime is s64-bit. This is needed for the clinit of
1658// java.lang.invoke.VarHandle clinit. The clinit determines sets of
1659// available VarHandle accessors and these differ based on machine
1660// word size.
1661void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1662 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1663 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1664 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1665 jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1666 result->SetZ(is64bit);
1667}
1668
Mathieu Chartiere401d142015-04-22 13:56:20 -07001669void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
1670 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1671 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001672 int32_t length = args[1];
1673 DCHECK_GE(length, 0);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001674 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001675 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001676 ObjPtr<mirror::Class> array_class =
1677 runtime->GetClassLinker()->FindArrayClass(self, &element_class);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001678 DCHECK(array_class != nullptr);
1679 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001680 result->SetL(mirror::Array::Alloc<true, true>(self,
1681 array_class,
1682 length,
1683 array_class->GetComponentSizeShift(),
1684 allocator));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001685}
1686
Mathieu Chartiere401d142015-04-22 13:56:20 -07001687void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1688 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1689 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001690 result->SetL(nullptr);
1691}
1692
Mathieu Chartiere401d142015-04-22 13:56:20 -07001693void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1694 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1695 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001696 NthCallerVisitor visitor(self, 3);
1697 visitor.WalkStack();
1698 if (visitor.caller != nullptr) {
1699 result->SetL(visitor.caller->GetDeclaringClass());
1700 }
1701}
1702
Mathieu Chartiere401d142015-04-22 13:56:20 -07001703void UnstartedRuntime::UnstartedJNIMathLog(
1704 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1705 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001706 JValue value;
1707 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1708 result->SetD(log(value.GetD()));
1709}
1710
Mathieu Chartiere401d142015-04-22 13:56:20 -07001711void UnstartedRuntime::UnstartedJNIMathExp(
1712 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1713 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001714 JValue value;
1715 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1716 result->SetD(exp(value.GetD()));
1717}
1718
Andreas Gampebc4d2182016-02-22 10:03:12 -08001719void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1720 Thread* self ATTRIBUTE_UNUSED,
1721 ArtMethod* method ATTRIBUTE_UNUSED,
1722 mirror::Object* receiver ATTRIBUTE_UNUSED,
1723 uint32_t* args ATTRIBUTE_UNUSED,
1724 JValue* result) {
1725 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1726 ? 0
1727 : 1);
1728}
1729
Mathieu Chartiere401d142015-04-22 13:56:20 -07001730void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1731 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1732 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001733 StackHandleScope<1> hs(self);
1734 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1735}
1736
Andreas Gampebc4d2182016-02-22 10:03:12 -08001737void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1738 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1739 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1740 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1741 result->SetD(bit_cast<double>(long_input));
1742}
1743
Mathieu Chartiere401d142015-04-22 13:56:20 -07001744void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1745 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1746 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001747 result->SetI(args[0]);
1748}
1749
Mathieu Chartiere401d142015-04-22 13:56:20 -07001750void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1751 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1752 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001753 result->SetI(args[0]);
1754}
1755
Mathieu Chartiere401d142015-04-22 13:56:20 -07001756void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1757 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1758 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001759 result->SetL(receiver->Clone(self));
1760}
1761
Mathieu Chartiere401d142015-04-22 13:56:20 -07001762void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1763 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1764 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001765 receiver->NotifyAll(self);
1766}
1767
Mathieu Chartiere401d142015-04-22 13:56:20 -07001768void UnstartedRuntime::UnstartedJNIStringCompareTo(
1769 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver, uint32_t* args,
1770 JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001771 mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
1772 if (rhs == nullptr) {
Andreas Gampe068b0c02015-03-11 12:44:47 -07001773 AbortTransactionOrFail(self, "String.compareTo with null object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001774 }
1775 result->SetI(receiver->AsString()->CompareTo(rhs));
1776}
1777
Mathieu Chartiere401d142015-04-22 13:56:20 -07001778void UnstartedRuntime::UnstartedJNIStringIntern(
1779 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1780 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001781 result->SetL(receiver->AsString()->Intern());
1782}
1783
Mathieu Chartiere401d142015-04-22 13:56:20 -07001784void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1785 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1786 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001787 StackHandleScope<2> hs(self);
1788 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1789 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1790 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1791}
1792
Mathieu Chartiere401d142015-04-22 13:56:20 -07001793void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1794 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1795 uint32_t* args, JValue* result) {
Andreas Gampee598e042015-04-10 14:57:10 -07001796 int32_t length = static_cast<int32_t>(args[1]);
1797 if (length < 0) {
1798 ThrowNegativeArraySizeException(length);
1799 return;
1800 }
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001801 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
Andreas Gampee598e042015-04-10 14:57:10 -07001802 Runtime* runtime = Runtime::Current();
1803 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001804 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, &element_class);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001805 if (UNLIKELY(array_class == nullptr)) {
Andreas Gampee598e042015-04-10 14:57:10 -07001806 CHECK(self->IsExceptionPending());
1807 return;
1808 }
1809 DCHECK(array_class->IsObjectArrayClass());
1810 mirror::Array* new_array = mirror::ObjectArray<mirror::Object*>::Alloc(
1811 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1812 result->SetL(new_array);
1813}
1814
Mathieu Chartiere401d142015-04-22 13:56:20 -07001815void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1816 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1817 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001818 ScopedObjectAccessUnchecked soa(self);
1819 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001820 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<true>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001821 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001822 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<false>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001823 }
1824}
1825
Mathieu Chartiere401d142015-04-22 13:56:20 -07001826void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
1827 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1828 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001829 result->SetZ(JNI_TRUE);
1830}
1831
Mathieu Chartiere401d142015-04-22 13:56:20 -07001832void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
1833 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1834 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001835 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1836 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1837 jint expectedValue = args[3];
1838 jint newValue = args[4];
1839 bool success;
1840 if (Runtime::Current()->IsActiveTransaction()) {
1841 success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
1842 expectedValue, newValue);
1843 } else {
1844 success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
1845 expectedValue, newValue);
1846 }
1847 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1848}
1849
Narayan Kamath34a316f2016-03-30 13:11:18 +01001850void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(
1851 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1852 uint32_t* args, JValue* result) {
1853 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1854 if (obj == nullptr) {
1855 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1856 return;
1857 }
1858
1859 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1860 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1861}
1862
Mathieu Chartiere401d142015-04-22 13:56:20 -07001863void UnstartedRuntime::UnstartedJNIUnsafePutObject(
1864 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1865 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001866 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1867 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1868 mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
1869 if (Runtime::Current()->IsActiveTransaction()) {
1870 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1871 } else {
1872 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1873 }
1874}
1875
Andreas Gampe799681b2015-05-15 19:24:12 -07001876void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001877 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1878 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001879 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1880 Primitive::Type primitive_type = component->GetPrimitiveType();
1881 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1882}
1883
Andreas Gampe799681b2015-05-15 19:24:12 -07001884void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001885 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1886 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001887 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1888 Primitive::Type primitive_type = component->GetPrimitiveType();
1889 result->SetI(Primitive::ComponentSize(primitive_type));
1890}
1891
Andreas Gampedd9d0552015-03-09 12:57:41 -07001892typedef void (*InvokeHandler)(Thread* self, ShadowFrame* shadow_frame, JValue* result,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001893 size_t arg_size);
1894
Mathieu Chartiere401d142015-04-22 13:56:20 -07001895typedef void (*JNIHandler)(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001896 uint32_t* args, JValue* result);
1897
1898static bool tables_initialized_ = false;
1899static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
1900static std::unordered_map<std::string, JNIHandler> jni_handlers_;
1901
Andreas Gampe799681b2015-05-15 19:24:12 -07001902void UnstartedRuntime::InitializeInvokeHandlers() {
1903#define UNSTARTED_DIRECT(ShortName, Sig) \
1904 invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
1905#include "unstarted_runtime_list.h"
1906 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
1907#undef UNSTARTED_RUNTIME_DIRECT_LIST
1908#undef UNSTARTED_RUNTIME_JNI_LIST
1909#undef UNSTARTED_DIRECT
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001910}
1911
Andreas Gampe799681b2015-05-15 19:24:12 -07001912void UnstartedRuntime::InitializeJNIHandlers() {
1913#define UNSTARTED_JNI(ShortName, Sig) \
1914 jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
1915#include "unstarted_runtime_list.h"
1916 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
1917#undef UNSTARTED_RUNTIME_DIRECT_LIST
1918#undef UNSTARTED_RUNTIME_JNI_LIST
1919#undef UNSTARTED_JNI
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001920}
1921
Andreas Gampe799681b2015-05-15 19:24:12 -07001922void UnstartedRuntime::Initialize() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001923 CHECK(!tables_initialized_);
1924
Andreas Gampe799681b2015-05-15 19:24:12 -07001925 InitializeInvokeHandlers();
1926 InitializeJNIHandlers();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001927
1928 tables_initialized_ = true;
1929}
1930
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001931void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
Andreas Gampe799681b2015-05-15 19:24:12 -07001932 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001933 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
1934 // problems in core libraries.
1935 CHECK(tables_initialized_);
1936
David Sehr709b0702016-10-13 09:12:37 -07001937 std::string name(ArtMethod::PrettyMethod(shadow_frame->GetMethod()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001938 const auto& iter = invoke_handlers_.find(name);
1939 if (iter != invoke_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001940 // Clear out the result in case it's not zeroed out.
1941 result->SetL(0);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001942
1943 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
1944 self->PushShadowFrame(shadow_frame);
1945
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001946 (*iter->second)(self, shadow_frame, result, arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001947
1948 self->PopShadowFrame();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001949 } else {
1950 // Not special, continue with regular interpreter execution.
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001951 ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001952 }
1953}
1954
1955// 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 -07001956void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe799681b2015-05-15 19:24:12 -07001957 uint32_t* args, JValue* result) {
David Sehr709b0702016-10-13 09:12:37 -07001958 std::string name(ArtMethod::PrettyMethod(method));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001959 const auto& iter = jni_handlers_.find(name);
1960 if (iter != jni_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001961 // Clear out the result in case it's not zeroed out.
1962 result->SetL(0);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001963 (*iter->second)(self, method, receiver, args, result);
1964 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02001965 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
1966 name.c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001967 } else {
David Sehr709b0702016-10-13 09:12:37 -07001968 LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001969 "non-transactional runtime";
1970 }
1971}
1972
1973} // namespace interpreter
1974} // namespace art