blob: eae3fbc9ed71e6ddd145680b01fd97f63ac6d368 [file] [log] [blame]
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "unstarted_runtime.h"
18
Andreas Gampe8ce9c302016-04-15 21:24:28 -070019#include <ctype.h>
Andreas Gampe13fc1be2016-04-05 20:14:30 -070020#include <errno.h>
21#include <stdlib.h>
22
Andreas Gampe2969bcd2015-03-09 12:57:41 -070023#include <cmath>
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -080024#include <initializer_list>
Andreas Gampe13fc1be2016-04-05 20:14:30 -070025#include <limits>
Andreas Gampe8ce9c302016-04-15 21:24:28 -070026#include <locale>
Andreas Gampe2969bcd2015-03-09 12:57:41 -070027#include <unordered_map>
28
Andreas Gampe57943812017-12-06 21:39:13 -080029#include <android-base/logging.h>
30#include <android-base/stringprintf.h>
Andreas Gampeaacc25d2015-04-01 14:49:06 -070031
Mathieu Chartiere401d142015-04-22 13:56:20 -070032#include "art_method-inl.h"
Andreas Gampebc4d2182016-02-22 10:03:12 -080033#include "base/casts.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070034#include "base/enums.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070035#include "base/macros.h"
David Sehrc431b9d2018-03-02 12:01:51 -080036#include "base/quasi_atomic.h"
David Sehr79e26072018-04-06 17:58:50 -070037#include "base/zip_archive.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070038#include "class_linker.h"
39#include "common_throws.h"
David Sehrb2ec9f52018-02-21 13:20:31 -080040#include "dex/descriptors_names.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070041#include "entrypoints/entrypoint_utils-inl.h"
Andreas Gampebc4d2182016-02-22 10:03:12 -080042#include "gc/reference_processor.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070043#include "handle_scope-inl.h"
David Brazdil5a61bb72018-01-19 16:59:46 +000044#include "hidden_api.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070045#include "interpreter/interpreter_common.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070046#include "jvalue-inl.h"
Andreas Gampe8e0f0432018-10-24 13:38:03 -070047#include "mirror/array-alloc-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070048#include "mirror/array-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070049#include "mirror/class.h"
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070050#include "mirror/field-inl.h"
Narayan Kamath14832ef2016-08-05 11:44:32 +010051#include "mirror/method.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070052#include "mirror/object-inl.h"
53#include "mirror/object_array-inl.h"
54#include "mirror/string-inl.h"
Andreas Gampe373a9b52017-10-18 09:01:57 -070055#include "nativehelper/scoped_local_ref.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070056#include "nth_caller_visitor.h"
Andreas Gampe715fdc22016-04-18 17:07:30 -070057#include "reflection.h"
Andreas Gampe513061a2017-06-01 09:17:34 -070058#include "thread-inl.h"
Sebastien Hertz2fd7e692015-04-02 11:11:19 +020059#include "transaction.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070060#include "well_known_classes.h"
61
62namespace art {
63namespace interpreter {
64
Andreas Gampe46ee31b2016-12-14 10:11:49 -080065using android::base::StringAppendV;
66using android::base::StringPrintf;
67
Andreas Gampe068b0c02015-03-11 12:44:47 -070068static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
Sebastien Hertz45b15972015-04-03 16:07:05 +020069 __attribute__((__format__(__printf__, 2, 3)))
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070070 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertz45b15972015-04-03 16:07:05 +020071
72static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
Andreas Gampe068b0c02015-03-11 12:44:47 -070073 va_list args;
Andreas Gampe068b0c02015-03-11 12:44:47 -070074 if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +020075 va_start(args, fmt);
76 AbortTransactionV(self, fmt, args);
Andreas Gampe068b0c02015-03-11 12:44:47 -070077 va_end(args);
78 } else {
Sebastien Hertz45b15972015-04-03 16:07:05 +020079 va_start(args, fmt);
80 std::string msg;
81 StringAppendV(&msg, fmt, args);
82 va_end(args);
83 LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
Andreas Gampe068b0c02015-03-11 12:44:47 -070084 UNREACHABLE();
85 }
86}
87
Andreas Gampe8ce9c302016-04-15 21:24:28 -070088// Restricted support for character upper case / lower case. Only support ASCII, where
89// it's easy. Abort the transaction otherwise.
90static void CharacterLowerUpper(Thread* self,
91 ShadowFrame* shadow_frame,
92 JValue* result,
93 size_t arg_offset,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070094 bool to_lower_case) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8ce9c302016-04-15 21:24:28 -070095 uint32_t int_value = static_cast<uint32_t>(shadow_frame->GetVReg(arg_offset));
96
97 // Only ASCII (7-bit).
98 if (!isascii(int_value)) {
99 AbortTransactionOrFail(self,
100 "Only support ASCII characters for toLowerCase/toUpperCase: %u",
101 int_value);
102 return;
103 }
104
105 std::locale c_locale("C");
106 char char_value = static_cast<char>(int_value);
107
108 if (to_lower_case) {
109 result->SetI(std::tolower(char_value, c_locale));
110 } else {
111 result->SetI(std::toupper(char_value, c_locale));
112 }
113}
114
115void UnstartedRuntime::UnstartedCharacterToLowerCase(
116 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
117 CharacterLowerUpper(self, shadow_frame, result, arg_offset, true);
118}
119
120void UnstartedRuntime::UnstartedCharacterToUpperCase(
121 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
122 CharacterLowerUpper(self, shadow_frame, result, arg_offset, false);
123}
124
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700125// Helper function to deal with class loading in an unstarted runtime.
126static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
127 Handle<mirror::ClassLoader> class_loader, JValue* result,
128 const std::string& method_name, bool initialize_class,
129 bool abort_if_not_found)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700130 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampefa4333d2017-02-14 11:10:34 -0800131 CHECK(className != nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700132 std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
133 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
134
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100135 ObjPtr<mirror::Class> found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700136 if (found == nullptr && abort_if_not_found) {
137 if (!self->IsExceptionPending()) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700138 AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
David Sehr709b0702016-10-13 09:12:37 -0700139 method_name.c_str(),
140 PrettyDescriptor(descriptor.c_str()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700141 }
142 return;
143 }
144 if (found != nullptr && initialize_class) {
145 StackHandleScope<1> hs(self);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100146 HandleWrapperObjPtr<mirror::Class> h_class = hs.NewHandleWrapper(&found);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700147 if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
148 CHECK(self->IsExceptionPending());
149 return;
150 }
151 }
152 result->SetL(found);
153}
154
155// Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
156// rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
157// ClassNotFoundException), so need to do the same. The only exception is if the exception is
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200158// actually the transaction abort exception. This must not be wrapped, as it signals an
159// initialization abort.
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700160static void CheckExceptionGenerateClassNotFound(Thread* self)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700161 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700162 if (self->IsExceptionPending()) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200163 // If it is not the transaction abort exception, wrap it.
David Sehr709b0702016-10-13 09:12:37 -0700164 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200165 if (type != Transaction::kAbortExceptionDescriptor) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700166 self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
167 "ClassNotFoundException");
168 }
169 }
170}
171
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700172static mirror::String* GetClassName(Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700173 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700174 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
175 if (param == nullptr) {
176 AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
177 return nullptr;
178 }
179 return param->AsString();
180}
181
David Brazdila02cb112018-01-31 11:36:39 +0000182template<typename T>
183static ALWAYS_INLINE bool ShouldBlockAccessToMember(T* member, ShadowFrame* frame)
184 REQUIRES_SHARED(Locks::mutator_lock_) {
Narayan Kamathf5f1f802018-04-03 15:23:46 +0100185 // All uses in this file are from reflection
186 constexpr hiddenapi::AccessMethod access_method = hiddenapi::kReflection;
187 return hiddenapi::GetMemberAction(
David Brazdil8ce3bfa2018-03-12 18:01:18 +0000188 member,
189 frame->GetMethod()->GetDeclaringClass()->GetClassLoader(),
David Brazdil8e1a7cb2018-03-27 08:14:25 +0000190 frame->GetMethod()->GetDeclaringClass()->GetDexCache(),
Narayan Kamathf5f1f802018-04-03 15:23:46 +0100191 access_method) == hiddenapi::kDeny;
David Brazdila02cb112018-01-31 11:36:39 +0000192}
193
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800194void UnstartedRuntime::UnstartedClassForNameCommon(Thread* self,
195 ShadowFrame* shadow_frame,
196 JValue* result,
197 size_t arg_offset,
198 bool long_form,
199 const char* caller) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700200 mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
201 if (class_name == nullptr) {
202 return;
203 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800204 bool initialize_class;
205 mirror::ClassLoader* class_loader;
206 if (long_form) {
207 initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
208 class_loader = down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
209 } else {
210 initialize_class = true;
211 // TODO: This is really only correct for the boot classpath, and for robustness we should
212 // check the caller.
213 class_loader = nullptr;
214 }
215
216 ScopedObjectAccessUnchecked soa(self);
217 if (class_loader != nullptr && !ClassLinker::IsBootClassLoader(soa, class_loader)) {
218 AbortTransactionOrFail(self,
219 "Only the boot classloader is supported: %s",
220 mirror::Object::PrettyTypeOf(class_loader).c_str());
221 return;
222 }
223
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700224 StackHandleScope<1> hs(self);
225 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800226 UnstartedRuntimeFindClass(self,
227 h_class_name,
228 ScopedNullHandle<mirror::ClassLoader>(),
229 result,
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800230 caller,
231 initialize_class,
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800232 false);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700233 CheckExceptionGenerateClassNotFound(self);
234}
235
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800236void UnstartedRuntime::UnstartedClassForName(
237 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
238 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, false, "Class.forName");
239}
240
Andreas Gampe799681b2015-05-15 19:24:12 -0700241void UnstartedRuntime::UnstartedClassForNameLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700242 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800243 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.forName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700244}
245
Vladimir Marko7287c4d2018-02-15 10:41:07 +0000246void UnstartedRuntime::UnstartedClassGetPrimitiveClass(
247 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
248 ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
249 ObjPtr<mirror::Class> klass = mirror::Class::GetPrimitiveClass(class_name);
250 if (UNLIKELY(klass == nullptr)) {
251 DCHECK(self->IsExceptionPending());
252 AbortTransactionOrFail(self,
253 "Class.getPrimitiveClass() failed: %s",
254 self->GetException()->GetDetailMessage()->ToModifiedUtf8().c_str());
255 return;
256 }
257 result->SetL(klass);
258}
259
Andreas Gampe799681b2015-05-15 19:24:12 -0700260void UnstartedRuntime::UnstartedClassClassForName(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700261 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -0800262 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.classForName");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700263}
264
Andreas Gampe799681b2015-05-15 19:24:12 -0700265void UnstartedRuntime::UnstartedClassNewInstance(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700266 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
267 StackHandleScope<2> hs(self); // Class, constructor, object.
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700268 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
269 if (param == nullptr) {
270 AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
271 return;
272 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100273 Handle<mirror::Class> h_klass(hs.NewHandle(param->AsClass()));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700274
275 // Check that it's not null.
Andreas Gampefa4333d2017-02-14 11:10:34 -0800276 if (h_klass == nullptr) {
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700277 AbortTransactionOrFail(self, "Class reference is null for newInstance");
278 return;
279 }
280
281 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
282 if (Runtime::Current()->IsActiveTransaction()) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100283 if (h_klass->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200284 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700285 h_klass->PrettyClass().c_str());
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700286 return;
287 }
288 }
289
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700290 // There are two situations in which we'll abort this run.
291 // 1) If the class isn't yet initialized and initialization fails.
292 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
293 // Note that 2) could likely be handled here, but for safety abort the transaction.
294 bool ok = false;
Mathieu Chartiere401d142015-04-22 13:56:20 -0700295 auto* cl = Runtime::Current()->GetClassLinker();
296 if (cl->EnsureInitialized(self, h_klass, true, true)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000297 ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
David Brazdila02cb112018-01-31 11:36:39 +0000298 if (cons != nullptr && ShouldBlockAccessToMember(cons, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000299 cons = nullptr;
300 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700301 if (cons != nullptr) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100302 Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800303 CHECK(h_obj != nullptr); // We don't expect OOM at compile-time.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700304 EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700305 if (!self->IsExceptionPending()) {
306 result->SetL(h_obj.Get());
307 ok = true;
308 }
309 } else {
310 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
311 "Could not find default constructor for '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700312 h_klass->PrettyClass().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700313 }
314 }
315 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700316 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
David Sehr709b0702016-10-13 09:12:37 -0700317 h_klass->PrettyClass().c_str(),
318 mirror::Object::PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700319 }
320}
321
Andreas Gampe799681b2015-05-15 19:24:12 -0700322void UnstartedRuntime::UnstartedClassGetDeclaredField(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700323 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700324 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
325 // going the reflective Dex way.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100326 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
327 ObjPtr<mirror::String> name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700328 ArtField* found = nullptr;
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700329 for (ArtField& field : klass->GetIFields()) {
330 if (name2->Equals(field.GetName())) {
331 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700332 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700333 }
334 }
335 if (found == nullptr) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700336 for (ArtField& field : klass->GetSFields()) {
337 if (name2->Equals(field.GetName())) {
338 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700339 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700340 }
341 }
342 }
David Brazdila02cb112018-01-31 11:36:39 +0000343 if (found != nullptr && ShouldBlockAccessToMember(found, shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000344 found = nullptr;
345 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700346 if (found == nullptr) {
347 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
348 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
David Sehr709b0702016-10-13 09:12:37 -0700349 klass->PrettyDescriptor().c_str());
Andreas Gampe068b0c02015-03-11 12:44:47 -0700350 return;
351 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700352 Runtime* runtime = Runtime::Current();
Andreas Gampe542451c2016-07-26 09:02:02 -0700353 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Andreas Gampee01e3642016-07-25 13:06:04 -0700354 mirror::Field* field;
355 if (runtime->IsActiveTransaction()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700356 if (pointer_size == PointerSize::k64) {
357 field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
358 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700359 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700360 field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
361 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700362 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700363 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700364 if (pointer_size == PointerSize::k64) {
365 field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
366 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700367 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700368 field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
369 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700370 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700371 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700372 result->SetL(field);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700373}
374
Andreas Gampebc4d2182016-02-22 10:03:12 -0800375// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
376void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
377 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
378 // Special managed code cut-out to allow method lookup in a un-started runtime.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100379 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
Andreas Gampebc4d2182016-02-22 10:03:12 -0800380 if (klass == nullptr) {
381 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
382 return;
383 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100384 ObjPtr<mirror::String> name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
385 ObjPtr<mirror::ObjectArray<mirror::Class>> args =
Andreas Gampebc4d2182016-02-22 10:03:12 -0800386 shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700387 Runtime* runtime = Runtime::Current();
388 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700389 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700390 ObjPtr<mirror::Method> method;
Andreas Gampee01e3642016-07-25 13:06:04 -0700391 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700392 if (pointer_size == PointerSize::k64) {
393 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
394 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700395 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700396 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
397 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700398 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800399 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700400 if (pointer_size == PointerSize::k64) {
401 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
402 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700403 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700404 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
405 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700406 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800407 }
David Brazdila02cb112018-01-31 11:36:39 +0000408 if (method != nullptr && ShouldBlockAccessToMember(method->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000409 method = nullptr;
410 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700411 result->SetL(method);
Andreas Gampebc4d2182016-02-22 10:03:12 -0800412}
413
Andreas Gampe6039e562016-04-05 18:18:43 -0700414// Special managed code cut-out to allow constructor lookup in a un-started runtime.
415void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
416 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100417 ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
Andreas Gampe6039e562016-04-05 18:18:43 -0700418 if (klass == nullptr) {
419 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
420 return;
421 }
422 mirror::ObjectArray<mirror::Class>* args =
423 shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700424 Runtime* runtime = Runtime::Current();
425 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700426 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700427 ObjPtr<mirror::Constructor> constructor;
Andreas Gampee01e3642016-07-25 13:06:04 -0700428 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700429 if (pointer_size == PointerSize::k64) {
430 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
431 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700432 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700433 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
434 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700435 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700436 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700437 if (pointer_size == PointerSize::k64) {
438 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
439 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700440 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700441 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
442 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700443 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700444 }
David Brazdil5a61bb72018-01-19 16:59:46 +0000445 if (constructor != nullptr &&
David Brazdila02cb112018-01-31 11:36:39 +0000446 ShouldBlockAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
David Brazdil5a61bb72018-01-19 16:59:46 +0000447 constructor = nullptr;
448 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700449 result->SetL(constructor);
Andreas Gampe6039e562016-04-05 18:18:43 -0700450}
451
Andreas Gampeae78c262017-02-01 20:40:44 -0800452void UnstartedRuntime::UnstartedClassGetDeclaringClass(
453 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
454 StackHandleScope<1> hs(self);
455 Handle<mirror::Class> klass(hs.NewHandle(
456 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
457 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
458 result->SetL(nullptr);
459 return;
460 }
461 // Return null for anonymous classes.
462 JValue is_anon_result;
463 UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
464 if (is_anon_result.GetZ() != 0) {
465 result->SetL(nullptr);
466 return;
467 }
468 result->SetL(annotations::GetDeclaringClass(klass));
469}
470
Andreas Gampe633750c2016-02-19 10:49:50 -0800471void UnstartedRuntime::UnstartedClassGetEnclosingClass(
472 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
473 StackHandleScope<1> hs(self);
474 Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
475 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
476 result->SetL(nullptr);
477 }
David Sehr9323e6e2016-09-13 08:58:35 -0700478 result->SetL(annotations::GetEnclosingClass(klass));
Andreas Gampe633750c2016-02-19 10:49:50 -0800479}
480
Andreas Gampe715fdc22016-04-18 17:07:30 -0700481void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
482 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
483 StackHandleScope<1> hs(self);
484 Handle<mirror::Class> klass(hs.NewHandle(
485 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
486 const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
487 result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
488}
489
Andreas Gampe9486a162017-02-16 15:17:47 -0800490void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
491 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
492 StackHandleScope<1> hs(self);
493 Handle<mirror::Class> klass(hs.NewHandle(
494 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
495
496 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
497 result->SetL(nullptr);
498 return;
499 }
500
501 result->SetL(annotations::GetSignatureAnnotationForClass(klass));
502}
503
Andreas Gampeae78c262017-02-01 20:40:44 -0800504void UnstartedRuntime::UnstartedClassIsAnonymousClass(
505 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
506 StackHandleScope<1> hs(self);
507 Handle<mirror::Class> klass(hs.NewHandle(
508 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
509 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
510 result->SetZ(false);
511 return;
512 }
Vladimir Marko2d3065e2018-05-22 13:56:09 +0100513 ObjPtr<mirror::String> class_name = nullptr;
Andreas Gampeae78c262017-02-01 20:40:44 -0800514 if (!annotations::GetInnerClass(klass, &class_name)) {
515 result->SetZ(false);
516 return;
517 }
518 result->SetZ(class_name == nullptr);
519}
520
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100521static MemMap FindAndExtractEntry(const std::string& jar_file,
522 const char* entry_name,
523 size_t* size,
524 std::string* error_msg) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700525 CHECK(size != nullptr);
526
527 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
528 if (zip_archive == nullptr) {
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100529 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700530 }
531 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
532 if (zip_entry == nullptr) {
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100533 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700534 }
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100535 MemMap tmp_map = zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg);
536 if (!tmp_map.IsValid()) {
537 return MemMap::Invalid();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700538 }
539
540 // OK, from here everything seems fine.
541 *size = zip_entry->GetUncompressedLength();
542 return tmp_map;
543}
544
545static void GetResourceAsStream(Thread* self,
546 ShadowFrame* shadow_frame,
547 JValue* result,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700548 size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700549 mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
550 if (resource_obj == nullptr) {
551 AbortTransactionOrFail(self, "null name for getResourceAsStream");
552 return;
553 }
554 CHECK(resource_obj->IsString());
555 mirror::String* resource_name = resource_obj->AsString();
556
557 std::string resource_name_str = resource_name->ToModifiedUtf8();
558 if (resource_name_str.empty() || resource_name_str == "/") {
559 AbortTransactionOrFail(self,
560 "Unsupported name %s for getResourceAsStream",
561 resource_name_str.c_str());
562 return;
563 }
564 const char* resource_cstr = resource_name_str.c_str();
565 if (resource_cstr[0] == '/') {
566 resource_cstr++;
567 }
568
569 Runtime* runtime = Runtime::Current();
570
571 std::vector<std::string> split;
572 Split(runtime->GetBootClassPathString(), ':', &split);
573 if (split.empty()) {
574 AbortTransactionOrFail(self,
575 "Boot classpath not set or split error:: %s",
576 runtime->GetBootClassPathString().c_str());
577 return;
578 }
579
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100580 MemMap mem_map;
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700581 size_t map_size;
582 std::string last_error_msg; // Only store the last message (we could concatenate).
583
584 for (const std::string& jar_file : split) {
585 mem_map = FindAndExtractEntry(jar_file, resource_cstr, &map_size, &last_error_msg);
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100586 if (mem_map.IsValid()) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700587 break;
588 }
589 }
590
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100591 if (!mem_map.IsValid()) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700592 // Didn't find it. There's a good chance this will be the same at runtime, but still
593 // conservatively abort the transaction here.
594 AbortTransactionOrFail(self,
595 "Could not find resource %s. Last error was %s.",
596 resource_name_str.c_str(),
597 last_error_msg.c_str());
598 return;
599 }
600
601 StackHandleScope<3> hs(self);
602
603 // Create byte array for content.
604 Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800605 if (h_array == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700606 AbortTransactionOrFail(self, "Could not find/create byte array class");
607 return;
608 }
609 // Copy in content.
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100610 memcpy(h_array->GetData(), mem_map.Begin(), map_size);
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700611 // Be proactive releasing memory.
Vladimir Markoc34bebf2018-08-16 16:12:49 +0100612 mem_map.Reset();
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700613
614 // Create a ByteArrayInputStream.
615 Handle<mirror::Class> h_class(hs.NewHandle(
616 runtime->GetClassLinker()->FindClass(self,
617 "Ljava/io/ByteArrayInputStream;",
618 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800619 if (h_class == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700620 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
621 return;
622 }
623 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
624 AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
625 return;
626 }
627
628 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800629 if (h_obj == nullptr) {
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700630 AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
631 return;
632 }
633
634 auto* cl = Runtime::Current()->GetClassLinker();
Vladimir Markoba118822017-06-12 15:41:56 +0100635 ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700636 if (constructor == nullptr) {
637 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
638 return;
639 }
640
641 uint32_t args[1];
Vladimir Marko78baed52018-10-11 10:44:58 +0100642 args[0] = reinterpret_cast32<uint32_t>(h_array.Get());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700643 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
644
645 if (self->IsExceptionPending()) {
646 AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
647 return;
648 }
649
650 result->SetL(h_obj.Get());
651}
652
653void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
654 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
655 {
656 mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
657 CHECK(this_obj != nullptr);
658 CHECK(this_obj->IsClassLoader());
659
660 StackHandleScope<1> hs(self);
661 Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
662
663 if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
664 this_classloader_class.Get()) {
665 AbortTransactionOrFail(self,
David Sehr709b0702016-10-13 09:12:37 -0700666 "Unsupported classloader type %s for getResourceAsStream",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700667 mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700668 return;
669 }
670 }
671
672 GetResourceAsStream(self, shadow_frame, result, arg_offset);
673}
674
Andreas Gampe85bef7e2017-02-16 18:13:26 -0800675void UnstartedRuntime::UnstartedConstructorNewInstance0(
676 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
677 // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
678 StackHandleScope<4> hs(self);
679 Handle<mirror::Constructor> m = hs.NewHandle(
680 reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
681 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
682 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
683 shadow_frame->GetVRegReference(arg_offset + 1)));
684 Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
685 if (UNLIKELY(c->IsAbstract())) {
686 AbortTransactionOrFail(self, "Cannot handle abstract classes");
687 return;
688 }
689 // Verify that we can access the class.
690 if (!m->IsAccessible() && !c->IsPublic()) {
691 // Go 2 frames back, this method is always called from newInstance0, which is called from
692 // Constructor.newInstance(Object... args).
693 ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
694 // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
695 // access checks anyways. TODO: Investigate if this the correct behavior.
696 if (caller != nullptr && !caller->CanAccess(c.Get())) {
697 AbortTransactionOrFail(self, "Cannot access class");
698 return;
699 }
700 }
701 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
702 DCHECK(self->IsExceptionPending());
703 return;
704 }
705 if (c->IsClassClass()) {
706 AbortTransactionOrFail(self, "new Class() is not supported");
707 return;
708 }
709
710 // String constructor is replaced by a StringFactory method in InvokeMethod.
711 if (c->IsStringClass()) {
712 // We don't support strings.
713 AbortTransactionOrFail(self, "String construction is not supported");
714 return;
715 }
716
717 Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
718 if (receiver == nullptr) {
719 AbortTransactionOrFail(self, "Could not allocate");
720 return;
721 }
722
723 // It's easier to use reflection to make the call, than create the uint32_t array.
724 {
725 ScopedObjectAccessUnchecked soa(self);
726 ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
727 soa.AddLocalReference<jobject>(m.Get()));
728 ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
729 soa.AddLocalReference<jobject>(receiver.Get()));
730 ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
731 soa.AddLocalReference<jobject>(args.Get()));
732 InvokeMethod(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
733 }
734 if (self->IsExceptionPending()) {
735 AbortTransactionOrFail(self, "Failed running constructor");
736 } else {
737 result->SetL(receiver.Get());
738 }
739}
740
Andreas Gampe799681b2015-05-15 19:24:12 -0700741void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700742 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700743 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
744 mirror::ClassLoader* class_loader =
745 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
746 StackHandleScope<2> hs(self);
747 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
748 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
749 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
750 "VMClassLoader.findLoadedClass", false, false);
751 // This might have an error pending. But semantics are to just return null.
752 if (self->IsExceptionPending()) {
753 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
David Sehr709b0702016-10-13 09:12:37 -0700754 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700755 if (type != "java.lang.InternalError") {
756 self->ClearException();
757 }
758 }
759}
760
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700761// Arraycopy emulation.
762// Note: we can't use any fast copy functions, as they are not available under transaction.
763
764template <typename T>
765static void PrimitiveArrayCopy(Thread* self,
766 mirror::Array* src_array, int32_t src_pos,
767 mirror::Array* dst_array, int32_t dst_pos,
768 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700769 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700770 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700771 AbortTransactionOrFail(self,
772 "Types mismatched in arraycopy: %s vs %s.",
773 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700774 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700775 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700776 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700777 return;
778 }
779 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
780 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
781 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
782 if (copy_forward) {
783 for (int32_t i = 0; i < length; ++i) {
784 dst->Set(dst_pos + i, src->Get(src_pos + i));
785 }
786 } else {
787 for (int32_t i = 1; i <= length; ++i) {
788 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
789 }
790 }
791}
792
Andreas Gampe799681b2015-05-15 19:24:12 -0700793void UnstartedRuntime::UnstartedSystemArraycopy(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700794 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700795 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700796 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
797 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700798 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700799
Andreas Gampe85a098a2016-03-31 13:30:53 -0700800 mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
801 mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
802 // Null checking. For simplicity, abort transaction.
803 if (src_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700804 AbortTransactionOrFail(self, "src is null in arraycopy.");
805 return;
806 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700807 if (dst_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700808 AbortTransactionOrFail(self, "dst is null in arraycopy.");
809 return;
810 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700811 // Test for arrayness. Throw ArrayStoreException.
812 if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
813 self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
814 return;
815 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700816
Andreas Gampe85a098a2016-03-31 13:30:53 -0700817 mirror::Array* src_array = src_obj->AsArray();
818 mirror::Array* dst_array = dst_obj->AsArray();
819
820 // Bounds checking. Throw IndexOutOfBoundsException.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700821 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
822 UNLIKELY(src_pos > src_array->GetLength() - length) ||
823 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700824 self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700825 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
826 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
827 length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700828 return;
829 }
830
831 // Type checking.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100832 ObjPtr<mirror::Class> src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700833 GetComponentType();
834
835 if (!src_type->IsPrimitive()) {
836 // Check that the second type is not primitive.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100837 ObjPtr<mirror::Class> trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700838 GetComponentType();
839 if (trg_type->IsPrimitiveInt()) {
840 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
Mathieu Chartieref41db72016-10-25 15:08:01 -0700841 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700842 src_array->GetClass()->GetComponentType()).c_str(),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700843 mirror::Class::PrettyDescriptor(
David Sehr709b0702016-10-13 09:12:37 -0700844 dst_array->GetClass()->GetComponentType()).c_str());
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700845 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700846 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700847
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700848 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
849 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
850 if (src == dst) {
851 // Can overlap, but not have type mismatches.
Andreas Gampe85a098a2016-03-31 13:30:53 -0700852 // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700853 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
854 if (copy_forward) {
855 for (int32_t i = 0; i < length; ++i) {
856 dst->Set(dst_pos + i, src->Get(src_pos + i));
857 }
858 } else {
859 for (int32_t i = 1; i <= length; ++i) {
860 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
861 }
862 }
863 } else {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700864 // We're being lazy here. Optimally this could be a memcpy (if component types are
865 // assignable), but the ObjectArray implementation doesn't support transactions. The
866 // checking version, however, does.
867 if (Runtime::Current()->IsActiveTransaction()) {
868 dst->AssignableCheckingMemcpy<true>(
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700869 dst_pos, src, src_pos, length, /* throw_exception= */ true);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700870 } else {
871 dst->AssignableCheckingMemcpy<false>(
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700872 dst_pos, src, src_pos, length, /* throw_exception= */ true);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700873 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700874 }
Andreas Gampe5c9af612016-04-05 14:16:10 -0700875 } else if (src_type->IsPrimitiveByte()) {
876 PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700877 } else if (src_type->IsPrimitiveChar()) {
878 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
879 } else if (src_type->IsPrimitiveInt()) {
880 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700881 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700882 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
David Sehr709b0702016-10-13 09:12:37 -0700883 src_type->PrettyDescriptor().c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700884 }
885}
886
Andreas Gampe5c9af612016-04-05 14:16:10 -0700887void UnstartedRuntime::UnstartedSystemArraycopyByte(
888 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
889 // Just forward.
890 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
891}
892
Andreas Gampe799681b2015-05-15 19:24:12 -0700893void UnstartedRuntime::UnstartedSystemArraycopyChar(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700894 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700895 // Just forward.
896 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
897}
898
899void UnstartedRuntime::UnstartedSystemArraycopyInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700900 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700901 // Just forward.
902 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
903}
904
Narayan Kamath34a316f2016-03-30 13:11:18 +0100905void UnstartedRuntime::UnstartedSystemGetSecurityManager(
906 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
907 JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
908 result->SetL(nullptr);
909}
910
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700911static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
912
913static void GetSystemProperty(Thread* self,
914 ShadowFrame* shadow_frame,
915 JValue* result,
916 size_t arg_offset,
917 bool is_default_version)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700918 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700919 StackHandleScope<4> hs(self);
920 Handle<mirror::String> h_key(
921 hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800922 if (h_key == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700923 AbortTransactionOrFail(self, "getProperty key was null");
924 return;
925 }
926
927 // This is overall inefficient, but reflecting the values here is not great, either. So
928 // for simplicity, and with the assumption that the number of getProperty calls is not
929 // too great, just iterate each time.
930
931 // Get the storage class.
932 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
933 Handle<mirror::Class> h_props_class(hs.NewHandle(
934 class_linker->FindClass(self,
935 "Ljava/lang/AndroidHardcodedSystemProperties;",
936 ScopedNullHandle<mirror::ClassLoader>())));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800937 if (h_props_class == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700938 AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
939 return;
940 }
941 if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
942 AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
943 return;
944 }
945
946 // Get the storage array.
947 ArtField* static_properties =
948 h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
949 "[[Ljava/lang/String;");
950 if (static_properties == nullptr) {
951 AbortTransactionOrFail(self,
952 "Could not find %s field",
953 kAndroidHardcodedSystemPropertiesFieldName);
954 return;
955 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700956 ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
957 Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
958 props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800959 if (h_2string_array == nullptr) {
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700960 AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
961 return;
962 }
963
964 // Iterate over it.
965 const int32_t prop_count = h_2string_array->GetLength();
966 // Use the third handle as mutable.
967 MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
968 hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
969 for (int32_t i = 0; i < prop_count; ++i) {
970 h_string_array.Assign(h_2string_array->Get(i));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800971 if (h_string_array == nullptr ||
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700972 h_string_array->GetLength() != 2 ||
973 h_string_array->Get(0) == nullptr) {
974 AbortTransactionOrFail(self,
975 "Unexpected content of %s",
976 kAndroidHardcodedSystemPropertiesFieldName);
977 return;
978 }
979 if (h_key->Equals(h_string_array->Get(0))) {
980 // Found a value.
981 if (h_string_array->Get(1) == nullptr && is_default_version) {
982 // Null is being delegated to the default map, and then resolved to the given default value.
983 // As there's no default map, return the given value.
984 result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
985 } else {
986 result->SetL(h_string_array->Get(1));
987 }
988 return;
989 }
990 }
991
992 // Key is not supported.
993 AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
994}
995
996void UnstartedRuntime::UnstartedSystemGetProperty(
997 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
998 GetSystemProperty(self, shadow_frame, result, arg_offset, false);
999}
1000
1001void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
1002 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1003 GetSystemProperty(self, shadow_frame, result, arg_offset, true);
1004}
1005
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001006static std::string GetImmediateCaller(ShadowFrame* shadow_frame)
1007 REQUIRES_SHARED(Locks::mutator_lock_) {
1008 if (shadow_frame->GetLink() == nullptr) {
1009 return "<no caller>";
1010 }
1011 return ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1012}
1013
1014static bool CheckCallers(ShadowFrame* shadow_frame,
1015 std::initializer_list<std::string> allowed_call_stack)
1016 REQUIRES_SHARED(Locks::mutator_lock_) {
1017 for (const std::string& allowed_caller : allowed_call_stack) {
1018 if (shadow_frame->GetLink() == nullptr) {
1019 return false;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001020 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001021
1022 std::string found_caller = ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1023 if (allowed_caller != found_caller) {
1024 return false;
1025 }
1026
1027 shadow_frame = shadow_frame->GetLink();
1028 }
1029 return true;
1030}
1031
1032static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_descriptor)
1033 REQUIRES_SHARED(Locks::mutator_lock_) {
1034 // Find the requested class.
1035 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1036 ObjPtr<mirror::Class> klass =
1037 class_linker->FindClass(self, class_descriptor, ScopedNullHandle<mirror::ClassLoader>());
1038 if (klass == nullptr) {
1039 AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
1040 return nullptr;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001041 }
1042
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001043 StackHandleScope<2> hs(self);
1044 Handle<mirror::Class> h_class(hs.NewHandle(klass));
1045 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001046 if (h_obj != nullptr) {
Vladimir Markoba118822017-06-12 15:41:56 +01001047 ArtMethod* init_method = h_class->FindConstructor("()V", class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001048 if (init_method == nullptr) {
1049 AbortTransactionOrFail(self, "Could not find <init> for %s", class_descriptor);
1050 return nullptr;
1051 } else {
1052 JValue invoke_result;
1053 EnterInterpreterFromInvoke(self, init_method, h_obj.Get(), nullptr, nullptr);
1054 if (!self->IsExceptionPending()) {
1055 return h_obj.Get();
1056 }
1057 AbortTransactionOrFail(self, "Could not run <init> for %s", class_descriptor);
1058 }
1059 }
1060 AbortTransactionOrFail(self, "Could not allocate instance of %s", class_descriptor);
1061 return nullptr;
1062}
1063
1064void UnstartedRuntime::UnstartedThreadLocalGet(
1065 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1066 if (CheckCallers(shadow_frame, { "sun.misc.FloatingDecimal$BinaryToASCIIBuffer "
1067 "sun.misc.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1068 result->SetL(CreateInstanceOf(self, "Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;"));
1069 } else {
1070 AbortTransactionOrFail(self,
1071 "ThreadLocal.get() does not support %s",
1072 GetImmediateCaller(shadow_frame).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001073 }
1074}
1075
Andreas Gampebad529d2017-02-13 18:52:10 -08001076void UnstartedRuntime::UnstartedThreadCurrentThread(
1077 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1078 if (CheckCallers(shadow_frame,
1079 { "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
Paul Duffin7ec95c52018-08-01 15:09:37 +01001080 "java.lang.String, long, java.security.AccessControlContext)",
1081 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
Andreas Gampebad529d2017-02-13 18:52:10 -08001082 "java.lang.String, long)",
1083 "void java.lang.Thread.<init>()",
1084 "void java.util.logging.LogManager$Cleaner.<init>("
1085 "java.util.logging.LogManager)" })) {
1086 // Whitelist LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
1087 // Thread constructor only asks for the current thread to set up defaults and add the
1088 // thread as unstarted to the ThreadGroup. A faked-up main thread peer is good enough for
1089 // these purposes.
1090 Runtime::Current()->InitThreadGroups(self);
1091 jobject main_peer =
1092 self->CreateCompileTimePeer(self->GetJniEnv(),
1093 "main",
1094 false,
1095 Runtime::Current()->GetMainThreadGroup());
1096 if (main_peer == nullptr) {
1097 AbortTransactionOrFail(self, "Failed allocating peer");
1098 return;
1099 }
1100
1101 result->SetL(self->DecodeJObject(main_peer));
1102 self->GetJniEnv()->DeleteLocalRef(main_peer);
1103 } else {
1104 AbortTransactionOrFail(self,
1105 "Thread.currentThread() does not support %s",
1106 GetImmediateCaller(shadow_frame).c_str());
1107 }
1108}
1109
1110void UnstartedRuntime::UnstartedThreadGetNativeState(
1111 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1112 if (CheckCallers(shadow_frame,
1113 { "java.lang.Thread$State java.lang.Thread.getState()",
1114 "java.lang.ThreadGroup java.lang.Thread.getThreadGroup()",
1115 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
Paul Duffin7ec95c52018-08-01 15:09:37 +01001116 "java.lang.String, long, java.security.AccessControlContext)",
1117 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
Andreas Gampebad529d2017-02-13 18:52:10 -08001118 "java.lang.String, long)",
1119 "void java.lang.Thread.<init>()",
1120 "void java.util.logging.LogManager$Cleaner.<init>("
1121 "java.util.logging.LogManager)" })) {
1122 // Whitelist reading the state of the "main" thread when creating another (unstarted) thread
1123 // for LogManager. Report the thread as "new" (it really only counts that it isn't terminated).
1124 constexpr int32_t kJavaRunnable = 1;
1125 result->SetI(kJavaRunnable);
1126 } else {
1127 AbortTransactionOrFail(self,
1128 "Thread.getNativeState() does not support %s",
1129 GetImmediateCaller(shadow_frame).c_str());
1130 }
1131}
1132
Sergio Giro83261202016-04-11 20:49:20 +01001133void UnstartedRuntime::UnstartedMathCeil(
1134 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001135 result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
Sergio Giro83261202016-04-11 20:49:20 +01001136}
1137
1138void UnstartedRuntime::UnstartedMathFloor(
1139 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -07001140 result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001141}
1142
Andreas Gampeb8a00f92016-04-18 20:51:13 -07001143void UnstartedRuntime::UnstartedMathSin(
1144 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1145 result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
1146}
1147
1148void UnstartedRuntime::UnstartedMathCos(
1149 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1150 result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
1151}
1152
1153void UnstartedRuntime::UnstartedMathPow(
1154 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1155 result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
1156 shadow_frame->GetVRegDouble(arg_offset + 2)));
1157}
1158
Andreas Gampe799681b2015-05-15 19:24:12 -07001159void UnstartedRuntime::UnstartedObjectHashCode(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001160 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001161 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1162 result->SetI(obj->IdentityHashCode());
1163}
1164
Andreas Gampe799681b2015-05-15 19:24:12 -07001165void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
Andreas Gampedd9d0552015-03-09 12:57:41 -07001166 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001167 double in = shadow_frame->GetVRegDouble(arg_offset);
Roland Levillainda4d79b2015-03-24 14:36:11 +00001168 result->SetJ(bit_cast<int64_t, double>(in));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001169}
1170
Andreas Gampedd9d0552015-03-09 12:57:41 -07001171static void UnstartedMemoryPeek(
1172 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1173 int64_t address = shadow_frame->GetVRegLong(arg_offset);
1174 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
1175 // aborting the transaction.
1176
1177 switch (type) {
1178 case Primitive::kPrimByte: {
1179 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
1180 return;
1181 }
1182
1183 case Primitive::kPrimShort: {
Andreas Gampec55bb392018-09-21 00:02:02 +00001184 using unaligned_short __attribute__((__aligned__(1))) = int16_t;
Andreas Gampe799681b2015-05-15 19:24:12 -07001185 result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001186 return;
1187 }
1188
1189 case Primitive::kPrimInt: {
Andreas Gampec55bb392018-09-21 00:02:02 +00001190 using unaligned_int __attribute__((__aligned__(1))) = int32_t;
Andreas Gampe799681b2015-05-15 19:24:12 -07001191 result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001192 return;
1193 }
1194
1195 case Primitive::kPrimLong: {
Andreas Gampec55bb392018-09-21 00:02:02 +00001196 using unaligned_long __attribute__((__aligned__(1))) = int64_t;
Andreas Gampe799681b2015-05-15 19:24:12 -07001197 result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -07001198 return;
1199 }
1200
1201 case Primitive::kPrimBoolean:
1202 case Primitive::kPrimChar:
1203 case Primitive::kPrimFloat:
1204 case Primitive::kPrimDouble:
1205 case Primitive::kPrimVoid:
1206 case Primitive::kPrimNot:
1207 LOG(FATAL) << "Not in the Memory API: " << type;
1208 UNREACHABLE();
1209 }
1210 LOG(FATAL) << "Should not reach here";
1211 UNREACHABLE();
1212}
1213
Andreas Gampe799681b2015-05-15 19:24:12 -07001214void UnstartedRuntime::UnstartedMemoryPeekByte(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001215 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001216 UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
1217}
1218
1219void UnstartedRuntime::UnstartedMemoryPeekShort(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001220 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001221 UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
1222}
1223
1224void UnstartedRuntime::UnstartedMemoryPeekInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001225 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001226 UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
1227}
1228
1229void UnstartedRuntime::UnstartedMemoryPeekLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001230 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001231 UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001232}
1233
1234static void UnstartedMemoryPeekArray(
1235 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001236 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampedd9d0552015-03-09 12:57:41 -07001237 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1238 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1239 if (obj == nullptr) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001240 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
Andreas Gampedd9d0552015-03-09 12:57:41 -07001241 return;
1242 }
1243 mirror::Array* array = obj->AsArray();
1244
1245 int offset = shadow_frame->GetVReg(arg_offset + 3);
1246 int count = shadow_frame->GetVReg(arg_offset + 4);
1247 if (offset < 0 || offset + count > array->GetLength()) {
1248 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
1249 offset, count, array->GetLength()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001250 Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
Andreas Gampedd9d0552015-03-09 12:57:41 -07001251 return;
1252 }
1253
1254 switch (type) {
1255 case Primitive::kPrimByte: {
1256 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
1257 mirror::ByteArray* byte_array = array->AsByteArray();
1258 for (int32_t i = 0; i < count; ++i, ++address) {
1259 byte_array->SetWithoutChecks<true>(i + offset, *address);
1260 }
1261 return;
1262 }
1263
1264 case Primitive::kPrimShort:
1265 case Primitive::kPrimInt:
1266 case Primitive::kPrimLong:
1267 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1268 UNREACHABLE();
1269
1270 case Primitive::kPrimBoolean:
1271 case Primitive::kPrimChar:
1272 case Primitive::kPrimFloat:
1273 case Primitive::kPrimDouble:
1274 case Primitive::kPrimVoid:
1275 case Primitive::kPrimNot:
1276 LOG(FATAL) << "Not in the Memory API: " << type;
1277 UNREACHABLE();
1278 }
1279 LOG(FATAL) << "Should not reach here";
1280 UNREACHABLE();
1281}
1282
Andreas Gampe799681b2015-05-15 19:24:12 -07001283void UnstartedRuntime::UnstartedMemoryPeekByteArray(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001284 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001285 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001286}
1287
Kenny Root1c9e61c2015-05-14 15:58:17 -07001288// This allows reading the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001289void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001290 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001291 jint start = shadow_frame->GetVReg(arg_offset + 1);
1292 jint end = shadow_frame->GetVReg(arg_offset + 2);
1293 jint index = shadow_frame->GetVReg(arg_offset + 4);
1294 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1295 if (string == nullptr) {
1296 AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1297 return;
1298 }
Kenny Root57f91e82015-05-14 15:58:17 -07001299 DCHECK_GE(start, 0);
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001300 DCHECK_LE(start, end);
1301 DCHECK_LE(end, string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001302 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001303 Handle<mirror::CharArray> h_char_array(
1304 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
Vladimir Markofdaf0f42016-10-13 19:29:53 +01001305 DCHECK_GE(index, 0);
Kenny Root57f91e82015-05-14 15:58:17 -07001306 DCHECK_LE(index, h_char_array->GetLength());
1307 DCHECK_LE(end - start, h_char_array->GetLength() - index);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001308 string->GetChars(start, end, h_char_array, index);
1309}
1310
1311// This allows reading chars from the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001312void UnstartedRuntime::UnstartedStringCharAt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001313 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001314 jint index = shadow_frame->GetVReg(arg_offset + 1);
1315 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1316 if (string == nullptr) {
1317 AbortTransactionOrFail(self, "String.charAt with null object");
1318 return;
1319 }
1320 result->SetC(string->CharAt(index));
1321}
1322
Vladimir Marko92907f32017-02-20 14:08:30 +00001323// This allows creating String objects with replaced characters during compilation.
1324// String.doReplace(char, char) is called from String.replace(char, char) when there is a match.
1325void UnstartedRuntime::UnstartedStringDoReplace(
1326 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1327 jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
1328 jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001329 StackHandleScope<1> hs(self);
1330 Handle<mirror::String> string =
1331 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
Kenny Root57f91e82015-05-14 15:58:17 -07001332 if (string == nullptr) {
Vladimir Marko92907f32017-02-20 14:08:30 +00001333 AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
Kenny Root57f91e82015-05-14 15:58:17 -07001334 return;
1335 }
Vladimir Marko9e57aba2017-03-16 10:45:40 +00001336 result->SetL(mirror::String::DoReplace(self, string, old_c, new_c));
Kenny Root57f91e82015-05-14 15:58:17 -07001337}
1338
Kenny Root1c9e61c2015-05-14 15:58:17 -07001339// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001340void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001341 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001342 jint offset = shadow_frame->GetVReg(arg_offset);
1343 jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1344 DCHECK_GE(char_count, 0);
1345 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001346 Handle<mirror::CharArray> h_char_array(
1347 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
Kenny Root1c9e61c2015-05-14 15:58:17 -07001348 Runtime* runtime = Runtime::Current();
1349 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1350 result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator));
1351}
1352
1353// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001354void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001355 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root57f91e82015-05-14 15:58:17 -07001356 mirror::String* to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1357 if (to_copy == nullptr) {
1358 AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1359 return;
1360 }
1361 StackHandleScope<1> hs(self);
1362 Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1363 Runtime* runtime = Runtime::Current();
1364 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1365 result->SetL(mirror::String::AllocFromString<true>(self, h_string->GetLength(), h_string, 0,
1366 allocator));
1367}
1368
Andreas Gampe799681b2015-05-15 19:24:12 -07001369void UnstartedRuntime::UnstartedStringFastSubstring(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001370 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001371 jint start = shadow_frame->GetVReg(arg_offset + 1);
1372 jint length = shadow_frame->GetVReg(arg_offset + 2);
Kenny Root57f91e82015-05-14 15:58:17 -07001373 DCHECK_GE(start, 0);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001374 DCHECK_GE(length, 0);
1375 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001376 Handle<mirror::String> h_string(
1377 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
Kenny Root57f91e82015-05-14 15:58:17 -07001378 DCHECK_LE(start, h_string->GetLength());
1379 DCHECK_LE(start + length, h_string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001380 Runtime* runtime = Runtime::Current();
1381 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1382 result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator));
1383}
1384
Kenny Root57f91e82015-05-14 15:58:17 -07001385// This allows getting the char array for new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001386void UnstartedRuntime::UnstartedStringToCharArray(
Kenny Root57f91e82015-05-14 15:58:17 -07001387 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001388 REQUIRES_SHARED(Locks::mutator_lock_) {
Kenny Root57f91e82015-05-14 15:58:17 -07001389 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1390 if (string == nullptr) {
1391 AbortTransactionOrFail(self, "String.charAt with null object");
1392 return;
1393 }
1394 result->SetL(string->ToCharArray(self));
1395}
1396
Andreas Gampebc4d2182016-02-22 10:03:12 -08001397// This allows statically initializing ConcurrentHashMap and SynchronousQueue.
1398void UnstartedRuntime::UnstartedReferenceGetReferent(
1399 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001400 ObjPtr<mirror::Reference> const ref = down_cast<mirror::Reference*>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001401 shadow_frame->GetVRegReference(arg_offset));
1402 if (ref == nullptr) {
1403 AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1404 return;
1405 }
Mathieu Chartier5d3f73a2016-10-14 14:28:47 -07001406 ObjPtr<mirror::Object> const referent =
Andreas Gampebc4d2182016-02-22 10:03:12 -08001407 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1408 result->SetL(referent);
1409}
1410
1411// This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1412// conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1413// where we can predict the behavior (somewhat).
1414// Note: this is required (instead of lazy initialization) as these classes are used in the static
1415// initialization of other classes, so will *use* the value.
1416void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1417 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001418 if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001419 // SynchronousQueue really only separates between single- and multiprocessor case. Return
1420 // 8 as a conservative upper approximation.
1421 result->SetI(8);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001422 } else if (CheckCallers(shadow_frame,
1423 { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001424 // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1425 // a good upper bound.
1426 // TODO: Consider resetting in the zygote?
1427 result->SetI(8);
1428 } else {
1429 // Not supported.
1430 AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1431 }
1432}
1433
1434// This allows accessing ConcurrentHashMap/SynchronousQueue.
1435
1436void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1437 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1438 // Argument 0 is the Unsafe instance, skip.
1439 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1440 if (obj == nullptr) {
1441 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1442 return;
1443 }
1444 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1445 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1446 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001447 bool success;
1448 // Check whether we're in a transaction, call accordingly.
1449 if (Runtime::Current()->IsActiveTransaction()) {
1450 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1451 expectedValue,
1452 newValue);
1453 } else {
1454 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1455 expectedValue,
1456 newValue);
1457 }
1458 result->SetZ(success ? 1 : 0);
1459}
1460
1461void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1462 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1463 // Argument 0 is the Unsafe instance, skip.
1464 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1465 if (obj == nullptr) {
1466 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1467 return;
1468 }
1469 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1470 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1471 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 5);
1472
1473 // Must use non transactional mode.
1474 if (kUseReadBarrier) {
1475 // Need to make sure the reference stored in the field is a to-space one before attempting the
1476 // CAS or the CAS could fail incorrectly.
1477 mirror::HeapReference<mirror::Object>* field_addr =
1478 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1479 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001480 ReadBarrier::Barrier<
1481 mirror::Object,
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001482 /* kIsVolatile= */ false,
Hans Boehmcc55e1d2017-07-27 15:28:07 -07001483 kWithReadBarrier,
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001484 /* kAlwaysUpdateField= */ true>(
Andreas Gampebc4d2182016-02-22 10:03:12 -08001485 obj,
1486 MemberOffset(offset),
1487 field_addr);
1488 }
1489 bool success;
1490 // Check whether we're in a transaction, call accordingly.
1491 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001492 success = obj->CasFieldObject<true>(MemberOffset(offset),
1493 expected_value,
1494 newValue,
1495 CASMode::kStrong,
1496 std::memory_order_seq_cst);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001497 } else {
Mathieu Chartiera9746b92018-06-22 10:25:40 -07001498 success = obj->CasFieldObject<false>(MemberOffset(offset),
1499 expected_value,
1500 newValue,
1501 CASMode::kStrong,
1502 std::memory_order_seq_cst);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001503 }
1504 result->SetZ(success ? 1 : 0);
1505}
1506
1507void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1508 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001509 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001510 // Argument 0 is the Unsafe instance, skip.
1511 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1512 if (obj == nullptr) {
1513 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1514 return;
1515 }
1516 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1517 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1518 result->SetL(value);
1519}
1520
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001521void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1522 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001523 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001524 // Argument 0 is the Unsafe instance, skip.
1525 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1526 if (obj == nullptr) {
1527 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1528 return;
1529 }
1530 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1531 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1532 if (Runtime::Current()->IsActiveTransaction()) {
1533 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1534 } else {
1535 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1536 }
1537}
1538
Andreas Gampebc4d2182016-02-22 10:03:12 -08001539void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1540 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001541 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampebc4d2182016-02-22 10:03:12 -08001542 // Argument 0 is the Unsafe instance, skip.
1543 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1544 if (obj == nullptr) {
1545 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1546 return;
1547 }
1548 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1549 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 4);
Orion Hodson27b96762018-03-13 16:06:57 +00001550 std::atomic_thread_fence(std::memory_order_release);
Andreas Gampebc4d2182016-02-22 10:03:12 -08001551 if (Runtime::Current()->IsActiveTransaction()) {
1552 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1553 } else {
1554 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1555 }
1556}
1557
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001558// A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1559// of correctly handling the corner cases.
1560void UnstartedRuntime::UnstartedIntegerParseInt(
1561 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001562 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001563 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1564 if (obj == nullptr) {
1565 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1566 return;
1567 }
1568
1569 std::string string_value = obj->AsString()->ToModifiedUtf8();
1570 if (string_value.empty()) {
1571 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1572 return;
1573 }
1574
1575 const char* c_str = string_value.c_str();
1576 char *end;
1577 // Can we set errno to 0? Is this always a variable, and not a macro?
1578 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1579 int64_t l = strtol(c_str, &end, 10);
1580
1581 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1582 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1583 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1584 return;
1585 }
1586 if (l == 0) {
1587 // Check whether the string wasn't exactly zero.
1588 if (string_value != "0") {
1589 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1590 return;
1591 }
1592 } else if (*end != '\0') {
1593 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1594 return;
1595 }
1596
1597 result->SetI(static_cast<int32_t>(l));
1598}
1599
1600// A cutout for Long.parseLong.
1601//
1602// Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1603// well.
1604void UnstartedRuntime::UnstartedLongParseLong(
1605 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001606 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001607 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1608 if (obj == nullptr) {
1609 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1610 return;
1611 }
1612
1613 std::string string_value = obj->AsString()->ToModifiedUtf8();
1614 if (string_value.empty()) {
1615 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1616 return;
1617 }
1618
1619 const char* c_str = string_value.c_str();
1620 char *end;
1621 // Can we set errno to 0? Is this always a variable, and not a macro?
1622 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1623 int64_t l = strtol(c_str, &end, 10);
1624
1625 // Note: comparing against int32_t min/max is intentional here.
1626 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1627 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1628 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1629 return;
1630 }
1631 if (l == 0) {
1632 // Check whether the string wasn't exactly zero.
1633 if (string_value != "0") {
1634 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1635 return;
1636 }
1637 } else if (*end != '\0') {
1638 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1639 return;
1640 }
1641
1642 result->SetJ(l);
1643}
1644
Andreas Gampe715fdc22016-04-18 17:07:30 -07001645void UnstartedRuntime::UnstartedMethodInvoke(
1646 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07001647 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe715fdc22016-04-18 17:07:30 -07001648 JNIEnvExt* env = self->GetJniEnv();
1649 ScopedObjectAccessUnchecked soa(self);
1650
Mathieu Chartier8778c522016-10-04 19:06:30 -07001651 ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001652 ScopedLocalRef<jobject> java_method(env,
Roland Levillain5e8d5f02016-10-18 18:03:43 +01001653 java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001654
Mathieu Chartier8778c522016-10-04 19:06:30 -07001655 ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001656 ScopedLocalRef<jobject> java_receiver(env,
1657 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1658
Mathieu Chartier8778c522016-10-04 19:06:30 -07001659 ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001660 ScopedLocalRef<jobject> java_args(env,
1661 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1662
1663 ScopedLocalRef<jobject> result_jobj(env,
1664 InvokeMethod(soa, java_method.get(), java_receiver.get(), java_args.get()));
1665
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001666 result->SetL(self->DecodeJObject(result_jobj.get()));
Andreas Gampe715fdc22016-04-18 17:07:30 -07001667
1668 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1669 // InvocationTargetExceptions.
1670 if (self->IsExceptionPending()) {
1671 AbortTransactionOrFail(self, "Failed Method.invoke");
1672 }
1673}
1674
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001675void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1676 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1677 REQUIRES_SHARED(Locks::mutator_lock_) {
1678 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1679 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1680}
Andreas Gampebc4d2182016-02-22 10:03:12 -08001681
Orion Hodson43f0cdb2017-10-10 14:47:32 +01001682// Checks whether the runtime is s64-bit. This is needed for the clinit of
1683// java.lang.invoke.VarHandle clinit. The clinit determines sets of
1684// available VarHandle accessors and these differ based on machine
1685// word size.
1686void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1687 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1688 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1689 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1690 jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1691 result->SetZ(is64bit);
1692}
1693
Mathieu Chartiere401d142015-04-22 13:56:20 -07001694void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
Vladimir Marko78baed52018-10-11 10:44:58 +01001695 Thread* self,
1696 ArtMethod* method ATTRIBUTE_UNUSED,
1697 mirror::Object* receiver ATTRIBUTE_UNUSED,
1698 uint32_t* args,
1699 JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001700 int32_t length = args[1];
1701 DCHECK_GE(length, 0);
Vladimir Marko78baed52018-10-11 10:44:58 +01001702 ObjPtr<mirror::Object> element_class = reinterpret_cast32<mirror::Object*>(args[0])->AsClass();
1703 if (element_class == nullptr) {
1704 AbortTransactionOrFail(self, "VMRuntime.newUnpaddedArray with null element_class.");
1705 return;
1706 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001707 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001708 ObjPtr<mirror::Class> array_class =
Vladimir Marko78baed52018-10-11 10:44:58 +01001709 runtime->GetClassLinker()->FindArrayClass(self, element_class->AsClass());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001710 DCHECK(array_class != nullptr);
1711 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001712 result->SetL(mirror::Array::Alloc<true, true>(self,
1713 array_class,
1714 length,
1715 array_class->GetComponentSizeShift(),
1716 allocator));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001717}
1718
Mathieu Chartiere401d142015-04-22 13:56:20 -07001719void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1720 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1721 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001722 result->SetL(nullptr);
1723}
1724
Mathieu Chartiere401d142015-04-22 13:56:20 -07001725void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1726 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1727 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001728 NthCallerVisitor visitor(self, 3);
1729 visitor.WalkStack();
1730 if (visitor.caller != nullptr) {
1731 result->SetL(visitor.caller->GetDeclaringClass());
1732 }
1733}
1734
Mathieu Chartiere401d142015-04-22 13:56:20 -07001735void UnstartedRuntime::UnstartedJNIMathLog(
1736 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1737 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001738 JValue value;
1739 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1740 result->SetD(log(value.GetD()));
1741}
1742
Mathieu Chartiere401d142015-04-22 13:56:20 -07001743void UnstartedRuntime::UnstartedJNIMathExp(
1744 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1745 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001746 JValue value;
1747 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1748 result->SetD(exp(value.GetD()));
1749}
1750
Andreas Gampebc4d2182016-02-22 10:03:12 -08001751void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1752 Thread* self ATTRIBUTE_UNUSED,
1753 ArtMethod* method ATTRIBUTE_UNUSED,
1754 mirror::Object* receiver ATTRIBUTE_UNUSED,
1755 uint32_t* args ATTRIBUTE_UNUSED,
1756 JValue* result) {
1757 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1758 ? 0
1759 : 1);
1760}
1761
Mathieu Chartiere401d142015-04-22 13:56:20 -07001762void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1763 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1764 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001765 StackHandleScope<1> hs(self);
1766 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1767}
1768
Andreas Gampebc4d2182016-02-22 10:03:12 -08001769void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1770 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1771 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1772 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1773 result->SetD(bit_cast<double>(long_input));
1774}
1775
Mathieu Chartiere401d142015-04-22 13:56:20 -07001776void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1777 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1778 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001779 result->SetI(args[0]);
1780}
1781
Mathieu Chartiere401d142015-04-22 13:56:20 -07001782void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1783 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1784 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001785 result->SetI(args[0]);
1786}
1787
Mathieu Chartiere401d142015-04-22 13:56:20 -07001788void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1789 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1790 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001791 result->SetL(receiver->Clone(self));
1792}
1793
Mathieu Chartiere401d142015-04-22 13:56:20 -07001794void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1795 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1796 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001797 receiver->NotifyAll(self);
1798}
1799
Vladimir Marko78baed52018-10-11 10:44:58 +01001800void UnstartedRuntime::UnstartedJNIStringCompareTo(Thread* self,
1801 ArtMethod* method ATTRIBUTE_UNUSED,
1802 mirror::Object* receiver,
1803 uint32_t* args,
1804 JValue* result) {
1805 ObjPtr<mirror::Object> rhs = reinterpret_cast32<mirror::Object*>(args[0]);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001806 if (rhs == nullptr) {
Vladimir Marko78baed52018-10-11 10:44:58 +01001807 AbortTransactionOrFail(self, "String.compareTo with null object.");
1808 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001809 }
Vladimir Marko78baed52018-10-11 10:44:58 +01001810 result->SetI(receiver->AsString()->CompareTo(rhs->AsString()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001811}
1812
Mathieu Chartiere401d142015-04-22 13:56:20 -07001813void UnstartedRuntime::UnstartedJNIStringIntern(
1814 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1815 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001816 result->SetL(receiver->AsString()->Intern());
1817}
1818
Mathieu Chartiere401d142015-04-22 13:56:20 -07001819void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1820 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1821 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001822 StackHandleScope<2> hs(self);
1823 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1824 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1825 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1826}
1827
Mathieu Chartiere401d142015-04-22 13:56:20 -07001828void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1829 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1830 uint32_t* args, JValue* result) {
Andreas Gampee598e042015-04-10 14:57:10 -07001831 int32_t length = static_cast<int32_t>(args[1]);
1832 if (length < 0) {
1833 ThrowNegativeArraySizeException(length);
1834 return;
1835 }
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001836 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
Andreas Gampee598e042015-04-10 14:57:10 -07001837 Runtime* runtime = Runtime::Current();
1838 ClassLinker* class_linker = runtime->GetClassLinker();
Vladimir Markobcf17522018-06-01 13:14:32 +01001839 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, element_class);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001840 if (UNLIKELY(array_class == nullptr)) {
Andreas Gampee598e042015-04-10 14:57:10 -07001841 CHECK(self->IsExceptionPending());
1842 return;
1843 }
1844 DCHECK(array_class->IsObjectArrayClass());
Vladimir Markobcf17522018-06-01 13:14:32 +01001845 ObjPtr<mirror::Array> new_array = mirror::ObjectArray<mirror::Object>::Alloc(
Andreas Gampee598e042015-04-10 14:57:10 -07001846 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1847 result->SetL(new_array);
1848}
1849
Mathieu Chartiere401d142015-04-22 13:56:20 -07001850void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1851 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1852 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001853 ScopedObjectAccessUnchecked soa(self);
1854 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001855 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<true>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001856 } else {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -07001857 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<false>(soa)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001858 }
1859}
1860
Mathieu Chartiere401d142015-04-22 13:56:20 -07001861void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
1862 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1863 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001864 result->SetZ(JNI_TRUE);
1865}
1866
Mathieu Chartiere401d142015-04-22 13:56:20 -07001867void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
Vladimir Marko78baed52018-10-11 10:44:58 +01001868 Thread* self,
1869 ArtMethod* method ATTRIBUTE_UNUSED,
1870 mirror::Object* receiver ATTRIBUTE_UNUSED,
1871 uint32_t* args,
1872 JValue* result) {
1873 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1874 if (obj == nullptr) {
1875 AbortTransactionOrFail(self, "Unsafe.compareAndSwapInt with null object.");
1876 return;
1877 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001878 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1879 jint expectedValue = args[3];
1880 jint newValue = args[4];
1881 bool success;
1882 if (Runtime::Current()->IsActiveTransaction()) {
Mathieu Chartier42c2e502018-06-19 12:30:56 -07001883 success = obj->CasField32<true>(MemberOffset(offset),
1884 expectedValue,
1885 newValue,
1886 CASMode::kStrong,
1887 std::memory_order_seq_cst);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001888 } else {
Mathieu Chartier42c2e502018-06-19 12:30:56 -07001889 success = obj->CasField32<false>(MemberOffset(offset),
1890 expectedValue,
1891 newValue,
1892 CASMode::kStrong,
1893 std::memory_order_seq_cst);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001894 }
1895 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1896}
1897
Vladimir Marko78baed52018-10-11 10:44:58 +01001898void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(Thread* self,
1899 ArtMethod* method ATTRIBUTE_UNUSED,
1900 mirror::Object* receiver ATTRIBUTE_UNUSED,
1901 uint32_t* args,
1902 JValue* result) {
1903 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
Narayan Kamath34a316f2016-03-30 13:11:18 +01001904 if (obj == nullptr) {
Vladimir Marko78baed52018-10-11 10:44:58 +01001905 AbortTransactionOrFail(self, "Unsafe.compareAndSwapIntVolatile with null object.");
Narayan Kamath34a316f2016-03-30 13:11:18 +01001906 return;
1907 }
1908
1909 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1910 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1911}
1912
Vladimir Marko78baed52018-10-11 10:44:58 +01001913void UnstartedRuntime::UnstartedJNIUnsafePutObject(Thread* self,
1914 ArtMethod* method ATTRIBUTE_UNUSED,
1915 mirror::Object* receiver ATTRIBUTE_UNUSED,
1916 uint32_t* args,
1917 JValue* result ATTRIBUTE_UNUSED) {
1918 ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
1919 if (obj == nullptr) {
1920 AbortTransactionOrFail(self, "Unsafe.putObject with null object.");
1921 return;
1922 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001923 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
Vladimir Marko78baed52018-10-11 10:44:58 +01001924 ObjPtr<mirror::Object> newValue = reinterpret_cast32<mirror::Object*>(args[3]);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001925 if (Runtime::Current()->IsActiveTransaction()) {
1926 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1927 } else {
1928 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1929 }
1930}
1931
Andreas Gampe799681b2015-05-15 19:24:12 -07001932void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
Vladimir Marko78baed52018-10-11 10:44:58 +01001933 Thread* self,
1934 ArtMethod* method ATTRIBUTE_UNUSED,
1935 mirror::Object* receiver ATTRIBUTE_UNUSED,
1936 uint32_t* args,
1937 JValue* result) {
1938 ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
1939 if (component == nullptr) {
1940 AbortTransactionOrFail(self, "Unsafe.getArrayBaseOffsetForComponentType with null component.");
1941 return;
1942 }
1943 Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001944 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1945}
1946
Andreas Gampe799681b2015-05-15 19:24:12 -07001947void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
Vladimir Marko78baed52018-10-11 10:44:58 +01001948 Thread* self,
1949 ArtMethod* method ATTRIBUTE_UNUSED,
1950 mirror::Object* receiver ATTRIBUTE_UNUSED,
1951 uint32_t* args,
1952 JValue* result) {
1953 ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
1954 if (component == nullptr) {
1955 AbortTransactionOrFail(self, "Unsafe.getArrayIndexScaleForComponentType with null component.");
1956 return;
1957 }
1958 Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001959 result->SetI(Primitive::ComponentSize(primitive_type));
1960}
1961
Andreas Gampec55bb392018-09-21 00:02:02 +00001962using InvokeHandler = void(*)(Thread* self,
1963 ShadowFrame* shadow_frame,
1964 JValue* result,
1965 size_t arg_size);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001966
Andreas Gampec55bb392018-09-21 00:02:02 +00001967using JNIHandler = void(*)(Thread* self,
1968 ArtMethod* method,
1969 mirror::Object* receiver,
1970 uint32_t* args,
1971 JValue* result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001972
1973static bool tables_initialized_ = false;
1974static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
1975static std::unordered_map<std::string, JNIHandler> jni_handlers_;
1976
Andreas Gampe799681b2015-05-15 19:24:12 -07001977void UnstartedRuntime::InitializeInvokeHandlers() {
1978#define UNSTARTED_DIRECT(ShortName, Sig) \
1979 invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
1980#include "unstarted_runtime_list.h"
1981 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
1982#undef UNSTARTED_RUNTIME_DIRECT_LIST
1983#undef UNSTARTED_RUNTIME_JNI_LIST
1984#undef UNSTARTED_DIRECT
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001985}
1986
Andreas Gampe799681b2015-05-15 19:24:12 -07001987void UnstartedRuntime::InitializeJNIHandlers() {
1988#define UNSTARTED_JNI(ShortName, Sig) \
1989 jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
1990#include "unstarted_runtime_list.h"
1991 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
1992#undef UNSTARTED_RUNTIME_DIRECT_LIST
1993#undef UNSTARTED_RUNTIME_JNI_LIST
1994#undef UNSTARTED_JNI
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001995}
1996
Andreas Gampe799681b2015-05-15 19:24:12 -07001997void UnstartedRuntime::Initialize() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001998 CHECK(!tables_initialized_);
1999
Andreas Gampe799681b2015-05-15 19:24:12 -07002000 InitializeInvokeHandlers();
2001 InitializeJNIHandlers();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002002
2003 tables_initialized_ = true;
2004}
2005
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002006void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
Andreas Gampe799681b2015-05-15 19:24:12 -07002007 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002008 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
2009 // problems in core libraries.
2010 CHECK(tables_initialized_);
2011
David Sehr709b0702016-10-13 09:12:37 -07002012 std::string name(ArtMethod::PrettyMethod(shadow_frame->GetMethod()));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002013 const auto& iter = invoke_handlers_.find(name);
2014 if (iter != invoke_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07002015 // Clear out the result in case it's not zeroed out.
Yi Kong4b22b342018-08-02 14:43:21 -07002016 result->SetL(nullptr);
Andreas Gampe715fdc22016-04-18 17:07:30 -07002017
2018 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
2019 self->PushShadowFrame(shadow_frame);
2020
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002021 (*iter->second)(self, shadow_frame, result, arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07002022
2023 self->PopShadowFrame();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002024 } else {
2025 // Not special, continue with regular interpreter execution.
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002026 ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002027 }
2028}
2029
2030// 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 -07002031void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe799681b2015-05-15 19:24:12 -07002032 uint32_t* args, JValue* result) {
David Sehr709b0702016-10-13 09:12:37 -07002033 std::string name(ArtMethod::PrettyMethod(method));
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002034 const auto& iter = jni_handlers_.find(name);
2035 if (iter != jni_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07002036 // Clear out the result in case it's not zeroed out.
Yi Kong4b22b342018-08-02 14:43:21 -07002037 result->SetL(nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002038 (*iter->second)(self, method, receiver, args, result);
2039 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02002040 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
2041 name.c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002042 } else {
David Sehr709b0702016-10-13 09:12:37 -07002043 LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
Andreas Gampe2969bcd2015-03-09 12:57:41 -07002044 "non-transactional runtime";
2045 }
2046}
2047
2048} // namespace interpreter
2049} // namespace art