blob: 76df65f7303e525117c99bfea79a4424a67b661b [file] [log] [blame]
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "unstarted_runtime.h"
18
Andreas Gampe8ce9c302016-04-15 21:24:28 -070019#include <ctype.h>
Andreas Gampe13fc1be2016-04-05 20:14:30 -070020#include <errno.h>
21#include <stdlib.h>
22
Andreas Gampe2969bcd2015-03-09 12:57:41 -070023#include <cmath>
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -080024#include <initializer_list>
Andreas Gampe13fc1be2016-04-05 20:14:30 -070025#include <limits>
Andreas Gampe8ce9c302016-04-15 21:24:28 -070026#include <locale>
Andreas Gampe2969bcd2015-03-09 12:57:41 -070027#include <unordered_map>
28
Andreas Gampe57943812017-12-06 21:39:13 -080029#include <android-base/logging.h>
30#include <android-base/stringprintf.h>
Andreas Gampeaacc25d2015-04-01 14:49:06 -070031
Mathieu Chartiere401d142015-04-22 13:56:20 -070032#include "art_method-inl.h"
Andreas Gampebc4d2182016-02-22 10:03:12 -080033#include "base/casts.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070034#include "base/enums.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070035#include "base/macros.h"
David Sehrc431b9d2018-03-02 12:01:51 -080036#include "base/quasi_atomic.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070037#include "class_linker.h"
38#include "common_throws.h"
David Sehrb2ec9f52018-02-21 13:20:31 -080039#include "dex/descriptors_names.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070040#include "entrypoints/entrypoint_utils-inl.h"
Andreas Gampebc4d2182016-02-22 10:03:12 -080041#include "gc/reference_processor.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070042#include "handle_scope-inl.h"
David Brazdil5a61bb72018-01-19 16:59:46 +000043#include "hidden_api.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070044#include "interpreter/interpreter_common.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070045#include "jvalue-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070046#include "mirror/array-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070047#include "mirror/class.h"
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070048#include "mirror/field-inl.h"
Narayan Kamath14832ef2016-08-05 11:44:32 +010049#include "mirror/method.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070050#include "mirror/object-inl.h"
51#include "mirror/object_array-inl.h"
52#include "mirror/string-inl.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070053#include "nativehelper/scoped_local_ref.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070054#include "nth_caller_visitor.h"
Andreas Gampe715fdc22016-04-18 17:07:30 -070055#include "reflection.h"
Andreas Gampe513061a2017-06-01 09:17:34 -070056#include "thread-inl.h"
Sebastien Hertz2fd7e692015-04-02 11:11:19 +020057#include "transaction.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070058#include "well_known_classes.h"
Andreas Gampef778eb22015-04-13 14:17:09 -070059#include "zip_archive.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070060
61namespace art {
62namespace interpreter {
63
Andreas Gampe46ee31b2016-12-14 10:11:49 -080064using android::base::StringAppendV;
65using android::base::StringPrintf;
66
Andreas Gampe068b0c02015-03-11 12:44:47 -070067static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
Sebastien Hertz45b15972015-04-03 16:07:05 +020068 __attribute__((__format__(__printf__, 2, 3)))
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070069 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertz45b15972015-04-03 16:07:05 +020070
71static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
Andreas Gampe068b0c02015-03-11 12:44:47 -070072 va_list args;
Andreas Gampe068b0c02015-03-11 12:44:47 -070073 if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +020074 va_start(args, fmt);
75 AbortTransactionV(self, fmt, args);
Andreas Gampe068b0c02015-03-11 12:44:47 -070076 va_end(args);
77 } else {
Sebastien Hertz45b15972015-04-03 16:07:05 +020078 va_start(args, fmt);
79 std::string msg;
80 StringAppendV(&msg, fmt, args);
81 va_end(args);
82 LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
Andreas Gampe068b0c02015-03-11 12:44:47 -070083 UNREACHABLE();
84 }
85}
86
Andreas Gampe8ce9c302016-04-15 21:24:28 -070087// Restricted support for character upper case / lower case. Only support ASCII, where
88// it's easy. Abort the transaction otherwise.
89static void CharacterLowerUpper(Thread* self,
90 ShadowFrame* shadow_frame,
91 JValue* result,
92 size_t arg_offset,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070093 bool to_lower_case) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8ce9c302016-04-15 21:24:28 -070094 uint32_t int_value = static_cast<uint32_t>(shadow_frame->GetVReg(arg_offset));
95
96 // Only ASCII (7-bit).
97 if (!isascii(int_value)) {
98 AbortTransactionOrFail(self,
99 "Only support ASCII characters for toLowerCase/toUpperCase: %u",
100 int_value);
101 return;
102 }
103
104 std::locale c_locale("C");
105 char char_value = static_cast<char>(int_value);
106
107 if (to_lower_case) {
108 result->SetI(std::tolower(char_value, c_locale));
109 } else {
110 result->SetI(std::toupper(char_value, c_locale));
111 }
112}
113
114void UnstartedRuntime::UnstartedCharacterToLowerCase(
115 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
116 CharacterLowerUpper(self, shadow_frame, result, arg_offset, true);
117}
118
119void UnstartedRuntime::UnstartedCharacterToUpperCase(
120 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
121 CharacterLowerUpper(self, shadow_frame, result, arg_offset, false);
122}
123
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700124// Helper function to deal with class loading in an unstarted runtime.
125static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
126 Handle<mirror::ClassLoader> class_loader, JValue* result,
127 const std::string& method_name, bool initialize_class,
128 bool abort_if_not_found)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700129 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampefa4333d2017-02-14 11:10:34 -0800130 CHECK(className != nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700131 std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
132 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
133
134 mirror::Class* found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
135 if (found == nullptr && abort_if_not_found) {
136 if (!self->IsExceptionPending()) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700137 AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
David Sehr709b0702016-10-13 09:12:37 -0700138 method_name.c_str(),
139 PrettyDescriptor(descriptor.c_str()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700140 }
141 return;
142 }
143 if (found != nullptr && initialize_class) {
144 StackHandleScope<1> hs(self);
145 Handle<mirror::Class> h_class(hs.NewHandle(found));
146 if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
147 CHECK(self->IsExceptionPending());
148 return;
149 }
150 }
151 result->SetL(found);
152}
153
154// Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
155// rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
156// ClassNotFoundException), so need to do the same. The only exception is if the exception is
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200157// actually the transaction abort exception. This must not be wrapped, as it signals an
158// initialization abort.
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700159static void CheckExceptionGenerateClassNotFound(Thread* self)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700160 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700161 if (self->IsExceptionPending()) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200162 // If it is not the transaction abort exception, wrap it.
David Sehr709b0702016-10-13 09:12:37 -0700163 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200164 if (type != Transaction::kAbortExceptionDescriptor) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700165 self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
166 "ClassNotFoundException");
167 }
168 }
169}
170
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700171static mirror::String* GetClassName(Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700172 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700173 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
174 if (param == nullptr) {
175 AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
176 return nullptr;
177 }
178 return param->AsString();
179}
180
David Brazdila02cb112018-01-31 11:36:39 +0000181template<typename T>
182static ALWAYS_INLINE bool ShouldBlockAccessToMember(T* member, ShadowFrame* frame)
183 REQUIRES_SHARED(Locks::mutator_lock_) {
184 return hiddenapi::ShouldBlockAccessToMember(
David Brazdil8ce3bfa2018-03-12 18:01:18 +0000185 member,
186 frame->GetMethod()->GetDeclaringClass()->GetClassLoader(),
187 hiddenapi::kReflection); // all uses in this file are from reflection
David Brazdila02cb112018-01-31 11:36:39 +0000188}
189
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800190void UnstartedRuntime::UnstartedClassForNameCommon(Thread* self,
191 ShadowFrame* shadow_frame,
192 JValue* result,
193 size_t arg_offset,
194 bool long_form,
195 const char* caller) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700196 mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
197 if (class_name == nullptr) {
198 return;
199 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800200 bool initialize_class;
201 mirror::ClassLoader* class_loader;
202 if (long_form) {
203 initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
204 class_loader = down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
205 } else {
206 initialize_class = true;
207 // TODO: This is really only correct for the boot classpath, and for robustness we should
208 // check the caller.
209 class_loader = nullptr;
210 }
211
212 ScopedObjectAccessUnchecked soa(self);
213 if (class_loader != nullptr && !ClassLinker::IsBootClassLoader(soa, class_loader)) {
214 AbortTransactionOrFail(self,
215 "Only the boot classloader is supported: %s",
216 mirror::Object::PrettyTypeOf(class_loader).c_str());
217 return;
218 }
219
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700220 StackHandleScope<1> hs(self);
221 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800222 UnstartedRuntimeFindClass(self,
223 h_class_name,
224 ScopedNullHandle<mirror::ClassLoader>(),
225 result,
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800226 caller,
227 initialize_class,
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800228 false);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700229 CheckExceptionGenerateClassNotFound(self);
230}
231
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800232void UnstartedRuntime::UnstartedClassForName(
233 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
234 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, false, "Class.forName");
235}
236
Andreas Gampe799681b2015-05-15 19:24:12 -0700237void UnstartedRuntime::UnstartedClassForNameLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700238 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800239 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.forName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700240}
241
Vladimir Marko7287c4d2018-02-15 10:41:07 +0000242void UnstartedRuntime::UnstartedClassGetPrimitiveClass(
243 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
244 ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
245 ObjPtr<mirror::Class> klass = mirror::Class::GetPrimitiveClass(class_name);
246 if (UNLIKELY(klass == nullptr)) {
247 DCHECK(self->IsExceptionPending());
248 AbortTransactionOrFail(self,
249 "Class.getPrimitiveClass() failed: %s",
250 self->GetException()->GetDetailMessage()->ToModifiedUtf8().c_str());
251 return;
252 }
253 result->SetL(klass);
254}
255
Andreas Gampe799681b2015-05-15 19:24:12 -0700256void UnstartedRuntime::UnstartedClassClassForName(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700257 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800258 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.classForName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700259}
260
Andreas Gampe799681b2015-05-15 19:24:12 -0700261void UnstartedRuntime::UnstartedClassNewInstance(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700262 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
263 StackHandleScope<2> hs(self); // Class, constructor, object.
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700264 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
265 if (param == nullptr) {
266 AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
267 return;
268 }
269 mirror::Class* klass = param->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700270 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700271
272 // Check that it's not null.
Andreas Gampefa4333d2017-02-14 11:10:34 -0800273 if (h_klass == nullptr) {
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700274 AbortTransactionOrFail(self, "Class reference is null for newInstance");
275 return;
276 }
277
278 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
279 if (Runtime::Current()->IsActiveTransaction()) {
280 if (h_klass.Get()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200281 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700282 h_klass->PrettyClass().c_str());
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700283 return;
284 }
285 }
286
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700287 // There are two situations in which we'll abort this run.
288 // 1) If the class isn't yet initialized and initialization fails.
289 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
290 // Note that 2) could likely be handled here, but for safety abort the transaction.
291 bool ok = false;
Mathieu Chartiere401d142015-04-22 13:56:20 -0700292 auto* cl = Runtime::Current()->GetClassLinker();
293 if (cl->EnsureInitialized(self, h_klass, true, true)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000294 ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
David Brazdila02cb112018-01-31 11:36:39 +0000295 if (cons != nullptr && ShouldBlockAccessToMember(cons, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000296 cons = nullptr;
297 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700298 if (cons != nullptr) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700299 Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800300 CHECK(h_obj != nullptr); // We don't expect OOM at compile-time.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700301 EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700302 if (!self->IsExceptionPending()) {
303 result->SetL(h_obj.Get());
304 ok = true;
305 }
306 } else {
307 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
308 "Could not find default constructor for '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700309 h_klass->PrettyClass().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700310 }
311 }
312 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700313 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
David Sehr709b0702016-10-13 09:12:37 -0700314 h_klass->PrettyClass().c_str(),
315 mirror::Object::PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700316 }
317}
318
Andreas Gampe799681b2015-05-15 19:24:12 -0700319void UnstartedRuntime::UnstartedClassGetDeclaredField(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700320 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700321 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
322 // going the reflective Dex way.
323 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
324 mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700325 ArtField* found = nullptr;
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700326 for (ArtField& field : klass->GetIFields()) {
327 if (name2->Equals(field.GetName())) {
328 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700329 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700330 }
331 }
332 if (found == nullptr) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700333 for (ArtField& field : klass->GetSFields()) {
334 if (name2->Equals(field.GetName())) {
335 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700336 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700337 }
338 }
339 }
David Brazdila02cb112018-01-31 11:36:39 +0000340 if (found != nullptr && ShouldBlockAccessToMember(found, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000341 found = nullptr;
342 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700343 if (found == nullptr) {
344 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
345 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
David Sehr709b0702016-10-13 09:12:37 -0700346 klass->PrettyDescriptor().c_str());
Andreas Gampe068b0c02015-03-11 12:44:47 -0700347 return;
348 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700349 Runtime* runtime = Runtime::Current();
Andreas Gampe542451c2016-07-26 09:02:02 -0700350 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Andreas Gampee01e3642016-07-25 13:06:04 -0700351 mirror::Field* field;
352 if (runtime->IsActiveTransaction()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700353 if (pointer_size == PointerSize::k64) {
354 field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
355 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700356 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700357 field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
358 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700359 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700360 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700361 if (pointer_size == PointerSize::k64) {
362 field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
363 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700364 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700365 field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
366 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700367 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700368 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700369 result->SetL(field);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700370}
371
Andreas Gampebc4d2182016-02-22 10:03:12 -0800372// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
373void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
374 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
375 // Special managed code cut-out to allow method lookup in a un-started runtime.
376 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
377 if (klass == nullptr) {
378 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
379 return;
380 }
381 mirror::String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
382 mirror::ObjectArray<mirror::Class>* args =
383 shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700384 Runtime* runtime = Runtime::Current();
385 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700386 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700387 ObjPtr<mirror::Method> method;
Andreas Gampee01e3642016-07-25 13:06:04 -0700388 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700389 if (pointer_size == PointerSize::k64) {
390 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
391 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700392 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700393 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
394 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700395 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800396 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700397 if (pointer_size == PointerSize::k64) {
398 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
399 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700400 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700401 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
402 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700403 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800404 }
David Brazdila02cb112018-01-31 11:36:39 +0000405 if (method != nullptr && ShouldBlockAccessToMember(method->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000406 method = nullptr;
407 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700408 result->SetL(method);
Andreas Gampebc4d2182016-02-22 10:03:12 -0800409}
410
Andreas Gampe6039e562016-04-05 18:18:43 -0700411// Special managed code cut-out to allow constructor lookup in a un-started runtime.
412void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
413 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
414 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
415 if (klass == nullptr) {
416 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
417 return;
418 }
419 mirror::ObjectArray<mirror::Class>* args =
420 shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700421 Runtime* runtime = Runtime::Current();
422 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700423 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700424 ObjPtr<mirror::Constructor> constructor;
Andreas Gampee01e3642016-07-25 13:06:04 -0700425 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700426 if (pointer_size == PointerSize::k64) {
427 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
428 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700429 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700430 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
431 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700432 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700433 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700434 if (pointer_size == PointerSize::k64) {
435 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
436 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700437 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700438 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
439 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700440 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700441 }
David Brazdil5a61bb72018-01-19 16:59:46 +0000442 if (constructor != nullptr &&
David Brazdila02cb112018-01-31 11:36:39 +0000443 ShouldBlockAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000444 constructor = nullptr;
445 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700446 result->SetL(constructor);
Andreas Gampe6039e562016-04-05 18:18:43 -0700447}
448
Andreas Gampeae78c262017-02-01 20:40:44 -0800449void UnstartedRuntime::UnstartedClassGetDeclaringClass(
450 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
451 StackHandleScope<1> hs(self);
452 Handle<mirror::Class> klass(hs.NewHandle(
453 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
454 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
455 result->SetL(nullptr);
456 return;
457 }
458 // Return null for anonymous classes.
459 JValue is_anon_result;
460 UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
461 if (is_anon_result.GetZ() != 0) {
462 result->SetL(nullptr);
463 return;
464 }
465 result->SetL(annotations::GetDeclaringClass(klass));
466}
467
Andreas Gampe633750c2016-02-19 10:49:50 -0800468void UnstartedRuntime::UnstartedClassGetEnclosingClass(
469 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
470 StackHandleScope<1> hs(self);
471 Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
472 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
473 result->SetL(nullptr);
474 }
David Sehr9323e6e2016-09-13 08:58:35 -0700475 result->SetL(annotations::GetEnclosingClass(klass));
Andreas Gampe633750c2016-02-19 10:49:50 -0800476}
477
Andreas Gampe715fdc22016-04-18 17:07:30 -0700478void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
479 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
480 StackHandleScope<1> hs(self);
481 Handle<mirror::Class> klass(hs.NewHandle(
482 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
483 const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
484 result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
485}
486
Andreas Gampe9486a162017-02-16 15:17:47 -0800487void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
488 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
489 StackHandleScope<1> hs(self);
490 Handle<mirror::Class> klass(hs.NewHandle(
491 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
492
493 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
494 result->SetL(nullptr);
495 return;
496 }
497
498 result->SetL(annotations::GetSignatureAnnotationForClass(klass));
499}
500
Andreas Gampeae78c262017-02-01 20:40:44 -0800501void UnstartedRuntime::UnstartedClassIsAnonymousClass(
502 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
503 StackHandleScope<1> hs(self);
504 Handle<mirror::Class> klass(hs.NewHandle(
505 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
506 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
507 result->SetZ(false);
508 return;
509 }
510 mirror::String* class_name = nullptr;
511 if (!annotations::GetInnerClass(klass, &class_name)) {
512 result->SetZ(false);
513 return;
514 }
515 result->SetZ(class_name == nullptr);
516}
517
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700518static std::unique_ptr<MemMap> FindAndExtractEntry(const std::string& jar_file,
519 const char* entry_name,
520 size_t* size,
521 std::string* error_msg) {
522 CHECK(size != nullptr);
523
524 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
525 if (zip_archive == nullptr) {
Mathieu Chartier6beced42016-11-15 15:51:31 -0800526 return nullptr;
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700527 }
528 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
529 if (zip_entry == nullptr) {
530 return nullptr;
531 }
532 std::unique_ptr<MemMap> tmp_map(
533 zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg));
534 if (tmp_map == nullptr) {
535 return nullptr;
536 }
537
538 // OK, from here everything seems fine.
539 *size = zip_entry->GetUncompressedLength();
540 return tmp_map;
541}
542
543static void GetResourceAsStream(Thread* self,
544 ShadowFrame* shadow_frame,
545 JValue* result,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700546 size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700547 mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
548 if (resource_obj == nullptr) {
549 AbortTransactionOrFail(self, "null name for getResourceAsStream");
550 return;
551 }
552 CHECK(resource_obj->IsString());
553 mirror::String* resource_name = resource_obj->AsString();
554
555 std::string resource_name_str = resource_name->ToModifiedUtf8();
556 if (resource_name_str.empty() || resource_name_str == "/") {
557 AbortTransactionOrFail(self,
558 "Unsupported name %s for getResourceAsStream",
559 resource_name_str.c_str());
560 return;
561 }
562 const char* resource_cstr = resource_name_str.c_str();
563 if (resource_cstr[0] == '/') {
564 resource_cstr++;
565 }
566
567 Runtime* runtime = Runtime::Current();
568
569 std::vector<std::string> split;
570 Split(runtime->GetBootClassPathString(), ':', &split);
571 if (split.empty()) {
572 AbortTransactionOrFail(self,
573 "Boot classpath not set or split error:: %s",
574 runtime->GetBootClassPathString().c_str());
575 return;
576 }
577
578 std::unique_ptr<MemMap> mem_map;
579 size_t map_size;
580 std::string last_error_msg; // Only store the last message (we could concatenate).
581
582 for (const std::string& jar_file : split) {
583 mem_map = FindAndExtractEntry(jar_file, resource_cstr, &map_size, &last_error_msg);
584 if (mem_map != nullptr) {
585 break;
586 }
587 }
588
589 if (mem_map == nullptr) {
590 // Didn't find it. There's a good chance this will be the same at runtime, but still
591 // conservatively abort the transaction here.
592 AbortTransactionOrFail(self,
593 "Could not find resource %s. Last error was %s.",
594 resource_name_str.c_str(),
595 last_error_msg.c_str());
596 return;
597 }
598
599 StackHandleScope<3> hs(self);
600
601 // Create byte array for content.
602 Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800603 if (h_array == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700604 AbortTransactionOrFail(self, "Could not find/create byte array class");
605 return;
606 }
607 // Copy in content.
608 memcpy(h_array->GetData(), mem_map->Begin(), map_size);
609 // Be proactive releasing memory.
Andreas Gampeeac4f282017-04-26 21:07:04 -0700610 mem_map.reset();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700611
612 // Create a ByteArrayInputStream.
613 Handle<mirror::Class> h_class(hs.NewHandle(
614 runtime->GetClassLinker()->FindClass(self,
615 "Ljava/io/ByteArrayInputStream;",
616 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800617 if (h_class == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700618 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
619 return;
620 }
621 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
622 AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
623 return;
624 }
625
626 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800627 if (h_obj == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700628 AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
629 return;
630 }
631
632 auto* cl = Runtime::Current()->GetClassLinker();
Vladimir Markoba118822017-06-12 15:41:56 +0100633 ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700634 if (constructor == nullptr) {
635 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
636 return;
637 }
638
639 uint32_t args[1];
640 args[0] = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_array.Get()));
641 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
642
643 if (self->IsExceptionPending()) {
644 AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
645 return;
646 }
647
648 result->SetL(h_obj.Get());
649}
650
651void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
652 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
653 {
654 mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
655 CHECK(this_obj != nullptr);
656 CHECK(this_obj->IsClassLoader());
657
658 StackHandleScope<1> hs(self);
659 Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
660
661 if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
662 this_classloader_class.Get()) {
663 AbortTransactionOrFail(self,
David Sehr709b0702016-10-13 09:12:37 -0700664 "Unsupported classloader type %s for getResourceAsStream",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700665 mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700666 return;
667 }
668 }
669
670 GetResourceAsStream(self, shadow_frame, result, arg_offset);
671}
672
Andreas Gampe85bef7e2017-02-16 18:13:26 -0800673void UnstartedRuntime::UnstartedConstructorNewInstance0(
674 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
675 // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
676 StackHandleScope<4> hs(self);
677 Handle<mirror::Constructor> m = hs.NewHandle(
678 reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
679 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
680 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
681 shadow_frame->GetVRegReference(arg_offset + 1)));
682 Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
683 if (UNLIKELY(c->IsAbstract())) {
684 AbortTransactionOrFail(self, "Cannot handle abstract classes");
685 return;
686 }
687 // Verify that we can access the class.
688 if (!m->IsAccessible() && !c->IsPublic()) {
689 // Go 2 frames back, this method is always called from newInstance0, which is called from
690 // Constructor.newInstance(Object... args).
691 ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
692 // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
693 // access checks anyways. TODO: Investigate if this the correct behavior.
694 if (caller != nullptr && !caller->CanAccess(c.Get())) {
695 AbortTransactionOrFail(self, "Cannot access class");
696 return;
697 }
698 }
699 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
700 DCHECK(self->IsExceptionPending());
701 return;
702 }
703 if (c->IsClassClass()) {
704 AbortTransactionOrFail(self, "new Class() is not supported");
705 return;
706 }
707
708 // String constructor is replaced by a StringFactory method in InvokeMethod.
709 if (c->IsStringClass()) {
710 // We don't support strings.
711 AbortTransactionOrFail(self, "String construction is not supported");
712 return;
713 }
714
715 Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
716 if (receiver == nullptr) {
717 AbortTransactionOrFail(self, "Could not allocate");
718 return;
719 }
720
721 // It's easier to use reflection to make the call, than create the uint32_t array.
722 {
723 ScopedObjectAccessUnchecked soa(self);
724 ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
725 soa.AddLocalReference<jobject>(m.Get()));
726 ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
727 soa.AddLocalReference<jobject>(receiver.Get()));
728 ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
729 soa.AddLocalReference<jobject>(args.Get()));
730 InvokeMethod(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
731 }
732 if (self->IsExceptionPending()) {
733 AbortTransactionOrFail(self, "Failed running constructor");
734 } else {
735 result->SetL(receiver.Get());
736 }
737}
738
Andreas Gampe799681b2015-05-15 19:24:12 -0700739void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700740 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700741 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
742 mirror::ClassLoader* class_loader =
743 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
744 StackHandleScope<2> hs(self);
745 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
746 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
747 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
748 "VMClassLoader.findLoadedClass", false, false);
749 // This might have an error pending. But semantics are to just return null.
750 if (self->IsExceptionPending()) {
751 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
David Sehr709b0702016-10-13 09:12:37 -0700752 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700753 if (type != "java.lang.InternalError") {
754 self->ClearException();
755 }
756 }
757}
758
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700759// Arraycopy emulation.
760// Note: we can't use any fast copy functions, as they are not available under transaction.
761
762template <typename T>
763static void PrimitiveArrayCopy(Thread* self,
764 mirror::Array* src_array, int32_t src_pos,
765 mirror::Array* dst_array, int32_t dst_pos,
766 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700767 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700768 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700769 AbortTransactionOrFail(self,
770 "Types mismatched in arraycopy: %s vs %s.",
771 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700772 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700773 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700774 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700775 return;
776 }
777 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
778 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
779 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
780 if (copy_forward) {
781 for (int32_t i = 0; i < length; ++i) {
782 dst->Set(dst_pos + i, src->Get(src_pos + i));
783 }
784 } else {
785 for (int32_t i = 1; i <= length; ++i) {
786 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
787 }
788 }
789}
790
Andreas Gampe799681b2015-05-15 19:24:12 -0700791void UnstartedRuntime::UnstartedSystemArraycopy(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700792 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700793 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700794 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
795 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700796 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700797
Andreas Gampe85a098a2016-03-31 13:30:53 -0700798 mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
799 mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
800 // Null checking. For simplicity, abort transaction.
801 if (src_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700802 AbortTransactionOrFail(self, "src is null in arraycopy.");
803 return;
804 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700805 if (dst_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700806 AbortTransactionOrFail(self, "dst is null in arraycopy.");
807 return;
808 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700809 // Test for arrayness. Throw ArrayStoreException.
810 if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
811 self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
812 return;
813 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700814
Andreas Gampe85a098a2016-03-31 13:30:53 -0700815 mirror::Array* src_array = src_obj->AsArray();
816 mirror::Array* dst_array = dst_obj->AsArray();
817
818 // Bounds checking. Throw IndexOutOfBoundsException.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700819 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
820 UNLIKELY(src_pos > src_array->GetLength() - length) ||
821 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700822 self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700823 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
824 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
825 length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700826 return;
827 }
828
829 // Type checking.
830 mirror::Class* src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
831 GetComponentType();
832
833 if (!src_type->IsPrimitive()) {
834 // Check that the second type is not primitive.
835 mirror::Class* trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
836 GetComponentType();
837 if (trg_type->IsPrimitiveInt()) {
838 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700839 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700840 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700841 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700842 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700843 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700844 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700845
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700846 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
847 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
848 if (src == dst) {
849 // Can overlap, but not have type mismatches.
Andreas Gampe85a098a2016-03-31 13:30:53 -0700850 // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700851 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
852 if (copy_forward) {
853 for (int32_t i = 0; i < length; ++i) {
854 dst->Set(dst_pos + i, src->Get(src_pos + i));
855 }
856 } else {
857 for (int32_t i = 1; i <= length; ++i) {
858 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
859 }
860 }
861 } else {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700862 // We're being lazy here. Optimally this could be a memcpy (if component types are
863 // assignable), but the ObjectArray implementation doesn't support transactions. The
864 // checking version, however, does.
865 if (Runtime::Current()->IsActiveTransaction()) {
866 dst->AssignableCheckingMemcpy<true>(
867 dst_pos, src, src_pos, length, true /* throw_exception */);
868 } else {
869 dst->AssignableCheckingMemcpy<false>(
870 dst_pos, src, src_pos, length, true /* throw_exception */);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700871 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700872 }
Andreas Gampe5c9af612016-04-05 14:16:10 -0700873 } else if (src_type->IsPrimitiveByte()) {
874 PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700875 } else if (src_type->IsPrimitiveChar()) {
876 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
877 } else if (src_type->IsPrimitiveInt()) {
878 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700879 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700880 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700881 src_type->PrettyDescriptor().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700882 }
883}
884
Andreas Gampe5c9af612016-04-05 14:16:10 -0700885void UnstartedRuntime::UnstartedSystemArraycopyByte(
886 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
887 // Just forward.
888 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
889}
890
Andreas Gampe799681b2015-05-15 19:24:12 -0700891void UnstartedRuntime::UnstartedSystemArraycopyChar(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700892 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700893 // Just forward.
894 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
895}
896
897void UnstartedRuntime::UnstartedSystemArraycopyInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700898 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700899 // Just forward.
900 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
901}
902
Narayan Kamath34a316f2016-03-30 13:11:18 +0100903void UnstartedRuntime::UnstartedSystemGetSecurityManager(
904 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
905 JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
906 result->SetL(nullptr);
907}
908
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700909static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
910
911static void GetSystemProperty(Thread* self,
912 ShadowFrame* shadow_frame,
913 JValue* result,
914 size_t arg_offset,
915 bool is_default_version)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700916 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700917 StackHandleScope<4> hs(self);
918 Handle<mirror::String> h_key(
919 hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800920 if (h_key == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700921 AbortTransactionOrFail(self, "getProperty key was null");
922 return;
923 }
924
925 // This is overall inefficient, but reflecting the values here is not great, either. So
926 // for simplicity, and with the assumption that the number of getProperty calls is not
927 // too great, just iterate each time.
928
929 // Get the storage class.
930 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
931 Handle<mirror::Class> h_props_class(hs.NewHandle(
932 class_linker->FindClass(self,
933 "Ljava/lang/AndroidHardcodedSystemProperties;",
934 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800935 if (h_props_class == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700936 AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
937 return;
938 }
939 if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
940 AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
941 return;
942 }
943
944 // Get the storage array.
945 ArtField* static_properties =
946 h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
947 "[[Ljava/lang/String;");
948 if (static_properties == nullptr) {
949 AbortTransactionOrFail(self,
950 "Could not find %s field",
951 kAndroidHardcodedSystemPropertiesFieldName);
952 return;
953 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700954 ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
955 Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
956 props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800957 if (h_2string_array == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700958 AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
959 return;
960 }
961
962 // Iterate over it.
963 const int32_t prop_count = h_2string_array->GetLength();
964 // Use the third handle as mutable.
965 MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
966 hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
967 for (int32_t i = 0; i < prop_count; ++i) {
968 h_string_array.Assign(h_2string_array->Get(i));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800969 if (h_string_array == nullptr ||
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700970 h_string_array->GetLength() != 2 ||
971 h_string_array->Get(0) == nullptr) {
972 AbortTransactionOrFail(self,
973 "Unexpected content of %s",
974 kAndroidHardcodedSystemPropertiesFieldName);
975 return;
976 }
977 if (h_key->Equals(h_string_array->Get(0))) {
978 // Found a value.
979 if (h_string_array->Get(1) == nullptr && is_default_version) {
980 // Null is being delegated to the default map, and then resolved to the given default value.
981 // As there's no default map, return the given value.
982 result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
983 } else {
984 result->SetL(h_string_array->Get(1));
985 }
986 return;
987 }
988 }
989
990 // Key is not supported.
991 AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
992}
993
994void UnstartedRuntime::UnstartedSystemGetProperty(
995 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
996 GetSystemProperty(self, shadow_frame, result, arg_offset, false);
997}
998
999void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
1000 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1001 GetSystemProperty(self, shadow_frame, result, arg_offset, true);
1002}
1003
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001004static std::string GetImmediateCaller(ShadowFrame* shadow_frame)
1005 REQUIRES_SHARED(Locks::mutator_lock_) {
1006 if (shadow_frame->GetLink() == nullptr) {
1007 return "<no caller>";
1008 }
1009 return ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1010}
1011
1012static bool CheckCallers(ShadowFrame* shadow_frame,
1013 std::initializer_list<std::string> allowed_call_stack)
1014 REQUIRES_SHARED(Locks::mutator_lock_) {
1015 for (const std::string& allowed_caller : allowed_call_stack) {
1016 if (shadow_frame->GetLink() == nullptr) {
1017 return false;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001018 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001019
1020 std::string found_caller = ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1021 if (allowed_caller != found_caller) {
1022 return false;
1023 }
1024
1025 shadow_frame = shadow_frame->GetLink();
1026 }
1027 return true;
1028}
1029
1030static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_descriptor)
1031 REQUIRES_SHARED(Locks::mutator_lock_) {
1032 // Find the requested class.
1033 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1034 ObjPtr<mirror::Class> klass =
1035 class_linker->FindClass(self, class_descriptor, ScopedNullHandle<mirror::ClassLoader>());
1036 if (klass == nullptr) {
1037 AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
1038 return nullptr;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001039 }
1040
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001041 StackHandleScope<2> hs(self);
1042 Handle<mirror::Class> h_class(hs.NewHandle(klass));
1043 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001044 if (h_obj != nullptr) {
Vladimir Markoba118822017-06-12 15:41:56 +01001045 ArtMethod* init_method = h_class->FindConstructor("()V", class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001046 if (init_method == nullptr) {
1047 AbortTransactionOrFail(self, "Could not find <init> for %s", class_descriptor);
1048 return nullptr;
1049 } else {
1050 JValue invoke_result;
1051 EnterInterpreterFromInvoke(self, init_method, h_obj.Get(), nullptr, nullptr);
1052 if (!self->IsExceptionPending()) {
1053 return h_obj.Get();
1054 }
1055 AbortTransactionOrFail(self, "Could not run <init> for %s", class_descriptor);
1056 }
1057 }
1058 AbortTransactionOrFail(self, "Could not allocate instance of %s", class_descriptor);
1059 return nullptr;
1060}
1061
1062void UnstartedRuntime::UnstartedThreadLocalGet(
1063 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1064 if (CheckCallers(shadow_frame, { "sun.misc.FloatingDecimal$BinaryToASCIIBuffer "
1065 "sun.misc.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1066 result->SetL(CreateInstanceOf(self, "Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;"));
1067 } else {
1068 AbortTransactionOrFail(self,
1069 "ThreadLocal.get() does not support %s",
1070 GetImmediateCaller(shadow_frame).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001071 }
1072}
1073
Andreas Gampebad529d2017-02-13 18:52:10 -08001074void UnstartedRuntime::UnstartedThreadCurrentThread(
1075 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1076 if (CheckCallers(shadow_frame,
1077 { "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1078 "java.lang.String, long)",
1079 "void java.lang.Thread.<init>()",
1080 "void java.util.logging.LogManager$Cleaner.<init>("
1081 "java.util.logging.LogManager)" })) {
1082 // Whitelist LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
1083 // Thread constructor only asks for the current thread to set up defaults and add the
1084 // thread as unstarted to the ThreadGroup. A faked-up main thread peer is good enough for
1085 // these purposes.
1086 Runtime::Current()->InitThreadGroups(self);
1087 jobject main_peer =
1088 self->CreateCompileTimePeer(self->GetJniEnv(),
1089 "main",
1090 false,
1091 Runtime::Current()->GetMainThreadGroup());
1092 if (main_peer == nullptr) {
1093 AbortTransactionOrFail(self, "Failed allocating peer");
1094 return;
1095 }
1096
1097 result->SetL(self->DecodeJObject(main_peer));
1098 self->GetJniEnv()->DeleteLocalRef(main_peer);
1099 } else {
1100 AbortTransactionOrFail(self,
1101 "Thread.currentThread() does not support %s",
1102 GetImmediateCaller(shadow_frame).c_str());
1103 }
1104}
1105
1106void UnstartedRuntime::UnstartedThreadGetNativeState(
1107 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1108 if (CheckCallers(shadow_frame,
1109 { "java.lang.Thread$State java.lang.Thread.getState()",
1110 "java.lang.ThreadGroup java.lang.Thread.getThreadGroup()",
1111 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1112 "java.lang.String, long)",
1113 "void java.lang.Thread.<init>()",
1114 "void java.util.logging.LogManager$Cleaner.<init>("
1115 "java.util.logging.LogManager)" })) {
1116 // Whitelist reading the state of the "main" thread when creating another (unstarted) thread
1117 // for LogManager. Report the thread as "new" (it really only counts that it isn't terminated).
1118 constexpr int32_t kJavaRunnable = 1;
1119 result->SetI(kJavaRunnable);
1120 } else {
1121 AbortTransactionOrFail(self,
1122 "Thread.getNativeState() does not support %s",
1123 GetImmediateCaller(shadow_frame).c_str());
1124 }
1125}
1126
Sergio Giro83261202016-04-11 20:49:20 +01001127void UnstartedRuntime::UnstartedMathCeil(
1128 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001129 result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
Sergio Giro83261202016-04-11 20:49:20 +01001130}
1131
1132void UnstartedRuntime::UnstartedMathFloor(
1133 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001134 result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001135}
1136
Andreas Gampeb8a00f92016-04-18 20:51:13 -07001137void UnstartedRuntime::UnstartedMathSin(
1138 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1139 result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
1140}
1141
1142void UnstartedRuntime::UnstartedMathCos(
1143 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1144 result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
1145}
1146
1147void UnstartedRuntime::UnstartedMathPow(
1148 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1149 result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
1150 shadow_frame->GetVRegDouble(arg_offset + 2)));
1151}
1152
Andreas Gampe799681b2015-05-15 19:24:12 -07001153void UnstartedRuntime::UnstartedObjectHashCode(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001154 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001155 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1156 result->SetI(obj->IdentityHashCode());
1157}
1158
Andreas Gampe799681b2015-05-15 19:24:12 -07001159void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
Andreas Gampedd9d0552015-03-09 12:57:41 -07001160 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001161 double in = shadow_frame->GetVRegDouble(arg_offset);
Roland Levillainda4d79b2015-03-24 14:36:11 +00001162 result->SetJ(bit_cast<int64_t, double>(in));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001163}
1164
Andreas Gampedd9d0552015-03-09 12:57:41 -07001165static void UnstartedMemoryPeek(
1166 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1167 int64_t address = shadow_frame->GetVRegLong(arg_offset);
1168 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
1169 // aborting the transaction.
1170
1171 switch (type) {
1172 case Primitive::kPrimByte: {
1173 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
1174 return;
1175 }
1176
1177 case Primitive::kPrimShort: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001178 typedef int16_t unaligned_short __attribute__ ((aligned (1)));
1179 result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001180 return;
1181 }
1182
1183 case Primitive::kPrimInt: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001184 typedef int32_t unaligned_int __attribute__ ((aligned (1)));
1185 result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001186 return;
1187 }
1188
1189 case Primitive::kPrimLong: {
Andreas Gampe799681b2015-05-15 19:24:12 -07001190 typedef int64_t unaligned_long __attribute__ ((aligned (1)));
1191 result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001192 return;
1193 }
1194
1195 case Primitive::kPrimBoolean:
1196 case Primitive::kPrimChar:
1197 case Primitive::kPrimFloat:
1198 case Primitive::kPrimDouble:
1199 case Primitive::kPrimVoid:
1200 case Primitive::kPrimNot:
1201 LOG(FATAL) << "Not in the Memory API: " << type;
1202 UNREACHABLE();
1203 }
1204 LOG(FATAL) << "Should not reach here";
1205 UNREACHABLE();
1206}
1207
Andreas Gampe799681b2015-05-15 19:24:12 -07001208void UnstartedRuntime::UnstartedMemoryPeekByte(
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::kPrimByte, shadow_frame, result, arg_offset);
1211}
1212
1213void UnstartedRuntime::UnstartedMemoryPeekShort(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001214 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001215 UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
1216}
1217
1218void UnstartedRuntime::UnstartedMemoryPeekInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001219 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001220 UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
1221}
1222
1223void UnstartedRuntime::UnstartedMemoryPeekLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001224 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001225 UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001226}
1227
1228static void UnstartedMemoryPeekArray(
1229 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001230 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampedd9d0552015-03-09 12:57:41 -07001231 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1232 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1233 if (obj == nullptr) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001234 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
Andreas Gampedd9d0552015-03-09 12:57:41 -07001235 return;
1236 }
1237 mirror::Array* array = obj->AsArray();
1238
1239 int offset = shadow_frame->GetVReg(arg_offset + 3);
1240 int count = shadow_frame->GetVReg(arg_offset + 4);
1241 if (offset < 0 || offset + count > array->GetLength()) {
1242 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
1243 offset, count, array->GetLength()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001244 Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
Andreas Gampedd9d0552015-03-09 12:57:41 -07001245 return;
1246 }
1247
1248 switch (type) {
1249 case Primitive::kPrimByte: {
1250 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
1251 mirror::ByteArray* byte_array = array->AsByteArray();
1252 for (int32_t i = 0; i < count; ++i, ++address) {
1253 byte_array->SetWithoutChecks<true>(i + offset, *address);
1254 }
1255 return;
1256 }
1257
1258 case Primitive::kPrimShort:
1259 case Primitive::kPrimInt:
1260 case Primitive::kPrimLong:
1261 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1262 UNREACHABLE();
1263
1264 case Primitive::kPrimBoolean:
1265 case Primitive::kPrimChar:
1266 case Primitive::kPrimFloat:
1267 case Primitive::kPrimDouble:
1268 case Primitive::kPrimVoid:
1269 case Primitive::kPrimNot:
1270 LOG(FATAL) << "Not in the Memory API: " << type;
1271 UNREACHABLE();
1272 }
1273 LOG(FATAL) << "Should not reach here";
1274 UNREACHABLE();
1275}
1276
Andreas Gampe799681b2015-05-15 19:24:12 -07001277void UnstartedRuntime::UnstartedMemoryPeekByteArray(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001278 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001279 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001280}
1281
Kenny Root1c9e61c2015-05-14 15:58:17 -07001282// This allows reading the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001283void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001284 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001285 jint start = shadow_frame->GetVReg(arg_offset + 1);
1286 jint end = shadow_frame->GetVReg(arg_offset + 2);
1287 jint index = shadow_frame->GetVReg(arg_offset + 4);
1288 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1289 if (string == nullptr) {
1290 AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1291 return;
1292 }
Kenny Root57f91e82015-05-14 15:58:17 -07001293 DCHECK_GE(start, 0);
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001294 DCHECK_LE(start, end);
1295 DCHECK_LE(end, string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001296 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001297 Handle<mirror::CharArray> h_char_array(
1298 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001299 DCHECK_GE(index, 0);
Kenny Root57f91e82015-05-14 15:58:17 -07001300 DCHECK_LE(index, h_char_array->GetLength());
1301 DCHECK_LE(end - start, h_char_array->GetLength() - index);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001302 string->GetChars(start, end, h_char_array, index);
1303}
1304
1305// This allows reading chars from the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001306void UnstartedRuntime::UnstartedStringCharAt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001307 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001308 jint index = shadow_frame->GetVReg(arg_offset + 1);
1309 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1310 if (string == nullptr) {
1311 AbortTransactionOrFail(self, "String.charAt with null object");
1312 return;
1313 }
1314 result->SetC(string->CharAt(index));
1315}
1316
Vladimir Marko92907f32017-02-20 14:08:30 +00001317// This allows creating String objects with replaced characters during compilation.
1318// String.doReplace(char, char) is called from String.replace(char, char) when there is a match.
1319void UnstartedRuntime::UnstartedStringDoReplace(
1320 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1321 jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
1322 jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001323 StackHandleScope<1> hs(self);
1324 Handle<mirror::String> string =
1325 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
Kenny Root57f91e82015-05-14 15:58:17 -07001326 if (string == nullptr) {
Vladimir Marko92907f32017-02-20 14:08:30 +00001327 AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
Kenny Root57f91e82015-05-14 15:58:17 -07001328 return;
1329 }
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001330 result->SetL(mirror::String::DoReplace(self, string, old_c, new_c));
Kenny Root57f91e82015-05-14 15:58:17 -07001331}
1332
Kenny Root1c9e61c2015-05-14 15:58:17 -07001333// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001334void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001335 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001336 jint offset = shadow_frame->GetVReg(arg_offset);
1337 jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1338 DCHECK_GE(char_count, 0);
1339 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001340 Handle<mirror::CharArray> h_char_array(
1341 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
Kenny Root1c9e61c2015-05-14 15:58:17 -07001342 Runtime* runtime = Runtime::Current();
1343 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1344 result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator));
1345}
1346
1347// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001348void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001349 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root57f91e82015-05-14 15:58:17 -07001350 mirror::String* to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1351 if (to_copy == nullptr) {
1352 AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1353 return;
1354 }
1355 StackHandleScope<1> hs(self);
1356 Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1357 Runtime* runtime = Runtime::Current();
1358 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1359 result->SetL(mirror::String::AllocFromString<true>(self, h_string->GetLength(), h_string, 0,
1360 allocator));
1361}
1362
Andreas Gampe799681b2015-05-15 19:24:12 -07001363void UnstartedRuntime::UnstartedStringFastSubstring(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001364 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001365 jint start = shadow_frame->GetVReg(arg_offset + 1);
1366 jint length = shadow_frame->GetVReg(arg_offset + 2);
Kenny Root57f91e82015-05-14 15:58:17 -07001367 DCHECK_GE(start, 0);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001368 DCHECK_GE(length, 0);
1369 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001370 Handle<mirror::String> h_string(
1371 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
Kenny Root57f91e82015-05-14 15:58:17 -07001372 DCHECK_LE(start, h_string->GetLength());
1373 DCHECK_LE(start + length, h_string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001374 Runtime* runtime = Runtime::Current();
1375 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1376 result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator));
1377}
1378
Kenny Root57f91e82015-05-14 15:58:17 -07001379// This allows getting the char array for new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001380void UnstartedRuntime::UnstartedStringToCharArray(
Kenny Root57f91e82015-05-14 15:58:17 -07001381 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001382 REQUIRES_SHARED(Locks::mutator_lock_) {
Kenny Root57f91e82015-05-14 15:58:17 -07001383 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1384 if (string == nullptr) {
1385 AbortTransactionOrFail(self, "String.charAt with null object");
1386 return;
1387 }
1388 result->SetL(string->ToCharArray(self));
1389}
1390
Andreas Gampebc4d2182016-02-22 10:03:12 -08001391// This allows statically initializing ConcurrentHashMap and SynchronousQueue.
1392void UnstartedRuntime::UnstartedReferenceGetReferent(
1393 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001394 ObjPtr<mirror::Reference> const ref = down_cast<mirror::Reference*>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001395 shadow_frame->GetVRegReference(arg_offset));
1396 if (ref == nullptr) {
1397 AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1398 return;
1399 }
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001400 ObjPtr<mirror::Object> const referent =
Andreas Gampebc4d2182016-02-22 10:03:12 -08001401 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1402 result->SetL(referent);
1403}
1404
1405// This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1406// conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1407// where we can predict the behavior (somewhat).
1408// Note: this is required (instead of lazy initialization) as these classes are used in the static
1409// initialization of other classes, so will *use* the value.
1410void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1411 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001412 if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001413 // SynchronousQueue really only separates between single- and multiprocessor case. Return
1414 // 8 as a conservative upper approximation.
1415 result->SetI(8);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001416 } else if (CheckCallers(shadow_frame,
1417 { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001418 // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1419 // a good upper bound.
1420 // TODO: Consider resetting in the zygote?
1421 result->SetI(8);
1422 } else {
1423 // Not supported.
1424 AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1425 }
1426}
1427
1428// This allows accessing ConcurrentHashMap/SynchronousQueue.
1429
1430void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1431 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1432 // Argument 0 is the Unsafe instance, skip.
1433 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1434 if (obj == nullptr) {
1435 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1436 return;
1437 }
1438 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1439 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1440 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001441 bool success;
1442 // Check whether we're in a transaction, call accordingly.
1443 if (Runtime::Current()->IsActiveTransaction()) {
1444 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1445 expectedValue,
1446 newValue);
1447 } else {
1448 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1449 expectedValue,
1450 newValue);
1451 }
1452 result->SetZ(success ? 1 : 0);
1453}
1454
1455void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1456 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1457 // Argument 0 is the Unsafe instance, skip.
1458 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1459 if (obj == nullptr) {
1460 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1461 return;
1462 }
1463 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1464 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1465 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 5);
1466
1467 // Must use non transactional mode.
1468 if (kUseReadBarrier) {
1469 // Need to make sure the reference stored in the field is a to-space one before attempting the
1470 // CAS or the CAS could fail incorrectly.
1471 mirror::HeapReference<mirror::Object>* field_addr =
1472 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1473 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001474 ReadBarrier::Barrier<
1475 mirror::Object,
1476 /* kIsVolatile */ false,
1477 kWithReadBarrier,
1478 /* kAlwaysUpdateField */ true>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001479 obj,
1480 MemberOffset(offset),
1481 field_addr);
1482 }
1483 bool success;
1484 // Check whether we're in a transaction, call accordingly.
1485 if (Runtime::Current()->IsActiveTransaction()) {
1486 success = obj->CasFieldStrongSequentiallyConsistentObject<true>(MemberOffset(offset),
1487 expected_value,
1488 newValue);
1489 } else {
1490 success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
1491 expected_value,
1492 newValue);
1493 }
1494 result->SetZ(success ? 1 : 0);
1495}
1496
1497void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1498 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001499 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001500 // Argument 0 is the Unsafe instance, skip.
1501 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1502 if (obj == nullptr) {
1503 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1504 return;
1505 }
1506 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1507 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1508 result->SetL(value);
1509}
1510
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001511void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1512 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001513 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001514 // Argument 0 is the Unsafe instance, skip.
1515 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1516 if (obj == nullptr) {
1517 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1518 return;
1519 }
1520 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1521 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1522 if (Runtime::Current()->IsActiveTransaction()) {
1523 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1524 } else {
1525 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1526 }
1527}
1528
Andreas Gampebc4d2182016-02-22 10:03:12 -08001529void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1530 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001531 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001532 // Argument 0 is the Unsafe instance, skip.
1533 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1534 if (obj == nullptr) {
1535 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1536 return;
1537 }
1538 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1539 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 4);
1540 QuasiAtomic::ThreadFenceRelease();
1541 if (Runtime::Current()->IsActiveTransaction()) {
1542 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1543 } else {
1544 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1545 }
1546}
1547
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001548// A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1549// of correctly handling the corner cases.
1550void UnstartedRuntime::UnstartedIntegerParseInt(
1551 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001552 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001553 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1554 if (obj == nullptr) {
1555 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1556 return;
1557 }
1558
1559 std::string string_value = obj->AsString()->ToModifiedUtf8();
1560 if (string_value.empty()) {
1561 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1562 return;
1563 }
1564
1565 const char* c_str = string_value.c_str();
1566 char *end;
1567 // Can we set errno to 0? Is this always a variable, and not a macro?
1568 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1569 int64_t l = strtol(c_str, &end, 10);
1570
1571 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1572 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1573 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1574 return;
1575 }
1576 if (l == 0) {
1577 // Check whether the string wasn't exactly zero.
1578 if (string_value != "0") {
1579 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1580 return;
1581 }
1582 } else if (*end != '\0') {
1583 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1584 return;
1585 }
1586
1587 result->SetI(static_cast<int32_t>(l));
1588}
1589
1590// A cutout for Long.parseLong.
1591//
1592// Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1593// well.
1594void UnstartedRuntime::UnstartedLongParseLong(
1595 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001596 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001597 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1598 if (obj == nullptr) {
1599 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1600 return;
1601 }
1602
1603 std::string string_value = obj->AsString()->ToModifiedUtf8();
1604 if (string_value.empty()) {
1605 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1606 return;
1607 }
1608
1609 const char* c_str = string_value.c_str();
1610 char *end;
1611 // Can we set errno to 0? Is this always a variable, and not a macro?
1612 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1613 int64_t l = strtol(c_str, &end, 10);
1614
1615 // Note: comparing against int32_t min/max is intentional here.
1616 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1617 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1618 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1619 return;
1620 }
1621 if (l == 0) {
1622 // Check whether the string wasn't exactly zero.
1623 if (string_value != "0") {
1624 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1625 return;
1626 }
1627 } else if (*end != '\0') {
1628 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1629 return;
1630 }
1631
1632 result->SetJ(l);
1633}
1634
Andreas Gampe715fdc22016-04-18 17:07:30 -07001635void UnstartedRuntime::UnstartedMethodInvoke(
1636 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001637 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe715fdc22016-04-18 17:07:30 -07001638 JNIEnvExt* env = self->GetJniEnv();
1639 ScopedObjectAccessUnchecked soa(self);
1640
Mathieu Chartier8778c522016-10-04 19:06:30 -07001641 ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001642 ScopedLocalRef<jobject> java_method(env,
Roland Levillain5e8d5f02016-10-18 18:03:43 +01001643 java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001644
Mathieu Chartier8778c522016-10-04 19:06:30 -07001645 ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001646 ScopedLocalRef<jobject> java_receiver(env,
1647 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1648
Mathieu Chartier8778c522016-10-04 19:06:30 -07001649 ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001650 ScopedLocalRef<jobject> java_args(env,
1651 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1652
1653 ScopedLocalRef<jobject> result_jobj(env,
1654 InvokeMethod(soa, java_method.get(), java_receiver.get(), java_args.get()));
1655
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001656 result->SetL(self->DecodeJObject(result_jobj.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001657
1658 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1659 // InvocationTargetExceptions.
1660 if (self->IsExceptionPending()) {
1661 AbortTransactionOrFail(self, "Failed Method.invoke");
1662 }
1663}
1664
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001665void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1666 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1667 REQUIRES_SHARED(Locks::mutator_lock_) {
1668 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1669 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1670}
Andreas Gampebc4d2182016-02-22 10:03:12 -08001671
Orion Hodson43f0cdb2017-10-10 14:47:32 +01001672// Checks whether the runtime is s64-bit. This is needed for the clinit of
1673// java.lang.invoke.VarHandle clinit. The clinit determines sets of
1674// available VarHandle accessors and these differ based on machine
1675// word size.
1676void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1677 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1678 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1679 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1680 jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1681 result->SetZ(is64bit);
1682}
1683
Mathieu Chartiere401d142015-04-22 13:56:20 -07001684void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
1685 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1686 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001687 int32_t length = args[1];
1688 DCHECK_GE(length, 0);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001689 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001690 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001691 ObjPtr<mirror::Class> array_class =
1692 runtime->GetClassLinker()->FindArrayClass(self, &element_class);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001693 DCHECK(array_class != nullptr);
1694 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001695 result->SetL(mirror::Array::Alloc<true, true>(self,
1696 array_class,
1697 length,
1698 array_class->GetComponentSizeShift(),
1699 allocator));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001700}
1701
Mathieu Chartiere401d142015-04-22 13:56:20 -07001702void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1703 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1704 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001705 result->SetL(nullptr);
1706}
1707
Mathieu Chartiere401d142015-04-22 13:56:20 -07001708void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1709 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1710 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001711 NthCallerVisitor visitor(self, 3);
1712 visitor.WalkStack();
1713 if (visitor.caller != nullptr) {
1714 result->SetL(visitor.caller->GetDeclaringClass());
1715 }
1716}
1717
Mathieu Chartiere401d142015-04-22 13:56:20 -07001718void UnstartedRuntime::UnstartedJNIMathLog(
1719 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1720 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001721 JValue value;
1722 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1723 result->SetD(log(value.GetD()));
1724}
1725
Mathieu Chartiere401d142015-04-22 13:56:20 -07001726void UnstartedRuntime::UnstartedJNIMathExp(
1727 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1728 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001729 JValue value;
1730 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1731 result->SetD(exp(value.GetD()));
1732}
1733
Andreas Gampebc4d2182016-02-22 10:03:12 -08001734void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1735 Thread* self ATTRIBUTE_UNUSED,
1736 ArtMethod* method ATTRIBUTE_UNUSED,
1737 mirror::Object* receiver ATTRIBUTE_UNUSED,
1738 uint32_t* args ATTRIBUTE_UNUSED,
1739 JValue* result) {
1740 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1741 ? 0
1742 : 1);
1743}
1744
Mathieu Chartiere401d142015-04-22 13:56:20 -07001745void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1746 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1747 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001748 StackHandleScope<1> hs(self);
1749 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1750}
1751
Andreas Gampebc4d2182016-02-22 10:03:12 -08001752void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1753 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1754 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1755 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1756 result->SetD(bit_cast<double>(long_input));
1757}
1758
Mathieu Chartiere401d142015-04-22 13:56:20 -07001759void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1760 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1761 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001762 result->SetI(args[0]);
1763}
1764
Mathieu Chartiere401d142015-04-22 13:56:20 -07001765void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1766 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1767 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001768 result->SetI(args[0]);
1769}
1770
Mathieu Chartiere401d142015-04-22 13:56:20 -07001771void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1772 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1773 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001774 result->SetL(receiver->Clone(self));
1775}
1776
Mathieu Chartiere401d142015-04-22 13:56:20 -07001777void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1778 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1779 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001780 receiver->NotifyAll(self);
1781}
1782
Mathieu Chartiere401d142015-04-22 13:56:20 -07001783void UnstartedRuntime::UnstartedJNIStringCompareTo(
1784 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver, uint32_t* args,
1785 JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001786 mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
1787 if (rhs == nullptr) {
Andreas Gampe068b0c02015-03-11 12:44:47 -07001788 AbortTransactionOrFail(self, "String.compareTo with null object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001789 }
1790 result->SetI(receiver->AsString()->CompareTo(rhs));
1791}
1792
Mathieu Chartiere401d142015-04-22 13:56:20 -07001793void UnstartedRuntime::UnstartedJNIStringIntern(
1794 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1795 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001796 result->SetL(receiver->AsString()->Intern());
1797}
1798
Mathieu Chartiere401d142015-04-22 13:56:20 -07001799void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1800 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1801 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001802 StackHandleScope<2> hs(self);
1803 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1804 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1805 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1806}
1807
Mathieu Chartiere401d142015-04-22 13:56:20 -07001808void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1809 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1810 uint32_t* args, JValue* result) {
Andreas Gampee598e042015-04-10 14:57:10 -07001811 int32_t length = static_cast<int32_t>(args[1]);
1812 if (length < 0) {
1813 ThrowNegativeArraySizeException(length);
1814 return;
1815 }
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001816 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
Andreas Gampee598e042015-04-10 14:57:10 -07001817 Runtime* runtime = Runtime::Current();
1818 ClassLinker* class_linker = runtime->GetClassLinker();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001819 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, &element_class);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001820 if (UNLIKELY(array_class == nullptr)) {
Andreas Gampee598e042015-04-10 14:57:10 -07001821 CHECK(self->IsExceptionPending());
1822 return;
1823 }
1824 DCHECK(array_class->IsObjectArrayClass());
1825 mirror::Array* new_array = mirror::ObjectArray<mirror::Object*>::Alloc(
1826 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1827 result->SetL(new_array);
1828}
1829
Mathieu Chartiere401d142015-04-22 13:56:20 -07001830void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1831 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1832 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001833 ScopedObjectAccessUnchecked soa(self);
1834 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001835 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<true>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001836 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001837 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<false>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001838 }
1839}
1840
Mathieu Chartiere401d142015-04-22 13:56:20 -07001841void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
1842 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1843 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001844 result->SetZ(JNI_TRUE);
1845}
1846
Mathieu Chartiere401d142015-04-22 13:56:20 -07001847void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
1848 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1849 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001850 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1851 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1852 jint expectedValue = args[3];
1853 jint newValue = args[4];
1854 bool success;
1855 if (Runtime::Current()->IsActiveTransaction()) {
1856 success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
1857 expectedValue, newValue);
1858 } else {
1859 success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
1860 expectedValue, newValue);
1861 }
1862 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1863}
1864
Narayan Kamath34a316f2016-03-30 13:11:18 +01001865void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(
1866 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1867 uint32_t* args, JValue* result) {
1868 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1869 if (obj == nullptr) {
1870 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1871 return;
1872 }
1873
1874 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1875 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1876}
1877
Mathieu Chartiere401d142015-04-22 13:56:20 -07001878void UnstartedRuntime::UnstartedJNIUnsafePutObject(
1879 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1880 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001881 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1882 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1883 mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
1884 if (Runtime::Current()->IsActiveTransaction()) {
1885 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1886 } else {
1887 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1888 }
1889}
1890
Andreas Gampe799681b2015-05-15 19:24:12 -07001891void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001892 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1893 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001894 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1895 Primitive::Type primitive_type = component->GetPrimitiveType();
1896 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1897}
1898
Andreas Gampe799681b2015-05-15 19:24:12 -07001899void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001900 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1901 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001902 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1903 Primitive::Type primitive_type = component->GetPrimitiveType();
1904 result->SetI(Primitive::ComponentSize(primitive_type));
1905}
1906
Andreas Gampedd9d0552015-03-09 12:57:41 -07001907typedef void (*InvokeHandler)(Thread* self, ShadowFrame* shadow_frame, JValue* result,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001908 size_t arg_size);
1909
Mathieu Chartiere401d142015-04-22 13:56:20 -07001910typedef void (*JNIHandler)(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001911 uint32_t* args, JValue* result);
1912
1913static bool tables_initialized_ = false;
1914static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
1915static std::unordered_map<std::string, JNIHandler> jni_handlers_;
1916
Andreas Gampe799681b2015-05-15 19:24:12 -07001917void UnstartedRuntime::InitializeInvokeHandlers() {
1918#define UNSTARTED_DIRECT(ShortName, Sig) \
1919 invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
1920#include "unstarted_runtime_list.h"
1921 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
1922#undef UNSTARTED_RUNTIME_DIRECT_LIST
1923#undef UNSTARTED_RUNTIME_JNI_LIST
1924#undef UNSTARTED_DIRECT
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001925}
1926
Andreas Gampe799681b2015-05-15 19:24:12 -07001927void UnstartedRuntime::InitializeJNIHandlers() {
1928#define UNSTARTED_JNI(ShortName, Sig) \
1929 jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
1930#include "unstarted_runtime_list.h"
1931 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
1932#undef UNSTARTED_RUNTIME_DIRECT_LIST
1933#undef UNSTARTED_RUNTIME_JNI_LIST
1934#undef UNSTARTED_JNI
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001935}
1936
Andreas Gampe799681b2015-05-15 19:24:12 -07001937void UnstartedRuntime::Initialize() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001938 CHECK(!tables_initialized_);
1939
Andreas Gampe799681b2015-05-15 19:24:12 -07001940 InitializeInvokeHandlers();
1941 InitializeJNIHandlers();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001942
1943 tables_initialized_ = true;
1944}
1945
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001946void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
Andreas Gampe799681b2015-05-15 19:24:12 -07001947 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001948 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
1949 // problems in core libraries.
1950 CHECK(tables_initialized_);
1951
David Sehr709b0702016-10-13 09:12:37 -07001952 std::string name(ArtMethod::PrettyMethod(shadow_frame->GetMethod()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001953 const auto& iter = invoke_handlers_.find(name);
1954 if (iter != invoke_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001955 // Clear out the result in case it's not zeroed out.
1956 result->SetL(0);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001957
1958 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
1959 self->PushShadowFrame(shadow_frame);
1960
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001961 (*iter->second)(self, shadow_frame, result, arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001962
1963 self->PopShadowFrame();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001964 } else {
1965 // Not special, continue with regular interpreter execution.
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001966 ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001967 }
1968}
1969
1970// 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 -07001971void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe799681b2015-05-15 19:24:12 -07001972 uint32_t* args, JValue* result) {
David Sehr709b0702016-10-13 09:12:37 -07001973 std::string name(ArtMethod::PrettyMethod(method));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001974 const auto& iter = jni_handlers_.find(name);
1975 if (iter != jni_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001976 // Clear out the result in case it's not zeroed out.
1977 result->SetL(0);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001978 (*iter->second)(self, method, receiver, args, result);
1979 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02001980 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
1981 name.c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001982 } else {
David Sehr709b0702016-10-13 09:12:37 -07001983 LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001984 "non-transactional runtime";
1985 }
1986}
1987
1988} // namespace interpreter
1989} // namespace art