blob: 57443f14e6aa9f7ebd11b0939e51f5050a9fe59b [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 Gampe13fc1be2016-04-05 20:14:30 -070024#include <limits>
Andreas Gampe8ce9c302016-04-15 21:24:28 -070025#include <locale>
Andreas Gampe2969bcd2015-03-09 12:57:41 -070026#include <unordered_map>
27
Andreas Gampeaacc25d2015-04-01 14:49:06 -070028#include "ScopedLocalRef.h"
29
Mathieu Chartiere401d142015-04-22 13:56:20 -070030#include "art_method-inl.h"
Andreas Gampebc4d2182016-02-22 10:03:12 -080031#include "base/casts.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070032#include "base/enums.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070033#include "base/logging.h"
34#include "base/macros.h"
35#include "class_linker.h"
36#include "common_throws.h"
37#include "entrypoints/entrypoint_utils-inl.h"
Andreas Gampebc4d2182016-02-22 10:03:12 -080038#include "gc/reference_processor.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070039#include "handle_scope-inl.h"
40#include "interpreter/interpreter_common.h"
41#include "mirror/array-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070042#include "mirror/class.h"
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070043#include "mirror/field-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070044#include "mirror/object-inl.h"
45#include "mirror/object_array-inl.h"
46#include "mirror/string-inl.h"
47#include "nth_caller_visitor.h"
Andreas Gampe715fdc22016-04-18 17:07:30 -070048#include "reflection.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070049#include "thread.h"
Sebastien Hertz2fd7e692015-04-02 11:11:19 +020050#include "transaction.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070051#include "well_known_classes.h"
Andreas Gampef778eb22015-04-13 14:17:09 -070052#include "zip_archive.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070053
54namespace art {
55namespace interpreter {
56
Andreas Gampe068b0c02015-03-11 12:44:47 -070057static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
Sebastien Hertz45b15972015-04-03 16:07:05 +020058 __attribute__((__format__(__printf__, 2, 3)))
Mathieu Chartier90443472015-07-16 20:32:27 -070059 SHARED_REQUIRES(Locks::mutator_lock_);
Sebastien Hertz45b15972015-04-03 16:07:05 +020060
61static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
Andreas Gampe068b0c02015-03-11 12:44:47 -070062 va_list args;
Andreas Gampe068b0c02015-03-11 12:44:47 -070063 if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +020064 va_start(args, fmt);
65 AbortTransactionV(self, fmt, args);
Andreas Gampe068b0c02015-03-11 12:44:47 -070066 va_end(args);
67 } else {
Sebastien Hertz45b15972015-04-03 16:07:05 +020068 va_start(args, fmt);
69 std::string msg;
70 StringAppendV(&msg, fmt, args);
71 va_end(args);
72 LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
Andreas Gampe068b0c02015-03-11 12:44:47 -070073 UNREACHABLE();
74 }
75}
76
Andreas Gampe8ce9c302016-04-15 21:24:28 -070077// Restricted support for character upper case / lower case. Only support ASCII, where
78// it's easy. Abort the transaction otherwise.
79static void CharacterLowerUpper(Thread* self,
80 ShadowFrame* shadow_frame,
81 JValue* result,
82 size_t arg_offset,
83 bool to_lower_case) SHARED_REQUIRES(Locks::mutator_lock_) {
84 uint32_t int_value = static_cast<uint32_t>(shadow_frame->GetVReg(arg_offset));
85
86 // Only ASCII (7-bit).
87 if (!isascii(int_value)) {
88 AbortTransactionOrFail(self,
89 "Only support ASCII characters for toLowerCase/toUpperCase: %u",
90 int_value);
91 return;
92 }
93
94 std::locale c_locale("C");
95 char char_value = static_cast<char>(int_value);
96
97 if (to_lower_case) {
98 result->SetI(std::tolower(char_value, c_locale));
99 } else {
100 result->SetI(std::toupper(char_value, c_locale));
101 }
102}
103
104void UnstartedRuntime::UnstartedCharacterToLowerCase(
105 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
106 CharacterLowerUpper(self, shadow_frame, result, arg_offset, true);
107}
108
109void UnstartedRuntime::UnstartedCharacterToUpperCase(
110 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
111 CharacterLowerUpper(self, shadow_frame, result, arg_offset, false);
112}
113
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700114// Helper function to deal with class loading in an unstarted runtime.
115static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
116 Handle<mirror::ClassLoader> class_loader, JValue* result,
117 const std::string& method_name, bool initialize_class,
118 bool abort_if_not_found)
Mathieu Chartier90443472015-07-16 20:32:27 -0700119 SHARED_REQUIRES(Locks::mutator_lock_) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700120 CHECK(className.Get() != nullptr);
121 std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
122 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
123
124 mirror::Class* found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
125 if (found == nullptr && abort_if_not_found) {
126 if (!self->IsExceptionPending()) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700127 AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
128 method_name.c_str(), PrettyDescriptor(descriptor.c_str()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700129 }
130 return;
131 }
132 if (found != nullptr && initialize_class) {
133 StackHandleScope<1> hs(self);
134 Handle<mirror::Class> h_class(hs.NewHandle(found));
135 if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
136 CHECK(self->IsExceptionPending());
137 return;
138 }
139 }
140 result->SetL(found);
141}
142
143// Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
144// rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
145// ClassNotFoundException), so need to do the same. The only exception is if the exception is
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200146// actually the transaction abort exception. This must not be wrapped, as it signals an
147// initialization abort.
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700148static void CheckExceptionGenerateClassNotFound(Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700149 SHARED_REQUIRES(Locks::mutator_lock_) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700150 if (self->IsExceptionPending()) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200151 // If it is not the transaction abort exception, wrap it.
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700152 std::string type(PrettyTypeOf(self->GetException()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200153 if (type != Transaction::kAbortExceptionDescriptor) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700154 self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
155 "ClassNotFoundException");
156 }
157 }
158}
159
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700160static mirror::String* GetClassName(Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Mathieu Chartier90443472015-07-16 20:32:27 -0700161 SHARED_REQUIRES(Locks::mutator_lock_) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700162 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
163 if (param == nullptr) {
164 AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
165 return nullptr;
166 }
167 return param->AsString();
168}
169
Andreas Gampe799681b2015-05-15 19:24:12 -0700170void UnstartedRuntime::UnstartedClassForName(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700171 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700172 mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
173 if (class_name == nullptr) {
174 return;
175 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700176 StackHandleScope<1> hs(self);
177 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
Mathieu Chartier9865bde2015-12-21 09:58:16 -0800178 UnstartedRuntimeFindClass(self,
179 h_class_name,
180 ScopedNullHandle<mirror::ClassLoader>(),
181 result,
182 "Class.forName",
183 true,
184 false);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700185 CheckExceptionGenerateClassNotFound(self);
186}
187
Andreas Gampe799681b2015-05-15 19:24:12 -0700188void UnstartedRuntime::UnstartedClassForNameLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700189 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700190 mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
191 if (class_name == nullptr) {
Andreas Gampebf4d3af2015-04-14 10:10:33 -0700192 return;
193 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700194 bool initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
195 mirror::ClassLoader* class_loader =
196 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
197 StackHandleScope<2> hs(self);
198 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
199 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
200 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result, "Class.forName",
201 initialize_class, false);
202 CheckExceptionGenerateClassNotFound(self);
203}
204
Andreas Gampe799681b2015-05-15 19:24:12 -0700205void UnstartedRuntime::UnstartedClassClassForName(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700206 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700207 mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
208 if (class_name == nullptr) {
209 return;
210 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700211 bool initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
212 mirror::ClassLoader* class_loader =
213 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
214 StackHandleScope<2> hs(self);
215 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
216 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
217 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result, "Class.classForName",
218 initialize_class, false);
219 CheckExceptionGenerateClassNotFound(self);
220}
221
Andreas Gampe799681b2015-05-15 19:24:12 -0700222void UnstartedRuntime::UnstartedClassNewInstance(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700223 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
224 StackHandleScope<2> hs(self); // Class, constructor, object.
Andreas Gampe5d4bb1d2015-04-14 22:16:14 -0700225 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
226 if (param == nullptr) {
227 AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
228 return;
229 }
230 mirror::Class* klass = param->AsClass();
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700231 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700232
233 // Check that it's not null.
234 if (h_klass.Get() == nullptr) {
235 AbortTransactionOrFail(self, "Class reference is null for newInstance");
236 return;
237 }
238
239 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
240 if (Runtime::Current()->IsActiveTransaction()) {
241 if (h_klass.Get()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200242 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
243 PrettyClass(h_klass.Get()).c_str());
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700244 return;
245 }
246 }
247
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700248 // There are two situations in which we'll abort this run.
249 // 1) If the class isn't yet initialized and initialization fails.
250 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
251 // Note that 2) could likely be handled here, but for safety abort the transaction.
252 bool ok = false;
Mathieu Chartiere401d142015-04-22 13:56:20 -0700253 auto* cl = Runtime::Current()->GetClassLinker();
254 if (cl->EnsureInitialized(self, h_klass, true, true)) {
255 auto* cons = h_klass->FindDeclaredDirectMethod("<init>", "()V", cl->GetImagePointerSize());
256 if (cons != nullptr) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700257 Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
258 CHECK(h_obj.Get() != nullptr); // We don't expect OOM at compile-time.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700259 EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700260 if (!self->IsExceptionPending()) {
261 result->SetL(h_obj.Get());
262 ok = true;
263 }
264 } else {
265 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
266 "Could not find default constructor for '%s'",
267 PrettyClass(h_klass.Get()).c_str());
268 }
269 }
270 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700271 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
272 PrettyClass(h_klass.Get()).c_str(),
273 PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700274 }
275}
276
Andreas Gampe799681b2015-05-15 19:24:12 -0700277void UnstartedRuntime::UnstartedClassGetDeclaredField(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700278 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700279 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
280 // going the reflective Dex way.
281 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
282 mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700283 ArtField* found = nullptr;
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700284 for (ArtField& field : klass->GetIFields()) {
285 if (name2->Equals(field.GetName())) {
286 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700287 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700288 }
289 }
290 if (found == nullptr) {
Mathieu Chartier54d220e2015-07-30 16:20:06 -0700291 for (ArtField& field : klass->GetSFields()) {
292 if (name2->Equals(field.GetName())) {
293 found = &field;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700294 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700295 }
296 }
297 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700298 if (found == nullptr) {
299 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
300 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
301 PrettyDescriptor(klass).c_str());
302 return;
303 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700304 Runtime* runtime = Runtime::Current();
Andreas Gampe542451c2016-07-26 09:02:02 -0700305 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Andreas Gampee01e3642016-07-25 13:06:04 -0700306 mirror::Field* field;
307 if (runtime->IsActiveTransaction()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700308 if (pointer_size == PointerSize::k64) {
309 field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
310 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700311 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700312 field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
313 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700314 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700315 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700316 if (pointer_size == PointerSize::k64) {
317 field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
318 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700319 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700320 field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
321 self, found, true);
Andreas Gampee01e3642016-07-25 13:06:04 -0700322 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700323 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700324 result->SetL(field);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700325}
326
Andreas Gampebc4d2182016-02-22 10:03:12 -0800327// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
328void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
329 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
330 // Special managed code cut-out to allow method lookup in a un-started runtime.
331 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
332 if (klass == nullptr) {
333 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
334 return;
335 }
336 mirror::String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
337 mirror::ObjectArray<mirror::Class>* args =
338 shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700339 Runtime* runtime = Runtime::Current();
340 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700341 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Andreas Gampee01e3642016-07-25 13:06:04 -0700342 mirror::Method* method;
343 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700344 if (pointer_size == PointerSize::k64) {
345 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
346 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700347 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700348 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
349 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700350 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800351 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700352 if (pointer_size == PointerSize::k64) {
353 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
354 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700355 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700356 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
357 self, klass, name, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700358 }
Andreas Gampebc4d2182016-02-22 10:03:12 -0800359 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700360 result->SetL(method);
Andreas Gampebc4d2182016-02-22 10:03:12 -0800361}
362
Andreas Gampe6039e562016-04-05 18:18:43 -0700363// Special managed code cut-out to allow constructor lookup in a un-started runtime.
364void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
365 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
366 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
367 if (klass == nullptr) {
368 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
369 return;
370 }
371 mirror::ObjectArray<mirror::Class>* args =
372 shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
Andreas Gampee01e3642016-07-25 13:06:04 -0700373 Runtime* runtime = Runtime::Current();
374 bool transaction = runtime->IsActiveTransaction();
Andreas Gampe542451c2016-07-26 09:02:02 -0700375 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
Andreas Gampee01e3642016-07-25 13:06:04 -0700376 mirror::Constructor* constructor;
377 if (transaction) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700378 if (pointer_size == PointerSize::k64) {
379 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
380 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700381 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700382 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
383 true>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700384 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700385 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700386 if (pointer_size == PointerSize::k64) {
387 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
388 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700389 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700390 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
391 false>(self, klass, args);
Andreas Gampee01e3642016-07-25 13:06:04 -0700392 }
Andreas Gampe6039e562016-04-05 18:18:43 -0700393 }
Andreas Gampee01e3642016-07-25 13:06:04 -0700394 result->SetL(constructor);
Andreas Gampe6039e562016-04-05 18:18:43 -0700395}
396
Andreas Gampe633750c2016-02-19 10:49:50 -0800397void UnstartedRuntime::UnstartedClassGetEnclosingClass(
398 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
399 StackHandleScope<1> hs(self);
400 Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
401 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
402 result->SetL(nullptr);
403 }
404 result->SetL(klass->GetDexFile().GetEnclosingClass(klass));
405}
406
Andreas Gampe715fdc22016-04-18 17:07:30 -0700407void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
408 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
409 StackHandleScope<1> hs(self);
410 Handle<mirror::Class> klass(hs.NewHandle(
411 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
412 const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
413 result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
414}
415
Andreas Gampeeb8b0ae2016-04-13 17:58:05 -0700416static std::unique_ptr<MemMap> FindAndExtractEntry(const std::string& jar_file,
417 const char* entry_name,
418 size_t* size,
419 std::string* error_msg) {
420 CHECK(size != nullptr);
421
422 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
423 if (zip_archive == nullptr) {
424 return nullptr;;
425 }
426 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
427 if (zip_entry == nullptr) {
428 return nullptr;
429 }
430 std::unique_ptr<MemMap> tmp_map(
431 zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg));
432 if (tmp_map == nullptr) {
433 return nullptr;
434 }
435
436 // OK, from here everything seems fine.
437 *size = zip_entry->GetUncompressedLength();
438 return tmp_map;
439}
440
441static void GetResourceAsStream(Thread* self,
442 ShadowFrame* shadow_frame,
443 JValue* result,
444 size_t arg_offset) SHARED_REQUIRES(Locks::mutator_lock_) {
445 mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
446 if (resource_obj == nullptr) {
447 AbortTransactionOrFail(self, "null name for getResourceAsStream");
448 return;
449 }
450 CHECK(resource_obj->IsString());
451 mirror::String* resource_name = resource_obj->AsString();
452
453 std::string resource_name_str = resource_name->ToModifiedUtf8();
454 if (resource_name_str.empty() || resource_name_str == "/") {
455 AbortTransactionOrFail(self,
456 "Unsupported name %s for getResourceAsStream",
457 resource_name_str.c_str());
458 return;
459 }
460 const char* resource_cstr = resource_name_str.c_str();
461 if (resource_cstr[0] == '/') {
462 resource_cstr++;
463 }
464
465 Runtime* runtime = Runtime::Current();
466
467 std::vector<std::string> split;
468 Split(runtime->GetBootClassPathString(), ':', &split);
469 if (split.empty()) {
470 AbortTransactionOrFail(self,
471 "Boot classpath not set or split error:: %s",
472 runtime->GetBootClassPathString().c_str());
473 return;
474 }
475
476 std::unique_ptr<MemMap> mem_map;
477 size_t map_size;
478 std::string last_error_msg; // Only store the last message (we could concatenate).
479
480 for (const std::string& jar_file : split) {
481 mem_map = FindAndExtractEntry(jar_file, resource_cstr, &map_size, &last_error_msg);
482 if (mem_map != nullptr) {
483 break;
484 }
485 }
486
487 if (mem_map == nullptr) {
488 // Didn't find it. There's a good chance this will be the same at runtime, but still
489 // conservatively abort the transaction here.
490 AbortTransactionOrFail(self,
491 "Could not find resource %s. Last error was %s.",
492 resource_name_str.c_str(),
493 last_error_msg.c_str());
494 return;
495 }
496
497 StackHandleScope<3> hs(self);
498
499 // Create byte array for content.
500 Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
501 if (h_array.Get() == nullptr) {
502 AbortTransactionOrFail(self, "Could not find/create byte array class");
503 return;
504 }
505 // Copy in content.
506 memcpy(h_array->GetData(), mem_map->Begin(), map_size);
507 // Be proactive releasing memory.
508 mem_map.release();
509
510 // Create a ByteArrayInputStream.
511 Handle<mirror::Class> h_class(hs.NewHandle(
512 runtime->GetClassLinker()->FindClass(self,
513 "Ljava/io/ByteArrayInputStream;",
514 ScopedNullHandle<mirror::ClassLoader>())));
515 if (h_class.Get() == nullptr) {
516 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
517 return;
518 }
519 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
520 AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
521 return;
522 }
523
524 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
525 if (h_obj.Get() == nullptr) {
526 AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
527 return;
528 }
529
530 auto* cl = Runtime::Current()->GetClassLinker();
531 ArtMethod* constructor = h_class->FindDeclaredDirectMethod(
532 "<init>", "([B)V", cl->GetImagePointerSize());
533 if (constructor == nullptr) {
534 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
535 return;
536 }
537
538 uint32_t args[1];
539 args[0] = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_array.Get()));
540 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
541
542 if (self->IsExceptionPending()) {
543 AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
544 return;
545 }
546
547 result->SetL(h_obj.Get());
548}
549
550void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
551 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
552 {
553 mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
554 CHECK(this_obj != nullptr);
555 CHECK(this_obj->IsClassLoader());
556
557 StackHandleScope<1> hs(self);
558 Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
559
560 if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
561 this_classloader_class.Get()) {
562 AbortTransactionOrFail(self,
563 "Unsupported classloader type %s for getResourceAsStream",
564 PrettyClass(this_classloader_class.Get()).c_str());
565 return;
566 }
567 }
568
569 GetResourceAsStream(self, shadow_frame, result, arg_offset);
570}
571
Andreas Gampe799681b2015-05-15 19:24:12 -0700572void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700573 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700574 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
575 mirror::ClassLoader* class_loader =
576 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
577 StackHandleScope<2> hs(self);
578 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
579 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
580 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
581 "VMClassLoader.findLoadedClass", false, false);
582 // This might have an error pending. But semantics are to just return null.
583 if (self->IsExceptionPending()) {
584 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
585 std::string type(PrettyTypeOf(self->GetException()));
586 if (type != "java.lang.InternalError") {
587 self->ClearException();
588 }
589 }
590}
591
Mathieu Chartiere401d142015-04-22 13:56:20 -0700592void UnstartedRuntime::UnstartedVoidLookupType(
593 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED, JValue* result,
594 size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700595 result->SetL(Runtime::Current()->GetClassLinker()->FindPrimitiveClass('V'));
596}
597
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700598// Arraycopy emulation.
599// Note: we can't use any fast copy functions, as they are not available under transaction.
600
601template <typename T>
602static void PrimitiveArrayCopy(Thread* self,
603 mirror::Array* src_array, int32_t src_pos,
604 mirror::Array* dst_array, int32_t dst_pos,
605 int32_t length)
Mathieu Chartier90443472015-07-16 20:32:27 -0700606 SHARED_REQUIRES(Locks::mutator_lock_) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700607 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
608 AbortTransactionOrFail(self, "Types mismatched in arraycopy: %s vs %s.",
609 PrettyDescriptor(src_array->GetClass()->GetComponentType()).c_str(),
610 PrettyDescriptor(dst_array->GetClass()->GetComponentType()).c_str());
611 return;
612 }
613 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
614 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
615 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
616 if (copy_forward) {
617 for (int32_t i = 0; i < length; ++i) {
618 dst->Set(dst_pos + i, src->Get(src_pos + i));
619 }
620 } else {
621 for (int32_t i = 1; i <= length; ++i) {
622 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
623 }
624 }
625}
626
Andreas Gampe799681b2015-05-15 19:24:12 -0700627void UnstartedRuntime::UnstartedSystemArraycopy(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700628 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700629 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700630 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
631 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700632 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700633
Andreas Gampe85a098a2016-03-31 13:30:53 -0700634 mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
635 mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
636 // Null checking. For simplicity, abort transaction.
637 if (src_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700638 AbortTransactionOrFail(self, "src is null in arraycopy.");
639 return;
640 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700641 if (dst_obj == nullptr) {
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700642 AbortTransactionOrFail(self, "dst is null in arraycopy.");
643 return;
644 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700645 // Test for arrayness. Throw ArrayStoreException.
646 if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
647 self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
648 return;
649 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700650
Andreas Gampe85a098a2016-03-31 13:30:53 -0700651 mirror::Array* src_array = src_obj->AsArray();
652 mirror::Array* dst_array = dst_obj->AsArray();
653
654 // Bounds checking. Throw IndexOutOfBoundsException.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700655 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
656 UNLIKELY(src_pos > src_array->GetLength() - length) ||
657 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700658 self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700659 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
660 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
661 length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700662 return;
663 }
664
665 // Type checking.
666 mirror::Class* src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
667 GetComponentType();
668
669 if (!src_type->IsPrimitive()) {
670 // Check that the second type is not primitive.
671 mirror::Class* trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
672 GetComponentType();
673 if (trg_type->IsPrimitiveInt()) {
674 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
675 PrettyDescriptor(src_array->GetClass()->GetComponentType()).c_str(),
676 PrettyDescriptor(dst_array->GetClass()->GetComponentType()).c_str());
677 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700678 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700679
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700680 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
681 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
682 if (src == dst) {
683 // Can overlap, but not have type mismatches.
Andreas Gampe85a098a2016-03-31 13:30:53 -0700684 // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700685 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
686 if (copy_forward) {
687 for (int32_t i = 0; i < length; ++i) {
688 dst->Set(dst_pos + i, src->Get(src_pos + i));
689 }
690 } else {
691 for (int32_t i = 1; i <= length; ++i) {
692 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
693 }
694 }
695 } else {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700696 // We're being lazy here. Optimally this could be a memcpy (if component types are
697 // assignable), but the ObjectArray implementation doesn't support transactions. The
698 // checking version, however, does.
699 if (Runtime::Current()->IsActiveTransaction()) {
700 dst->AssignableCheckingMemcpy<true>(
701 dst_pos, src, src_pos, length, true /* throw_exception */);
702 } else {
703 dst->AssignableCheckingMemcpy<false>(
704 dst_pos, src, src_pos, length, true /* throw_exception */);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700705 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700706 }
Andreas Gampe5c9af612016-04-05 14:16:10 -0700707 } else if (src_type->IsPrimitiveByte()) {
708 PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700709 } else if (src_type->IsPrimitiveChar()) {
710 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
711 } else if (src_type->IsPrimitiveInt()) {
712 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700713 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700714 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700715 PrettyDescriptor(src_type).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700716 }
717}
718
Andreas Gampe5c9af612016-04-05 14:16:10 -0700719void UnstartedRuntime::UnstartedSystemArraycopyByte(
720 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
721 // Just forward.
722 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
723}
724
Andreas Gampe799681b2015-05-15 19:24:12 -0700725void UnstartedRuntime::UnstartedSystemArraycopyChar(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700726 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700727 // Just forward.
728 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
729}
730
731void UnstartedRuntime::UnstartedSystemArraycopyInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700732 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700733 // Just forward.
734 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
735}
736
Narayan Kamath34a316f2016-03-30 13:11:18 +0100737void UnstartedRuntime::UnstartedSystemGetSecurityManager(
738 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
739 JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
740 result->SetL(nullptr);
741}
742
Andreas Gamped4fa9f42016-04-13 14:53:23 -0700743static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
744
745static void GetSystemProperty(Thread* self,
746 ShadowFrame* shadow_frame,
747 JValue* result,
748 size_t arg_offset,
749 bool is_default_version)
750 SHARED_REQUIRES(Locks::mutator_lock_) {
751 StackHandleScope<4> hs(self);
752 Handle<mirror::String> h_key(
753 hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
754 if (h_key.Get() == nullptr) {
755 AbortTransactionOrFail(self, "getProperty key was null");
756 return;
757 }
758
759 // This is overall inefficient, but reflecting the values here is not great, either. So
760 // for simplicity, and with the assumption that the number of getProperty calls is not
761 // too great, just iterate each time.
762
763 // Get the storage class.
764 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
765 Handle<mirror::Class> h_props_class(hs.NewHandle(
766 class_linker->FindClass(self,
767 "Ljava/lang/AndroidHardcodedSystemProperties;",
768 ScopedNullHandle<mirror::ClassLoader>())));
769 if (h_props_class.Get() == nullptr) {
770 AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
771 return;
772 }
773 if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
774 AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
775 return;
776 }
777
778 // Get the storage array.
779 ArtField* static_properties =
780 h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
781 "[[Ljava/lang/String;");
782 if (static_properties == nullptr) {
783 AbortTransactionOrFail(self,
784 "Could not find %s field",
785 kAndroidHardcodedSystemPropertiesFieldName);
786 return;
787 }
788 Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(
789 hs.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>*>(
790 static_properties->GetObject(h_props_class.Get()))));
791 if (h_2string_array.Get() == nullptr) {
792 AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
793 return;
794 }
795
796 // Iterate over it.
797 const int32_t prop_count = h_2string_array->GetLength();
798 // Use the third handle as mutable.
799 MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
800 hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
801 for (int32_t i = 0; i < prop_count; ++i) {
802 h_string_array.Assign(h_2string_array->Get(i));
803 if (h_string_array.Get() == nullptr ||
804 h_string_array->GetLength() != 2 ||
805 h_string_array->Get(0) == nullptr) {
806 AbortTransactionOrFail(self,
807 "Unexpected content of %s",
808 kAndroidHardcodedSystemPropertiesFieldName);
809 return;
810 }
811 if (h_key->Equals(h_string_array->Get(0))) {
812 // Found a value.
813 if (h_string_array->Get(1) == nullptr && is_default_version) {
814 // Null is being delegated to the default map, and then resolved to the given default value.
815 // As there's no default map, return the given value.
816 result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
817 } else {
818 result->SetL(h_string_array->Get(1));
819 }
820 return;
821 }
822 }
823
824 // Key is not supported.
825 AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
826}
827
828void UnstartedRuntime::UnstartedSystemGetProperty(
829 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
830 GetSystemProperty(self, shadow_frame, result, arg_offset, false);
831}
832
833void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
834 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
835 GetSystemProperty(self, shadow_frame, result, arg_offset, true);
836}
837
Andreas Gampe799681b2015-05-15 19:24:12 -0700838void UnstartedRuntime::UnstartedThreadLocalGet(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700839 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700840 std::string caller(PrettyMethod(shadow_frame->GetLink()->GetMethod()));
841 bool ok = false;
Narayan Kamatha1e93122016-03-30 15:41:54 +0100842 if (caller == "void java.lang.FloatingDecimal.developLongDigits(int, long, long)" ||
843 caller == "java.lang.String java.lang.FloatingDecimal.toJavaFormatString()") {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700844 // Allocate non-threadlocal buffer.
Narayan Kamatha1e93122016-03-30 15:41:54 +0100845 result->SetL(mirror::CharArray::Alloc(self, 26));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700846 ok = true;
Narayan Kamatha1e93122016-03-30 15:41:54 +0100847 } else if (caller ==
848 "java.lang.FloatingDecimal java.lang.FloatingDecimal.getThreadLocalInstance()") {
849 // Allocate new object.
850 StackHandleScope<2> hs(self);
851 Handle<mirror::Class> h_real_to_string_class(hs.NewHandle(
852 shadow_frame->GetLink()->GetMethod()->GetDeclaringClass()));
853 Handle<mirror::Object> h_real_to_string_obj(hs.NewHandle(
854 h_real_to_string_class->AllocObject(self)));
855 if (h_real_to_string_obj.Get() != nullptr) {
856 auto* cl = Runtime::Current()->GetClassLinker();
857 ArtMethod* init_method = h_real_to_string_class->FindDirectMethod(
858 "<init>", "()V", cl->GetImagePointerSize());
859 if (init_method == nullptr) {
860 h_real_to_string_class->DumpClass(LOG(FATAL), mirror::Class::kDumpClassFullDetail);
861 } else {
862 JValue invoke_result;
863 EnterInterpreterFromInvoke(self, init_method, h_real_to_string_obj.Get(), nullptr,
864 nullptr);
865 if (!self->IsExceptionPending()) {
866 result->SetL(h_real_to_string_obj.Get());
867 ok = true;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700868 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700869 }
870 }
871 }
872
873 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700874 AbortTransactionOrFail(self, "Could not create RealToString object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700875 }
876}
877
Sergio Giro83261202016-04-11 20:49:20 +0100878void UnstartedRuntime::UnstartedMathCeil(
879 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -0700880 result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
Sergio Giro83261202016-04-11 20:49:20 +0100881}
882
883void UnstartedRuntime::UnstartedMathFloor(
884 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe89e3b482016-04-12 18:07:36 -0700885 result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700886}
887
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700888void UnstartedRuntime::UnstartedMathSin(
889 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
890 result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
891}
892
893void UnstartedRuntime::UnstartedMathCos(
894 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
895 result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
896}
897
898void UnstartedRuntime::UnstartedMathPow(
899 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
900 result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
901 shadow_frame->GetVRegDouble(arg_offset + 2)));
902}
903
Andreas Gampe799681b2015-05-15 19:24:12 -0700904void UnstartedRuntime::UnstartedObjectHashCode(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700905 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700906 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
907 result->SetI(obj->IdentityHashCode());
908}
909
Andreas Gampe799681b2015-05-15 19:24:12 -0700910void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
Andreas Gampedd9d0552015-03-09 12:57:41 -0700911 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700912 double in = shadow_frame->GetVRegDouble(arg_offset);
Roland Levillainda4d79b2015-03-24 14:36:11 +0000913 result->SetJ(bit_cast<int64_t, double>(in));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700914}
915
Andreas Gampedd9d0552015-03-09 12:57:41 -0700916static mirror::Object* GetDexFromDexCache(Thread* self, mirror::DexCache* dex_cache)
Mathieu Chartier90443472015-07-16 20:32:27 -0700917 SHARED_REQUIRES(Locks::mutator_lock_) {
Andreas Gampedd9d0552015-03-09 12:57:41 -0700918 const DexFile* dex_file = dex_cache->GetDexFile();
919 if (dex_file == nullptr) {
920 return nullptr;
921 }
922
923 // Create the direct byte buffer.
924 JNIEnv* env = self->GetJniEnv();
925 DCHECK(env != nullptr);
926 void* address = const_cast<void*>(reinterpret_cast<const void*>(dex_file->Begin()));
Andreas Gampeaacc25d2015-04-01 14:49:06 -0700927 ScopedLocalRef<jobject> byte_buffer(env, env->NewDirectByteBuffer(address, dex_file->Size()));
928 if (byte_buffer.get() == nullptr) {
Andreas Gampedd9d0552015-03-09 12:57:41 -0700929 DCHECK(self->IsExceptionPending());
930 return nullptr;
931 }
932
933 jvalue args[1];
Andreas Gampeaacc25d2015-04-01 14:49:06 -0700934 args[0].l = byte_buffer.get();
935
936 ScopedLocalRef<jobject> dex(env, env->CallStaticObjectMethodA(
937 WellKnownClasses::com_android_dex_Dex,
938 WellKnownClasses::com_android_dex_Dex_create,
939 args));
940
941 return self->DecodeJObject(dex.get());
Andreas Gampedd9d0552015-03-09 12:57:41 -0700942}
943
Andreas Gampe799681b2015-05-15 19:24:12 -0700944void UnstartedRuntime::UnstartedDexCacheGetDexNative(
Mathieu Chartiere401d142015-04-22 13:56:20 -0700945 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampedd9d0552015-03-09 12:57:41 -0700946 // We will create the Dex object, but the image writer will release it before creating the
947 // art file.
948 mirror::Object* src = shadow_frame->GetVRegReference(arg_offset);
949 bool have_dex = false;
950 if (src != nullptr) {
951 mirror::Object* dex = GetDexFromDexCache(self, reinterpret_cast<mirror::DexCache*>(src));
952 if (dex != nullptr) {
953 have_dex = true;
954 result->SetL(dex);
955 }
956 }
957 if (!have_dex) {
958 self->ClearException();
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200959 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Could not create Dex object");
Andreas Gampedd9d0552015-03-09 12:57:41 -0700960 }
961}
962
963static void UnstartedMemoryPeek(
964 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
965 int64_t address = shadow_frame->GetVRegLong(arg_offset);
966 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
967 // aborting the transaction.
968
969 switch (type) {
970 case Primitive::kPrimByte: {
971 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
972 return;
973 }
974
975 case Primitive::kPrimShort: {
Andreas Gampe799681b2015-05-15 19:24:12 -0700976 typedef int16_t unaligned_short __attribute__ ((aligned (1)));
977 result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -0700978 return;
979 }
980
981 case Primitive::kPrimInt: {
Andreas Gampe799681b2015-05-15 19:24:12 -0700982 typedef int32_t unaligned_int __attribute__ ((aligned (1)));
983 result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -0700984 return;
985 }
986
987 case Primitive::kPrimLong: {
Andreas Gampe799681b2015-05-15 19:24:12 -0700988 typedef int64_t unaligned_long __attribute__ ((aligned (1)));
989 result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
Andreas Gampedd9d0552015-03-09 12:57:41 -0700990 return;
991 }
992
993 case Primitive::kPrimBoolean:
994 case Primitive::kPrimChar:
995 case Primitive::kPrimFloat:
996 case Primitive::kPrimDouble:
997 case Primitive::kPrimVoid:
998 case Primitive::kPrimNot:
999 LOG(FATAL) << "Not in the Memory API: " << type;
1000 UNREACHABLE();
1001 }
1002 LOG(FATAL) << "Should not reach here";
1003 UNREACHABLE();
1004}
1005
Andreas Gampe799681b2015-05-15 19:24:12 -07001006void UnstartedRuntime::UnstartedMemoryPeekByte(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001007 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001008 UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
1009}
1010
1011void UnstartedRuntime::UnstartedMemoryPeekShort(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001012 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001013 UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
1014}
1015
1016void UnstartedRuntime::UnstartedMemoryPeekInt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001017 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001018 UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
1019}
1020
1021void UnstartedRuntime::UnstartedMemoryPeekLong(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001022 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001023 UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001024}
1025
1026static void UnstartedMemoryPeekArray(
1027 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
Mathieu Chartier90443472015-07-16 20:32:27 -07001028 SHARED_REQUIRES(Locks::mutator_lock_) {
Andreas Gampedd9d0552015-03-09 12:57:41 -07001029 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1030 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1031 if (obj == nullptr) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001032 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
Andreas Gampedd9d0552015-03-09 12:57:41 -07001033 return;
1034 }
1035 mirror::Array* array = obj->AsArray();
1036
1037 int offset = shadow_frame->GetVReg(arg_offset + 3);
1038 int count = shadow_frame->GetVReg(arg_offset + 4);
1039 if (offset < 0 || offset + count > array->GetLength()) {
1040 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
1041 offset, count, array->GetLength()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +02001042 Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
Andreas Gampedd9d0552015-03-09 12:57:41 -07001043 return;
1044 }
1045
1046 switch (type) {
1047 case Primitive::kPrimByte: {
1048 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
1049 mirror::ByteArray* byte_array = array->AsByteArray();
1050 for (int32_t i = 0; i < count; ++i, ++address) {
1051 byte_array->SetWithoutChecks<true>(i + offset, *address);
1052 }
1053 return;
1054 }
1055
1056 case Primitive::kPrimShort:
1057 case Primitive::kPrimInt:
1058 case Primitive::kPrimLong:
1059 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1060 UNREACHABLE();
1061
1062 case Primitive::kPrimBoolean:
1063 case Primitive::kPrimChar:
1064 case Primitive::kPrimFloat:
1065 case Primitive::kPrimDouble:
1066 case Primitive::kPrimVoid:
1067 case Primitive::kPrimNot:
1068 LOG(FATAL) << "Not in the Memory API: " << type;
1069 UNREACHABLE();
1070 }
1071 LOG(FATAL) << "Should not reach here";
1072 UNREACHABLE();
1073}
1074
Andreas Gampe799681b2015-05-15 19:24:12 -07001075void UnstartedRuntime::UnstartedMemoryPeekByteArray(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001076 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Andreas Gampe799681b2015-05-15 19:24:12 -07001077 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
Andreas Gampedd9d0552015-03-09 12:57:41 -07001078}
1079
Kenny Root1c9e61c2015-05-14 15:58:17 -07001080// This allows reading the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001081void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001082 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001083 jint start = shadow_frame->GetVReg(arg_offset + 1);
1084 jint end = shadow_frame->GetVReg(arg_offset + 2);
1085 jint index = shadow_frame->GetVReg(arg_offset + 4);
1086 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1087 if (string == nullptr) {
1088 AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1089 return;
1090 }
Kenny Root57f91e82015-05-14 15:58:17 -07001091 DCHECK_GE(start, 0);
1092 DCHECK_GE(end, string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001093 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001094 Handle<mirror::CharArray> h_char_array(
1095 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
Kenny Root57f91e82015-05-14 15:58:17 -07001096 DCHECK_LE(index, h_char_array->GetLength());
1097 DCHECK_LE(end - start, h_char_array->GetLength() - index);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001098 string->GetChars(start, end, h_char_array, index);
1099}
1100
1101// This allows reading chars from the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001102void UnstartedRuntime::UnstartedStringCharAt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001103 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001104 jint index = shadow_frame->GetVReg(arg_offset + 1);
1105 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1106 if (string == nullptr) {
1107 AbortTransactionOrFail(self, "String.charAt with null object");
1108 return;
1109 }
1110 result->SetC(string->CharAt(index));
1111}
1112
Kenny Root57f91e82015-05-14 15:58:17 -07001113// This allows setting chars from the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001114void UnstartedRuntime::UnstartedStringSetCharAt(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001115 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
Kenny Root57f91e82015-05-14 15:58:17 -07001116 jint index = shadow_frame->GetVReg(arg_offset + 1);
1117 jchar c = shadow_frame->GetVReg(arg_offset + 2);
1118 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1119 if (string == nullptr) {
1120 AbortTransactionOrFail(self, "String.setCharAt with null object");
1121 return;
1122 }
1123 string->SetCharAt(index, c);
1124}
1125
Kenny Root1c9e61c2015-05-14 15:58:17 -07001126// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001127void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001128 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001129 jint offset = shadow_frame->GetVReg(arg_offset);
1130 jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1131 DCHECK_GE(char_count, 0);
1132 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001133 Handle<mirror::CharArray> h_char_array(
1134 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
Kenny Root1c9e61c2015-05-14 15:58:17 -07001135 Runtime* runtime = Runtime::Current();
1136 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1137 result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator));
1138}
1139
1140// This allows creating the new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001141void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001142 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root57f91e82015-05-14 15:58:17 -07001143 mirror::String* to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1144 if (to_copy == nullptr) {
1145 AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1146 return;
1147 }
1148 StackHandleScope<1> hs(self);
1149 Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1150 Runtime* runtime = Runtime::Current();
1151 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1152 result->SetL(mirror::String::AllocFromString<true>(self, h_string->GetLength(), h_string, 0,
1153 allocator));
1154}
1155
Andreas Gampe799681b2015-05-15 19:24:12 -07001156void UnstartedRuntime::UnstartedStringFastSubstring(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001157 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Kenny Root1c9e61c2015-05-14 15:58:17 -07001158 jint start = shadow_frame->GetVReg(arg_offset + 1);
1159 jint length = shadow_frame->GetVReg(arg_offset + 2);
Kenny Root57f91e82015-05-14 15:58:17 -07001160 DCHECK_GE(start, 0);
Kenny Root1c9e61c2015-05-14 15:58:17 -07001161 DCHECK_GE(length, 0);
1162 StackHandleScope<1> hs(self);
Mathieu Chartiere401d142015-04-22 13:56:20 -07001163 Handle<mirror::String> h_string(
1164 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
Kenny Root57f91e82015-05-14 15:58:17 -07001165 DCHECK_LE(start, h_string->GetLength());
1166 DCHECK_LE(start + length, h_string->GetLength());
Kenny Root1c9e61c2015-05-14 15:58:17 -07001167 Runtime* runtime = Runtime::Current();
1168 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1169 result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator));
1170}
1171
Kenny Root57f91e82015-05-14 15:58:17 -07001172// This allows getting the char array for new style of String objects during compilation.
Andreas Gampe799681b2015-05-15 19:24:12 -07001173void UnstartedRuntime::UnstartedStringToCharArray(
Kenny Root57f91e82015-05-14 15:58:17 -07001174 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Mathieu Chartier90443472015-07-16 20:32:27 -07001175 SHARED_REQUIRES(Locks::mutator_lock_) {
Kenny Root57f91e82015-05-14 15:58:17 -07001176 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1177 if (string == nullptr) {
1178 AbortTransactionOrFail(self, "String.charAt with null object");
1179 return;
1180 }
1181 result->SetL(string->ToCharArray(self));
1182}
1183
Andreas Gampebc4d2182016-02-22 10:03:12 -08001184// This allows statically initializing ConcurrentHashMap and SynchronousQueue.
1185void UnstartedRuntime::UnstartedReferenceGetReferent(
1186 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1187 mirror::Reference* const ref = down_cast<mirror::Reference*>(
1188 shadow_frame->GetVRegReference(arg_offset));
1189 if (ref == nullptr) {
1190 AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1191 return;
1192 }
1193 mirror::Object* const referent =
1194 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1195 result->SetL(referent);
1196}
1197
1198// This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1199// conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1200// where we can predict the behavior (somewhat).
1201// Note: this is required (instead of lazy initialization) as these classes are used in the static
1202// initialization of other classes, so will *use* the value.
1203void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1204 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1205 std::string caller(PrettyMethod(shadow_frame->GetLink()->GetMethod()));
1206 if (caller == "void java.util.concurrent.SynchronousQueue.<clinit>()") {
1207 // SynchronousQueue really only separates between single- and multiprocessor case. Return
1208 // 8 as a conservative upper approximation.
1209 result->SetI(8);
1210 } else if (caller == "void java.util.concurrent.ConcurrentHashMap.<clinit>()") {
1211 // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1212 // a good upper bound.
1213 // TODO: Consider resetting in the zygote?
1214 result->SetI(8);
1215 } else {
1216 // Not supported.
1217 AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1218 }
1219}
1220
1221// This allows accessing ConcurrentHashMap/SynchronousQueue.
1222
1223void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1224 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1225 // Argument 0 is the Unsafe instance, skip.
1226 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1227 if (obj == nullptr) {
1228 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1229 return;
1230 }
1231 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1232 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1233 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
1234
1235 // Must use non transactional mode.
1236 if (kUseReadBarrier) {
1237 // Need to make sure the reference stored in the field is a to-space one before attempting the
1238 // CAS or the CAS could fail incorrectly.
1239 mirror::HeapReference<mirror::Object>* field_addr =
1240 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1241 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
1242 ReadBarrier::Barrier<mirror::Object, kWithReadBarrier, /*kAlwaysUpdateField*/true>(
1243 obj,
1244 MemberOffset(offset),
1245 field_addr);
1246 }
1247 bool success;
1248 // Check whether we're in a transaction, call accordingly.
1249 if (Runtime::Current()->IsActiveTransaction()) {
1250 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1251 expectedValue,
1252 newValue);
1253 } else {
1254 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1255 expectedValue,
1256 newValue);
1257 }
1258 result->SetZ(success ? 1 : 0);
1259}
1260
1261void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1262 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1263 // Argument 0 is the Unsafe instance, skip.
1264 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1265 if (obj == nullptr) {
1266 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1267 return;
1268 }
1269 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1270 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1271 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 5);
1272
1273 // Must use non transactional mode.
1274 if (kUseReadBarrier) {
1275 // Need to make sure the reference stored in the field is a to-space one before attempting the
1276 // CAS or the CAS could fail incorrectly.
1277 mirror::HeapReference<mirror::Object>* field_addr =
1278 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1279 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
1280 ReadBarrier::Barrier<mirror::Object, kWithReadBarrier, /*kAlwaysUpdateField*/true>(
1281 obj,
1282 MemberOffset(offset),
1283 field_addr);
1284 }
1285 bool success;
1286 // Check whether we're in a transaction, call accordingly.
1287 if (Runtime::Current()->IsActiveTransaction()) {
1288 success = obj->CasFieldStrongSequentiallyConsistentObject<true>(MemberOffset(offset),
1289 expected_value,
1290 newValue);
1291 } else {
1292 success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
1293 expected_value,
1294 newValue);
1295 }
1296 result->SetZ(success ? 1 : 0);
1297}
1298
1299void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1300 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1301 SHARED_REQUIRES(Locks::mutator_lock_) {
1302 // Argument 0 is the Unsafe instance, skip.
1303 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1304 if (obj == nullptr) {
1305 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1306 return;
1307 }
1308 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1309 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1310 result->SetL(value);
1311}
1312
Andreas Gampe8a18fde2016-04-05 21:12:51 -07001313void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1314 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
1315 SHARED_REQUIRES(Locks::mutator_lock_) {
1316 // Argument 0 is the Unsafe instance, skip.
1317 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1318 if (obj == nullptr) {
1319 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1320 return;
1321 }
1322 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1323 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1324 if (Runtime::Current()->IsActiveTransaction()) {
1325 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1326 } else {
1327 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1328 }
1329}
1330
Andreas Gampebc4d2182016-02-22 10:03:12 -08001331void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1332 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
1333 SHARED_REQUIRES(Locks::mutator_lock_) {
1334 // Argument 0 is the Unsafe instance, skip.
1335 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1336 if (obj == nullptr) {
1337 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1338 return;
1339 }
1340 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1341 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 4);
1342 QuasiAtomic::ThreadFenceRelease();
1343 if (Runtime::Current()->IsActiveTransaction()) {
1344 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1345 } else {
1346 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1347 }
1348}
1349
Andreas Gampe13fc1be2016-04-05 20:14:30 -07001350// A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1351// of correctly handling the corner cases.
1352void UnstartedRuntime::UnstartedIntegerParseInt(
1353 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1354 SHARED_REQUIRES(Locks::mutator_lock_) {
1355 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1356 if (obj == nullptr) {
1357 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1358 return;
1359 }
1360
1361 std::string string_value = obj->AsString()->ToModifiedUtf8();
1362 if (string_value.empty()) {
1363 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1364 return;
1365 }
1366
1367 const char* c_str = string_value.c_str();
1368 char *end;
1369 // Can we set errno to 0? Is this always a variable, and not a macro?
1370 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1371 int64_t l = strtol(c_str, &end, 10);
1372
1373 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1374 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1375 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1376 return;
1377 }
1378 if (l == 0) {
1379 // Check whether the string wasn't exactly zero.
1380 if (string_value != "0") {
1381 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1382 return;
1383 }
1384 } else if (*end != '\0') {
1385 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1386 return;
1387 }
1388
1389 result->SetI(static_cast<int32_t>(l));
1390}
1391
1392// A cutout for Long.parseLong.
1393//
1394// Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1395// well.
1396void UnstartedRuntime::UnstartedLongParseLong(
1397 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1398 SHARED_REQUIRES(Locks::mutator_lock_) {
1399 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1400 if (obj == nullptr) {
1401 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1402 return;
1403 }
1404
1405 std::string string_value = obj->AsString()->ToModifiedUtf8();
1406 if (string_value.empty()) {
1407 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1408 return;
1409 }
1410
1411 const char* c_str = string_value.c_str();
1412 char *end;
1413 // Can we set errno to 0? Is this always a variable, and not a macro?
1414 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1415 int64_t l = strtol(c_str, &end, 10);
1416
1417 // Note: comparing against int32_t min/max is intentional here.
1418 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1419 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1420 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1421 return;
1422 }
1423 if (l == 0) {
1424 // Check whether the string wasn't exactly zero.
1425 if (string_value != "0") {
1426 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1427 return;
1428 }
1429 } else if (*end != '\0') {
1430 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1431 return;
1432 }
1433
1434 result->SetJ(l);
1435}
1436
Andreas Gampe715fdc22016-04-18 17:07:30 -07001437void UnstartedRuntime::UnstartedMethodInvoke(
1438 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1439 SHARED_REQUIRES(Locks::mutator_lock_) {
1440 JNIEnvExt* env = self->GetJniEnv();
1441 ScopedObjectAccessUnchecked soa(self);
1442
1443 mirror::Object* java_method_obj = shadow_frame->GetVRegReference(arg_offset);
1444 ScopedLocalRef<jobject> java_method(env,
1445 java_method_obj == nullptr ? nullptr :env->AddLocalReference<jobject>(java_method_obj));
1446
1447 mirror::Object* java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
1448 ScopedLocalRef<jobject> java_receiver(env,
1449 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1450
1451 mirror::Object* java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
1452 ScopedLocalRef<jobject> java_args(env,
1453 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1454
1455 ScopedLocalRef<jobject> result_jobj(env,
1456 InvokeMethod(soa, java_method.get(), java_receiver.get(), java_args.get()));
1457
1458 result->SetL(self->DecodeJObject(result_jobj.get()));
1459
1460 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1461 // InvocationTargetExceptions.
1462 if (self->IsExceptionPending()) {
1463 AbortTransactionOrFail(self, "Failed Method.invoke");
1464 }
1465}
1466
Andreas Gampebc4d2182016-02-22 10:03:12 -08001467
Mathieu Chartiere401d142015-04-22 13:56:20 -07001468void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
1469 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1470 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001471 int32_t length = args[1];
1472 DCHECK_GE(length, 0);
1473 mirror::Class* element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1474 Runtime* runtime = Runtime::Current();
1475 mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(self, &element_class);
1476 DCHECK(array_class != nullptr);
1477 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1478 result->SetL(mirror::Array::Alloc<true, true>(self, array_class, length,
1479 array_class->GetComponentSizeShift(), allocator));
1480}
1481
Mathieu Chartiere401d142015-04-22 13:56:20 -07001482void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1483 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1484 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001485 result->SetL(nullptr);
1486}
1487
Mathieu Chartiere401d142015-04-22 13:56:20 -07001488void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1489 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1490 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001491 NthCallerVisitor visitor(self, 3);
1492 visitor.WalkStack();
1493 if (visitor.caller != nullptr) {
1494 result->SetL(visitor.caller->GetDeclaringClass());
1495 }
1496}
1497
Mathieu Chartiere401d142015-04-22 13:56:20 -07001498void UnstartedRuntime::UnstartedJNIMathLog(
1499 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1500 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001501 JValue value;
1502 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1503 result->SetD(log(value.GetD()));
1504}
1505
Mathieu Chartiere401d142015-04-22 13:56:20 -07001506void UnstartedRuntime::UnstartedJNIMathExp(
1507 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1508 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001509 JValue value;
1510 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1511 result->SetD(exp(value.GetD()));
1512}
1513
Andreas Gampebc4d2182016-02-22 10:03:12 -08001514void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1515 Thread* self ATTRIBUTE_UNUSED,
1516 ArtMethod* method ATTRIBUTE_UNUSED,
1517 mirror::Object* receiver ATTRIBUTE_UNUSED,
1518 uint32_t* args ATTRIBUTE_UNUSED,
1519 JValue* result) {
1520 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1521 ? 0
1522 : 1);
1523}
1524
Mathieu Chartiere401d142015-04-22 13:56:20 -07001525void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1526 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1527 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001528 StackHandleScope<1> hs(self);
1529 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1530}
1531
Andreas Gampebc4d2182016-02-22 10:03:12 -08001532void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1533 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1534 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1535 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1536 result->SetD(bit_cast<double>(long_input));
1537}
1538
Mathieu Chartiere401d142015-04-22 13:56:20 -07001539void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1540 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1541 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001542 result->SetI(args[0]);
1543}
1544
Mathieu Chartiere401d142015-04-22 13:56:20 -07001545void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1546 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1547 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001548 result->SetI(args[0]);
1549}
1550
Mathieu Chartiere401d142015-04-22 13:56:20 -07001551void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1552 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1553 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001554 result->SetL(receiver->Clone(self));
1555}
1556
Mathieu Chartiere401d142015-04-22 13:56:20 -07001557void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1558 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1559 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001560 receiver->NotifyAll(self);
1561}
1562
Mathieu Chartiere401d142015-04-22 13:56:20 -07001563void UnstartedRuntime::UnstartedJNIStringCompareTo(
1564 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver, uint32_t* args,
1565 JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001566 mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
1567 if (rhs == nullptr) {
Andreas Gampe068b0c02015-03-11 12:44:47 -07001568 AbortTransactionOrFail(self, "String.compareTo with null object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001569 }
1570 result->SetI(receiver->AsString()->CompareTo(rhs));
1571}
1572
Mathieu Chartiere401d142015-04-22 13:56:20 -07001573void UnstartedRuntime::UnstartedJNIStringIntern(
1574 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1575 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001576 result->SetL(receiver->AsString()->Intern());
1577}
1578
Mathieu Chartiere401d142015-04-22 13:56:20 -07001579void UnstartedRuntime::UnstartedJNIStringFastIndexOf(
1580 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1581 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001582 result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1]));
1583}
1584
Mathieu Chartiere401d142015-04-22 13:56:20 -07001585void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1586 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1587 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001588 StackHandleScope<2> hs(self);
1589 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1590 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1591 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1592}
1593
Mathieu Chartiere401d142015-04-22 13:56:20 -07001594void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1595 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1596 uint32_t* args, JValue* result) {
Andreas Gampee598e042015-04-10 14:57:10 -07001597 int32_t length = static_cast<int32_t>(args[1]);
1598 if (length < 0) {
1599 ThrowNegativeArraySizeException(length);
1600 return;
1601 }
1602 mirror::Class* element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
1603 Runtime* runtime = Runtime::Current();
1604 ClassLinker* class_linker = runtime->GetClassLinker();
1605 mirror::Class* array_class = class_linker->FindArrayClass(self, &element_class);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001606 if (UNLIKELY(array_class == nullptr)) {
Andreas Gampee598e042015-04-10 14:57:10 -07001607 CHECK(self->IsExceptionPending());
1608 return;
1609 }
1610 DCHECK(array_class->IsObjectArrayClass());
1611 mirror::Array* new_array = mirror::ObjectArray<mirror::Object*>::Alloc(
1612 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1613 result->SetL(new_array);
1614}
1615
Mathieu Chartiere401d142015-04-22 13:56:20 -07001616void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1617 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1618 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001619 ScopedObjectAccessUnchecked soa(self);
1620 if (Runtime::Current()->IsActiveTransaction()) {
1621 result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<true>(soa)));
1622 } else {
1623 result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<false>(soa)));
1624 }
1625}
1626
Mathieu Chartiere401d142015-04-22 13:56:20 -07001627void UnstartedRuntime::UnstartedJNISystemIdentityHashCode(
1628 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1629 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001630 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1631 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1632}
1633
Mathieu Chartiere401d142015-04-22 13:56:20 -07001634void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
1635 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1636 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001637 result->SetZ(JNI_TRUE);
1638}
1639
Mathieu Chartiere401d142015-04-22 13:56:20 -07001640void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
1641 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1642 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001643 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1644 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1645 jint expectedValue = args[3];
1646 jint newValue = args[4];
1647 bool success;
1648 if (Runtime::Current()->IsActiveTransaction()) {
1649 success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
1650 expectedValue, newValue);
1651 } else {
1652 success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
1653 expectedValue, newValue);
1654 }
1655 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1656}
1657
Narayan Kamath34a316f2016-03-30 13:11:18 +01001658void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(
1659 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1660 uint32_t* args, JValue* result) {
1661 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1662 if (obj == nullptr) {
1663 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1664 return;
1665 }
1666
1667 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1668 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1669}
1670
Mathieu Chartiere401d142015-04-22 13:56:20 -07001671void UnstartedRuntime::UnstartedJNIUnsafePutObject(
1672 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1673 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result ATTRIBUTE_UNUSED) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001674 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1675 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1676 mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
1677 if (Runtime::Current()->IsActiveTransaction()) {
1678 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1679 } else {
1680 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1681 }
1682}
1683
Andreas Gampe799681b2015-05-15 19:24:12 -07001684void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001685 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1686 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001687 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1688 Primitive::Type primitive_type = component->GetPrimitiveType();
1689 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1690}
1691
Andreas Gampe799681b2015-05-15 19:24:12 -07001692void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
Mathieu Chartiere401d142015-04-22 13:56:20 -07001693 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1694 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001695 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1696 Primitive::Type primitive_type = component->GetPrimitiveType();
1697 result->SetI(Primitive::ComponentSize(primitive_type));
1698}
1699
Andreas Gampedd9d0552015-03-09 12:57:41 -07001700typedef void (*InvokeHandler)(Thread* self, ShadowFrame* shadow_frame, JValue* result,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001701 size_t arg_size);
1702
Mathieu Chartiere401d142015-04-22 13:56:20 -07001703typedef void (*JNIHandler)(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001704 uint32_t* args, JValue* result);
1705
1706static bool tables_initialized_ = false;
1707static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
1708static std::unordered_map<std::string, JNIHandler> jni_handlers_;
1709
Andreas Gampe799681b2015-05-15 19:24:12 -07001710void UnstartedRuntime::InitializeInvokeHandlers() {
1711#define UNSTARTED_DIRECT(ShortName, Sig) \
1712 invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
1713#include "unstarted_runtime_list.h"
1714 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
1715#undef UNSTARTED_RUNTIME_DIRECT_LIST
1716#undef UNSTARTED_RUNTIME_JNI_LIST
1717#undef UNSTARTED_DIRECT
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001718}
1719
Andreas Gampe799681b2015-05-15 19:24:12 -07001720void UnstartedRuntime::InitializeJNIHandlers() {
1721#define UNSTARTED_JNI(ShortName, Sig) \
1722 jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
1723#include "unstarted_runtime_list.h"
1724 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
1725#undef UNSTARTED_RUNTIME_DIRECT_LIST
1726#undef UNSTARTED_RUNTIME_JNI_LIST
1727#undef UNSTARTED_JNI
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001728}
1729
Andreas Gampe799681b2015-05-15 19:24:12 -07001730void UnstartedRuntime::Initialize() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001731 CHECK(!tables_initialized_);
1732
Andreas Gampe799681b2015-05-15 19:24:12 -07001733 InitializeInvokeHandlers();
1734 InitializeJNIHandlers();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001735
1736 tables_initialized_ = true;
1737}
1738
Andreas Gampe799681b2015-05-15 19:24:12 -07001739void UnstartedRuntime::Invoke(Thread* self, const DexFile::CodeItem* code_item,
1740 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001741 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
1742 // problems in core libraries.
1743 CHECK(tables_initialized_);
1744
1745 std::string name(PrettyMethod(shadow_frame->GetMethod()));
1746 const auto& iter = invoke_handlers_.find(name);
1747 if (iter != invoke_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001748 // Clear out the result in case it's not zeroed out.
1749 result->SetL(0);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001750
1751 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
1752 self->PushShadowFrame(shadow_frame);
1753
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001754 (*iter->second)(self, shadow_frame, result, arg_offset);
Andreas Gampe715fdc22016-04-18 17:07:30 -07001755
1756 self->PopShadowFrame();
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001757 } else {
1758 // Not special, continue with regular interpreter execution.
Andreas Gampe3cfa4d02015-10-06 17:04:01 -07001759 ArtInterpreterToInterpreterBridge(self, code_item, shadow_frame, result);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001760 }
1761}
1762
1763// 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 -07001764void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
Andreas Gampe799681b2015-05-15 19:24:12 -07001765 uint32_t* args, JValue* result) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001766 std::string name(PrettyMethod(method));
1767 const auto& iter = jni_handlers_.find(name);
1768 if (iter != jni_handlers_.end()) {
Kenny Root57f91e82015-05-14 15:58:17 -07001769 // Clear out the result in case it's not zeroed out.
1770 result->SetL(0);
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001771 (*iter->second)(self, method, receiver, args, result);
1772 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02001773 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
1774 name.c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001775 } else {
1776 LOG(FATAL) << "Calling native method " << PrettyMethod(method) << " in an unstarted "
1777 "non-transactional runtime";
1778 }
1779}
1780
1781} // namespace interpreter
1782} // namespace art