blob: 9039e3c6677098f2a60a657f63c78f787219e0c3 [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
19#include <cmath>
20#include <unordered_map>
21
Andreas Gampeaacc25d2015-04-01 14:49:06 -070022#include "ScopedLocalRef.h"
23
Andreas Gampe2969bcd2015-03-09 12:57:41 -070024#include "base/logging.h"
25#include "base/macros.h"
26#include "class_linker.h"
27#include "common_throws.h"
28#include "entrypoints/entrypoint_utils-inl.h"
29#include "handle_scope-inl.h"
30#include "interpreter/interpreter_common.h"
31#include "mirror/array-inl.h"
32#include "mirror/art_method-inl.h"
33#include "mirror/class.h"
Mathieu Chartierdaaf3262015-03-24 13:30:28 -070034#include "mirror/field-inl.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070035#include "mirror/object-inl.h"
36#include "mirror/object_array-inl.h"
37#include "mirror/string-inl.h"
38#include "nth_caller_visitor.h"
39#include "thread.h"
Sebastien Hertz2fd7e692015-04-02 11:11:19 +020040#include "transaction.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070041#include "well_known_classes.h"
Andreas Gampef778eb22015-04-13 14:17:09 -070042#include "zip_archive.h"
Andreas Gampe2969bcd2015-03-09 12:57:41 -070043
44namespace art {
45namespace interpreter {
46
Andreas Gampe068b0c02015-03-11 12:44:47 -070047static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
Sebastien Hertz45b15972015-04-03 16:07:05 +020048 __attribute__((__format__(__printf__, 2, 3)))
49 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
50
51static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
Andreas Gampe068b0c02015-03-11 12:44:47 -070052 va_list args;
Andreas Gampe068b0c02015-03-11 12:44:47 -070053 if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +020054 va_start(args, fmt);
55 AbortTransactionV(self, fmt, args);
Andreas Gampe068b0c02015-03-11 12:44:47 -070056 va_end(args);
57 } else {
Sebastien Hertz45b15972015-04-03 16:07:05 +020058 va_start(args, fmt);
59 std::string msg;
60 StringAppendV(&msg, fmt, args);
61 va_end(args);
62 LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
Andreas Gampe068b0c02015-03-11 12:44:47 -070063 UNREACHABLE();
64 }
65}
66
Andreas Gampe2969bcd2015-03-09 12:57:41 -070067// Helper function to deal with class loading in an unstarted runtime.
68static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
69 Handle<mirror::ClassLoader> class_loader, JValue* result,
70 const std::string& method_name, bool initialize_class,
71 bool abort_if_not_found)
72 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
73 CHECK(className.Get() != nullptr);
74 std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
75 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
76
77 mirror::Class* found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
78 if (found == nullptr && abort_if_not_found) {
79 if (!self->IsExceptionPending()) {
Andreas Gampe068b0c02015-03-11 12:44:47 -070080 AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
81 method_name.c_str(), PrettyDescriptor(descriptor.c_str()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -070082 }
83 return;
84 }
85 if (found != nullptr && initialize_class) {
86 StackHandleScope<1> hs(self);
87 Handle<mirror::Class> h_class(hs.NewHandle(found));
88 if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
89 CHECK(self->IsExceptionPending());
90 return;
91 }
92 }
93 result->SetL(found);
94}
95
96// Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
97// rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
98// ClassNotFoundException), so need to do the same. The only exception is if the exception is
Sebastien Hertz2fd7e692015-04-02 11:11:19 +020099// actually the transaction abort exception. This must not be wrapped, as it signals an
100// initialization abort.
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700101static void CheckExceptionGenerateClassNotFound(Thread* self)
102 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
103 if (self->IsExceptionPending()) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200104 // If it is not the transaction abort exception, wrap it.
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700105 std::string type(PrettyTypeOf(self->GetException()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200106 if (type != Transaction::kAbortExceptionDescriptor) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700107 self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
108 "ClassNotFoundException");
109 }
110 }
111}
112
Andreas Gampedd9d0552015-03-09 12:57:41 -0700113static void UnstartedClassForName(
114 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700115 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
116 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset)->AsString();
117 StackHandleScope<1> hs(self);
118 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
119 UnstartedRuntimeFindClass(self, h_class_name, NullHandle<mirror::ClassLoader>(), result,
120 "Class.forName", true, false);
121 CheckExceptionGenerateClassNotFound(self);
122}
123
Andreas Gampedd9d0552015-03-09 12:57:41 -0700124static void UnstartedClassForNameLong(
125 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700126 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
127 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset)->AsString();
128 bool initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
129 mirror::ClassLoader* class_loader =
130 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
131 StackHandleScope<2> hs(self);
132 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
133 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
134 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result, "Class.forName",
135 initialize_class, false);
136 CheckExceptionGenerateClassNotFound(self);
137}
138
Andreas Gampedd9d0552015-03-09 12:57:41 -0700139static void UnstartedClassClassForName(
140 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700141 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
142 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset)->AsString();
143 bool initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
144 mirror::ClassLoader* class_loader =
145 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
146 StackHandleScope<2> hs(self);
147 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
148 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
149 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result, "Class.classForName",
150 initialize_class, false);
151 CheckExceptionGenerateClassNotFound(self);
152}
153
Andreas Gampedd9d0552015-03-09 12:57:41 -0700154static void UnstartedClassNewInstance(
155 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700156 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
157 StackHandleScope<3> hs(self); // Class, constructor, object.
158 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
159 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700160
161 // Check that it's not null.
162 if (h_klass.Get() == nullptr) {
163 AbortTransactionOrFail(self, "Class reference is null for newInstance");
164 return;
165 }
166
167 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
168 if (Runtime::Current()->IsActiveTransaction()) {
169 if (h_klass.Get()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200170 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
171 PrettyClass(h_klass.Get()).c_str());
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700172 return;
173 }
174 }
175
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700176 // There are two situations in which we'll abort this run.
177 // 1) If the class isn't yet initialized and initialization fails.
178 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
179 // Note that 2) could likely be handled here, but for safety abort the transaction.
180 bool ok = false;
181 if (Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
182 Handle<mirror::ArtMethod> h_cons(hs.NewHandle(
183 h_klass->FindDeclaredDirectMethod("<init>", "()V")));
184 if (h_cons.Get() != nullptr) {
185 Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
186 CHECK(h_obj.Get() != nullptr); // We don't expect OOM at compile-time.
187 EnterInterpreterFromInvoke(self, h_cons.Get(), h_obj.Get(), nullptr, nullptr);
188 if (!self->IsExceptionPending()) {
189 result->SetL(h_obj.Get());
190 ok = true;
191 }
192 } else {
193 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
194 "Could not find default constructor for '%s'",
195 PrettyClass(h_klass.Get()).c_str());
196 }
197 }
198 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700199 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
200 PrettyClass(h_klass.Get()).c_str(),
201 PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700202 }
203}
204
Andreas Gampedd9d0552015-03-09 12:57:41 -0700205static void UnstartedClassGetDeclaredField(
206 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700207 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
208 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
209 // going the reflective Dex way.
210 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
211 mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700212 ArtField* found = nullptr;
213 ArtField* fields = klass->GetIFields();
214 for (int32_t i = 0, count = klass->NumInstanceFields(); i < count; ++i) {
215 ArtField* f = &fields[i];
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700216 if (name2->Equals(f->GetName())) {
217 found = f;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700218 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700219 }
220 }
221 if (found == nullptr) {
222 fields = klass->GetSFields();
Mathieu Chartierc7853442015-03-27 14:35:38 -0700223 for (int32_t i = 0, count = klass->NumStaticFields(); i < count; ++i) {
224 ArtField* f = &fields[i];
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700225 if (name2->Equals(f->GetName())) {
226 found = f;
Mathieu Chartierc7853442015-03-27 14:35:38 -0700227 break;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700228 }
229 }
230 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700231 if (found == nullptr) {
232 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
233 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
234 PrettyDescriptor(klass).c_str());
235 return;
236 }
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700237 if (Runtime::Current()->IsActiveTransaction()) {
238 result->SetL(mirror::Field::CreateFromArtField<true>(self, found, true));
239 } else {
240 result->SetL(mirror::Field::CreateFromArtField<false>(self, found, true));
241 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700242}
243
Andreas Gampedd9d0552015-03-09 12:57:41 -0700244static void UnstartedVmClassLoaderFindLoadedClass(
245 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700246 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
247 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
248 mirror::ClassLoader* class_loader =
249 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
250 StackHandleScope<2> hs(self);
251 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
252 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
253 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
254 "VMClassLoader.findLoadedClass", false, false);
255 // This might have an error pending. But semantics are to just return null.
256 if (self->IsExceptionPending()) {
257 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
258 std::string type(PrettyTypeOf(self->GetException()));
259 if (type != "java.lang.InternalError") {
260 self->ClearException();
261 }
262 }
263}
264
265static void UnstartedVoidLookupType(Thread* self ATTRIBUTE_UNUSED,
266 ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
267 JValue* result,
268 size_t arg_offset ATTRIBUTE_UNUSED)
269 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
270 result->SetL(Runtime::Current()->GetClassLinker()->FindPrimitiveClass('V'));
271}
272
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700273// Arraycopy emulation.
274// Note: we can't use any fast copy functions, as they are not available under transaction.
275
276template <typename T>
277static void PrimitiveArrayCopy(Thread* self,
278 mirror::Array* src_array, int32_t src_pos,
279 mirror::Array* dst_array, int32_t dst_pos,
280 int32_t length)
281 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
282 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
283 AbortTransactionOrFail(self, "Types mismatched in arraycopy: %s vs %s.",
284 PrettyDescriptor(src_array->GetClass()->GetComponentType()).c_str(),
285 PrettyDescriptor(dst_array->GetClass()->GetComponentType()).c_str());
286 return;
287 }
288 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
289 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
290 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
291 if (copy_forward) {
292 for (int32_t i = 0; i < length; ++i) {
293 dst->Set(dst_pos + i, src->Get(src_pos + i));
294 }
295 } else {
296 for (int32_t i = 1; i <= length; ++i) {
297 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
298 }
299 }
300}
301
Andreas Gampedd9d0552015-03-09 12:57:41 -0700302static void UnstartedSystemArraycopy(
303 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700304 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
305 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700306 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
307 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700308 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700309 mirror::Array* src_array = shadow_frame->GetVRegReference(arg_offset)->AsArray();
310 mirror::Array* dst_array = shadow_frame->GetVRegReference(arg_offset + 2)->AsArray();
311
312 // Null checking.
313 if (src_array == nullptr) {
314 AbortTransactionOrFail(self, "src is null in arraycopy.");
315 return;
316 }
317 if (dst_array == nullptr) {
318 AbortTransactionOrFail(self, "dst is null in arraycopy.");
319 return;
320 }
321
322 // Bounds checking.
323 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
324 UNLIKELY(src_pos > src_array->GetLength() - length) ||
325 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
326 self->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
327 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
328 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
329 length);
330 AbortTransactionOrFail(self, "Index out of bounds.");
331 return;
332 }
333
334 // Type checking.
335 mirror::Class* src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
336 GetComponentType();
337
338 if (!src_type->IsPrimitive()) {
339 // Check that the second type is not primitive.
340 mirror::Class* trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
341 GetComponentType();
342 if (trg_type->IsPrimitiveInt()) {
343 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
344 PrettyDescriptor(src_array->GetClass()->GetComponentType()).c_str(),
345 PrettyDescriptor(dst_array->GetClass()->GetComponentType()).c_str());
346 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700347 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700348
349 // For simplicity only do this if the component types are the same. Otherwise we have to copy
350 // even more code from the object-array functions.
351 if (src_type != trg_type) {
352 AbortTransactionOrFail(self, "Types not the same in arraycopy: %s vs %s",
353 PrettyDescriptor(src_array->GetClass()->GetComponentType()).c_str(),
354 PrettyDescriptor(dst_array->GetClass()->GetComponentType()).c_str());
355 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700356 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700357
358 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
359 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
360 if (src == dst) {
361 // Can overlap, but not have type mismatches.
362 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
363 if (copy_forward) {
364 for (int32_t i = 0; i < length; ++i) {
365 dst->Set(dst_pos + i, src->Get(src_pos + i));
366 }
367 } else {
368 for (int32_t i = 1; i <= length; ++i) {
369 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
370 }
371 }
372 } else {
373 // Can't overlap. Would need type checks, but we abort above.
374 for (int32_t i = 0; i < length; ++i) {
375 dst->Set(dst_pos + i, src->Get(src_pos + i));
376 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700377 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700378 } else if (src_type->IsPrimitiveChar()) {
379 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
380 } else if (src_type->IsPrimitiveInt()) {
381 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700382 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700383 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700384 PrettyDescriptor(src_type).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700385 }
386}
387
Andreas Gampedd9d0552015-03-09 12:57:41 -0700388static void UnstartedThreadLocalGet(
389 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700390 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
391 std::string caller(PrettyMethod(shadow_frame->GetLink()->GetMethod()));
392 bool ok = false;
393 if (caller == "java.lang.String java.lang.IntegralToString.convertInt"
394 "(java.lang.AbstractStringBuilder, int)") {
395 // Allocate non-threadlocal buffer.
396 result->SetL(mirror::CharArray::Alloc(self, 11));
397 ok = true;
398 } else if (caller == "java.lang.RealToString java.lang.RealToString.getInstance()") {
399 // Note: RealToString is implemented and used in a different fashion than IntegralToString.
400 // Conversion is done over an actual object of RealToString (the conversion method is an
401 // instance method). This means it is not as clear whether it is correct to return a new
402 // object each time. The caller needs to be inspected by hand to see whether it (incorrectly)
403 // stores the object for later use.
404 // See also b/19548084 for a possible rewrite and bringing it in line with IntegralToString.
405 if (shadow_frame->GetLink()->GetLink() != nullptr) {
406 std::string caller2(PrettyMethod(shadow_frame->GetLink()->GetLink()->GetMethod()));
407 if (caller2 == "java.lang.String java.lang.Double.toString(double)") {
408 // Allocate new object.
409 StackHandleScope<2> hs(self);
410 Handle<mirror::Class> h_real_to_string_class(hs.NewHandle(
411 shadow_frame->GetLink()->GetMethod()->GetDeclaringClass()));
412 Handle<mirror::Object> h_real_to_string_obj(hs.NewHandle(
413 h_real_to_string_class->AllocObject(self)));
414 if (h_real_to_string_obj.Get() != nullptr) {
415 mirror::ArtMethod* init_method =
416 h_real_to_string_class->FindDirectMethod("<init>", "()V");
417 if (init_method == nullptr) {
418 h_real_to_string_class->DumpClass(LOG(FATAL), mirror::Class::kDumpClassFullDetail);
419 } else {
420 JValue invoke_result;
421 EnterInterpreterFromInvoke(self, init_method, h_real_to_string_obj.Get(), nullptr,
422 nullptr);
423 if (!self->IsExceptionPending()) {
424 result->SetL(h_real_to_string_obj.Get());
425 ok = true;
426 }
427 }
428 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700429 }
430 }
431 }
432
433 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700434 AbortTransactionOrFail(self, "Could not create RealToString object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700435 }
436}
437
Andreas Gampedd9d0552015-03-09 12:57:41 -0700438static void UnstartedMathCeil(
439 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700440 double in = shadow_frame->GetVRegDouble(arg_offset);
441 double out;
442 // Special cases:
443 // 1) NaN, infinity, +0, -0 -> out := in. All are guaranteed by cmath.
444 // -1 < in < 0 -> out := -0.
445 if (-1.0 < in && in < 0) {
446 out = -0.0;
447 } else {
448 out = ceil(in);
449 }
450 result->SetD(out);
451}
452
Andreas Gampedd9d0552015-03-09 12:57:41 -0700453static void UnstartedArtMethodGetMethodName(
454 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700455 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
456 mirror::ArtMethod* method = shadow_frame->GetVRegReference(arg_offset)->AsArtMethod();
457 result->SetL(method->GetNameAsString(self));
458}
459
Andreas Gampedd9d0552015-03-09 12:57:41 -0700460static void UnstartedObjectHashCode(
461 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700462 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
463 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
464 result->SetI(obj->IdentityHashCode());
465}
466
Andreas Gampedd9d0552015-03-09 12:57:41 -0700467static void UnstartedDoubleDoubleToRawLongBits(
468 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700469 double in = shadow_frame->GetVRegDouble(arg_offset);
Roland Levillainda4d79b2015-03-24 14:36:11 +0000470 result->SetJ(bit_cast<int64_t, double>(in));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700471}
472
Andreas Gampedd9d0552015-03-09 12:57:41 -0700473static mirror::Object* GetDexFromDexCache(Thread* self, mirror::DexCache* dex_cache)
474 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
475 const DexFile* dex_file = dex_cache->GetDexFile();
476 if (dex_file == nullptr) {
477 return nullptr;
478 }
479
480 // Create the direct byte buffer.
481 JNIEnv* env = self->GetJniEnv();
482 DCHECK(env != nullptr);
483 void* address = const_cast<void*>(reinterpret_cast<const void*>(dex_file->Begin()));
Andreas Gampeaacc25d2015-04-01 14:49:06 -0700484 ScopedLocalRef<jobject> byte_buffer(env, env->NewDirectByteBuffer(address, dex_file->Size()));
485 if (byte_buffer.get() == nullptr) {
Andreas Gampedd9d0552015-03-09 12:57:41 -0700486 DCHECK(self->IsExceptionPending());
487 return nullptr;
488 }
489
490 jvalue args[1];
Andreas Gampeaacc25d2015-04-01 14:49:06 -0700491 args[0].l = byte_buffer.get();
492
493 ScopedLocalRef<jobject> dex(env, env->CallStaticObjectMethodA(
494 WellKnownClasses::com_android_dex_Dex,
495 WellKnownClasses::com_android_dex_Dex_create,
496 args));
497
498 return self->DecodeJObject(dex.get());
Andreas Gampedd9d0552015-03-09 12:57:41 -0700499}
500
501static void UnstartedDexCacheGetDexNative(
502 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
503 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
504 // We will create the Dex object, but the image writer will release it before creating the
505 // art file.
506 mirror::Object* src = shadow_frame->GetVRegReference(arg_offset);
507 bool have_dex = false;
508 if (src != nullptr) {
509 mirror::Object* dex = GetDexFromDexCache(self, reinterpret_cast<mirror::DexCache*>(src));
510 if (dex != nullptr) {
511 have_dex = true;
512 result->SetL(dex);
513 }
514 }
515 if (!have_dex) {
516 self->ClearException();
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200517 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Could not create Dex object");
Andreas Gampedd9d0552015-03-09 12:57:41 -0700518 }
519}
520
521static void UnstartedMemoryPeek(
522 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
523 int64_t address = shadow_frame->GetVRegLong(arg_offset);
524 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
525 // aborting the transaction.
526
527 switch (type) {
528 case Primitive::kPrimByte: {
529 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
530 return;
531 }
532
533 case Primitive::kPrimShort: {
534 result->SetS(*reinterpret_cast<int16_t*>(static_cast<intptr_t>(address)));
535 return;
536 }
537
538 case Primitive::kPrimInt: {
539 result->SetI(*reinterpret_cast<int32_t*>(static_cast<intptr_t>(address)));
540 return;
541 }
542
543 case Primitive::kPrimLong: {
544 result->SetJ(*reinterpret_cast<int64_t*>(static_cast<intptr_t>(address)));
545 return;
546 }
547
548 case Primitive::kPrimBoolean:
549 case Primitive::kPrimChar:
550 case Primitive::kPrimFloat:
551 case Primitive::kPrimDouble:
552 case Primitive::kPrimVoid:
553 case Primitive::kPrimNot:
554 LOG(FATAL) << "Not in the Memory API: " << type;
555 UNREACHABLE();
556 }
557 LOG(FATAL) << "Should not reach here";
558 UNREACHABLE();
559}
560
561static void UnstartedMemoryPeekEntry(
562 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
563 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
564 std::string name(PrettyMethod(shadow_frame->GetMethod()));
565 if (name == "byte libcore.io.Memory.peekByte(long)") {
566 UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
567 } else if (name == "short libcore.io.Memory.peekShortNative(long)") {
568 UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
569 } else if (name == "int libcore.io.Memory.peekIntNative(long)") {
570 UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
571 } else if (name == "long libcore.io.Memory.peekLongNative(long)") {
572 UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
573 } else {
574 LOG(FATAL) << "Unsupported Memory.peek entry: " << name;
575 UNREACHABLE();
576 }
577}
578
579static void UnstartedMemoryPeekArray(
580 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
581 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
582 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
583 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
584 if (obj == nullptr) {
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200585 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
Andreas Gampedd9d0552015-03-09 12:57:41 -0700586 return;
587 }
588 mirror::Array* array = obj->AsArray();
589
590 int offset = shadow_frame->GetVReg(arg_offset + 3);
591 int count = shadow_frame->GetVReg(arg_offset + 4);
592 if (offset < 0 || offset + count > array->GetLength()) {
593 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
594 offset, count, array->GetLength()));
Sebastien Hertz2fd7e692015-04-02 11:11:19 +0200595 Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
Andreas Gampedd9d0552015-03-09 12:57:41 -0700596 return;
597 }
598
599 switch (type) {
600 case Primitive::kPrimByte: {
601 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
602 mirror::ByteArray* byte_array = array->AsByteArray();
603 for (int32_t i = 0; i < count; ++i, ++address) {
604 byte_array->SetWithoutChecks<true>(i + offset, *address);
605 }
606 return;
607 }
608
609 case Primitive::kPrimShort:
610 case Primitive::kPrimInt:
611 case Primitive::kPrimLong:
612 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
613 UNREACHABLE();
614
615 case Primitive::kPrimBoolean:
616 case Primitive::kPrimChar:
617 case Primitive::kPrimFloat:
618 case Primitive::kPrimDouble:
619 case Primitive::kPrimVoid:
620 case Primitive::kPrimNot:
621 LOG(FATAL) << "Not in the Memory API: " << type;
622 UNREACHABLE();
623 }
624 LOG(FATAL) << "Should not reach here";
625 UNREACHABLE();
626}
627
628static void UnstartedMemoryPeekArrayEntry(
629 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
630 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
631 std::string name(PrettyMethod(shadow_frame->GetMethod()));
632 if (name == "void libcore.io.Memory.peekByteArray(long, byte[], int, int)") {
633 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
634 } else {
635 LOG(FATAL) << "Unsupported Memory.peekArray entry: " << name;
636 UNREACHABLE();
637 }
638}
639
Andreas Gampef778eb22015-04-13 14:17:09 -0700640// This allows reading security.properties in an unstarted runtime and initialize Security.
641static void UnstartedSecurityGetSecurityPropertiesReader(
642 Thread* self,
643 ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
644 JValue* result,
645 size_t arg_offset ATTRIBUTE_UNUSED)
646 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
647 Runtime* runtime = Runtime::Current();
648 const std::vector<const DexFile*>& path = runtime->GetClassLinker()->GetBootClassPath();
649 std::string canonical(DexFile::GetDexCanonicalLocation(path[0]->GetLocation().c_str()));
650 mirror::String* string_data;
651
652 // Use a block to enclose the I/O and MemMap code so buffers are released early.
653 {
654 std::string error_msg;
655 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(canonical.c_str(), &error_msg));
656 if (zip_archive.get() == nullptr) {
657 AbortTransactionOrFail(self, "Could not open zip file %s: %s", canonical.c_str(),
658 error_msg.c_str());
659 return;
660 }
661 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find("java/security/security.properties",
662 &error_msg));
663 if (zip_entry.get() == nullptr) {
664 AbortTransactionOrFail(self, "Could not find security.properties file in %s: %s",
665 canonical.c_str(), error_msg.c_str());
666 return;
667 }
668 std::unique_ptr<MemMap> map(zip_entry->ExtractToMemMap(canonical.c_str(),
669 "java/security/security.properties",
670 &error_msg));
671 if (map.get() == nullptr) {
672 AbortTransactionOrFail(self, "Could not unzip security.properties file in %s: %s",
673 canonical.c_str(), error_msg.c_str());
674 return;
675 }
676
677 uint32_t length = zip_entry->GetUncompressedLength();
678 std::unique_ptr<char[]> tmp(new char[length + 1]);
679 memcpy(tmp.get(), map->Begin(), length);
680 tmp.get()[length] = 0; // null terminator
681
682 string_data = mirror::String::AllocFromModifiedUtf8(self, tmp.get());
683 }
684
685 if (string_data == nullptr) {
686 AbortTransactionOrFail(self, "Could not create string from file content of %s",
687 canonical.c_str());
688 return;
689 }
690
691 // Create a StringReader.
692 StackHandleScope<3> hs(self);
693 Handle<mirror::String> h_string(hs.NewHandle(string_data));
694
695 Handle<mirror::Class> h_class(hs.NewHandle(
696 runtime->GetClassLinker()->FindClass(self,
697 "Ljava/io/StringReader;",
698 NullHandle<mirror::ClassLoader>())));
699 if (h_class.Get() == nullptr) {
700 AbortTransactionOrFail(self, "Could not find StringReader class");
701 return;
702 }
703
704 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
705 AbortTransactionOrFail(self, "Could not initialize StringReader class");
706 return;
707 }
708
709 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
710 if (h_obj.Get() == nullptr) {
711 AbortTransactionOrFail(self, "Could not allocate StringReader object");
712 return;
713 }
714
715 mirror::ArtMethod* constructor = h_class->FindDeclaredDirectMethod("<init>",
716 "(Ljava/lang/String;)V");
717 if (constructor == nullptr) {
718 AbortTransactionOrFail(self, "Could not find StringReader constructor");
719 return;
720 }
721
722 uint32_t args[1];
723 args[0] = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_string.Get()));
724 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
725
726 if (self->IsExceptionPending()) {
727 AbortTransactionOrFail(self, "Could not run StringReader constructor");
728 return;
729 }
730
731 result->SetL(h_obj.Get());
732}
733
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700734static void UnstartedJNIVMRuntimeNewUnpaddedArray(Thread* self,
735 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
736 mirror::Object* receiver ATTRIBUTE_UNUSED,
737 uint32_t* args,
738 JValue* result)
739 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
740 int32_t length = args[1];
741 DCHECK_GE(length, 0);
742 mirror::Class* element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
743 Runtime* runtime = Runtime::Current();
744 mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(self, &element_class);
745 DCHECK(array_class != nullptr);
746 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
747 result->SetL(mirror::Array::Alloc<true, true>(self, array_class, length,
748 array_class->GetComponentSizeShift(), allocator));
749}
750
751static void UnstartedJNIVMStackGetCallingClassLoader(Thread* self ATTRIBUTE_UNUSED,
752 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
753 mirror::Object* receiver ATTRIBUTE_UNUSED,
754 uint32_t* args ATTRIBUTE_UNUSED,
755 JValue* result) {
756 result->SetL(nullptr);
757}
758
759static void UnstartedJNIVMStackGetStackClass2(Thread* self,
760 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
761 mirror::Object* receiver ATTRIBUTE_UNUSED,
762 uint32_t* args ATTRIBUTE_UNUSED,
763 JValue* result)
764 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
765 NthCallerVisitor visitor(self, 3);
766 visitor.WalkStack();
767 if (visitor.caller != nullptr) {
768 result->SetL(visitor.caller->GetDeclaringClass());
769 }
770}
771
772static void UnstartedJNIMathLog(Thread* self ATTRIBUTE_UNUSED,
773 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
774 mirror::Object* receiver ATTRIBUTE_UNUSED,
775 uint32_t* args,
776 JValue* result) {
777 JValue value;
778 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
779 result->SetD(log(value.GetD()));
780}
781
782static void UnstartedJNIMathExp(Thread* self ATTRIBUTE_UNUSED,
783 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
784 mirror::Object* receiver ATTRIBUTE_UNUSED,
785 uint32_t* args,
786 JValue* result) {
787 JValue value;
788 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
789 result->SetD(exp(value.GetD()));
790}
791
792static void UnstartedJNIClassGetNameNative(Thread* self,
793 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
794 mirror::Object* receiver,
795 uint32_t* args ATTRIBUTE_UNUSED,
796 JValue* result)
797 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
798 StackHandleScope<1> hs(self);
799 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
800}
801
802static void UnstartedJNIFloatFloatToRawIntBits(Thread* self ATTRIBUTE_UNUSED,
803 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
804 mirror::Object* receiver ATTRIBUTE_UNUSED,
805 uint32_t* args,
806 JValue* result) {
807 result->SetI(args[0]);
808}
809
810static void UnstartedJNIFloatIntBitsToFloat(Thread* self ATTRIBUTE_UNUSED,
811 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
812 mirror::Object* receiver ATTRIBUTE_UNUSED,
813 uint32_t* args,
814 JValue* result) {
815 result->SetI(args[0]);
816}
817
Andreas Gampeca714582015-04-03 19:41:34 -0700818static void UnstartedJNIObjectInternalClone(Thread* self,
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700819 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
820 mirror::Object* receiver,
821 uint32_t* args ATTRIBUTE_UNUSED,
822 JValue* result)
823 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
824 result->SetL(receiver->Clone(self));
825}
826
Andreas Gampeca714582015-04-03 19:41:34 -0700827static void UnstartedJNIObjectNotifyAll(Thread* self,
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700828 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
829 mirror::Object* receiver,
830 uint32_t* args ATTRIBUTE_UNUSED,
831 JValue* result ATTRIBUTE_UNUSED)
832 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
833 receiver->NotifyAll(self);
834}
835
836static void UnstartedJNIStringCompareTo(Thread* self,
837 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
838 mirror::Object* receiver,
839 uint32_t* args,
840 JValue* result)
841 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
842 mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
843 if (rhs == nullptr) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700844 AbortTransactionOrFail(self, "String.compareTo with null object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700845 }
846 result->SetI(receiver->AsString()->CompareTo(rhs));
847}
848
849static void UnstartedJNIStringIntern(Thread* self ATTRIBUTE_UNUSED,
850 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
851 mirror::Object* receiver,
852 uint32_t* args ATTRIBUTE_UNUSED,
853 JValue* result)
854 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
855 result->SetL(receiver->AsString()->Intern());
856}
857
858static void UnstartedJNIStringFastIndexOf(Thread* self ATTRIBUTE_UNUSED,
859 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
860 mirror::Object* receiver,
861 uint32_t* args,
862 JValue* result)
863 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
864 result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1]));
865}
866
867static void UnstartedJNIArrayCreateMultiArray(Thread* self,
868 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
869 mirror::Object* receiver ATTRIBUTE_UNUSED,
870 uint32_t* args,
871 JValue* result)
872 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
873 StackHandleScope<2> hs(self);
874 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
875 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
876 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
877}
878
Andreas Gampee598e042015-04-10 14:57:10 -0700879static void UnstartedJNIArrayCreateObjectArray(Thread* self,
880 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
881 mirror::Object* receiver ATTRIBUTE_UNUSED,
882 uint32_t* args,
883 JValue* result)
884 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
885 int32_t length = static_cast<int32_t>(args[1]);
886 if (length < 0) {
887 ThrowNegativeArraySizeException(length);
888 return;
889 }
890 mirror::Class* element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
891 Runtime* runtime = Runtime::Current();
892 ClassLinker* class_linker = runtime->GetClassLinker();
893 mirror::Class* array_class = class_linker->FindArrayClass(self, &element_class);
894 if (UNLIKELY(array_class == NULL)) {
895 CHECK(self->IsExceptionPending());
896 return;
897 }
898 DCHECK(array_class->IsObjectArrayClass());
899 mirror::Array* new_array = mirror::ObjectArray<mirror::Object*>::Alloc(
900 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
901 result->SetL(new_array);
902}
903
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700904static void UnstartedJNIThrowableNativeFillInStackTrace(Thread* self,
905 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
906 mirror::Object* receiver ATTRIBUTE_UNUSED,
907 uint32_t* args ATTRIBUTE_UNUSED,
908 JValue* result)
909 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
910 ScopedObjectAccessUnchecked soa(self);
911 if (Runtime::Current()->IsActiveTransaction()) {
912 result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<true>(soa)));
913 } else {
914 result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<false>(soa)));
915 }
916}
917
918static void UnstartedJNISystemIdentityHashCode(Thread* self ATTRIBUTE_UNUSED,
919 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
920 mirror::Object* receiver ATTRIBUTE_UNUSED,
921 uint32_t* args,
922 JValue* result)
923 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
924 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
925 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
926}
927
928static void UnstartedJNIByteOrderIsLittleEndian(Thread* self ATTRIBUTE_UNUSED,
929 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
930 mirror::Object* receiver ATTRIBUTE_UNUSED,
931 uint32_t* args ATTRIBUTE_UNUSED,
932 JValue* result) {
933 result->SetZ(JNI_TRUE);
934}
935
936static void UnstartedJNIUnsafeCompareAndSwapInt(Thread* self ATTRIBUTE_UNUSED,
937 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
938 mirror::Object* receiver ATTRIBUTE_UNUSED,
939 uint32_t* args,
940 JValue* result)
941 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
942 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
943 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
944 jint expectedValue = args[3];
945 jint newValue = args[4];
946 bool success;
947 if (Runtime::Current()->IsActiveTransaction()) {
948 success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
949 expectedValue, newValue);
950 } else {
951 success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
952 expectedValue, newValue);
953 }
954 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
955}
956
957static void UnstartedJNIUnsafePutObject(Thread* self ATTRIBUTE_UNUSED,
958 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
959 mirror::Object* receiver ATTRIBUTE_UNUSED,
960 uint32_t* args,
961 JValue* result ATTRIBUTE_UNUSED)
962 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
963 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
964 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
965 mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
966 if (Runtime::Current()->IsActiveTransaction()) {
967 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
968 } else {
969 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
970 }
971}
972
973static void UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
974 Thread* self ATTRIBUTE_UNUSED,
975 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
976 mirror::Object* receiver ATTRIBUTE_UNUSED,
977 uint32_t* args,
978 JValue* result)
979 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
980 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
981 Primitive::Type primitive_type = component->GetPrimitiveType();
982 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
983}
984
985static void UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
986 Thread* self ATTRIBUTE_UNUSED,
987 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
988 mirror::Object* receiver ATTRIBUTE_UNUSED,
989 uint32_t* args,
990 JValue* result)
991 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
992 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
993 Primitive::Type primitive_type = component->GetPrimitiveType();
994 result->SetI(Primitive::ComponentSize(primitive_type));
995}
996
Andreas Gampedd9d0552015-03-09 12:57:41 -0700997typedef void (*InvokeHandler)(Thread* self, ShadowFrame* shadow_frame, JValue* result,
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700998 size_t arg_size);
999
Andreas Gampedd9d0552015-03-09 12:57:41 -07001000typedef void (*JNIHandler)(Thread* self, mirror::ArtMethod* method, mirror::Object* receiver,
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001001 uint32_t* args, JValue* result);
1002
1003static bool tables_initialized_ = false;
1004static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
1005static std::unordered_map<std::string, JNIHandler> jni_handlers_;
1006
1007static void UnstartedRuntimeInitializeInvokeHandlers() {
1008 struct InvokeHandlerDef {
1009 std::string name;
1010 InvokeHandler function;
1011 };
1012
1013 InvokeHandlerDef defs[] {
1014 { "java.lang.Class java.lang.Class.forName(java.lang.String)",
1015 &UnstartedClassForName },
1016 { "java.lang.Class java.lang.Class.forName(java.lang.String, boolean, java.lang.ClassLoader)",
1017 &UnstartedClassForNameLong },
1018 { "java.lang.Class java.lang.Class.classForName(java.lang.String, boolean, java.lang.ClassLoader)",
1019 &UnstartedClassClassForName },
1020 { "java.lang.Class java.lang.VMClassLoader.findLoadedClass(java.lang.ClassLoader, java.lang.String)",
1021 &UnstartedVmClassLoaderFindLoadedClass },
1022 { "java.lang.Class java.lang.Void.lookupType()",
1023 &UnstartedVoidLookupType },
1024 { "java.lang.Object java.lang.Class.newInstance()",
1025 &UnstartedClassNewInstance },
1026 { "java.lang.reflect.Field java.lang.Class.getDeclaredField(java.lang.String)",
1027 &UnstartedClassGetDeclaredField },
1028 { "int java.lang.Object.hashCode()",
1029 &UnstartedObjectHashCode },
1030 { "java.lang.String java.lang.reflect.ArtMethod.getMethodName(java.lang.reflect.ArtMethod)",
1031 &UnstartedArtMethodGetMethodName },
1032 { "void java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int)",
1033 &UnstartedSystemArraycopy},
1034 { "void java.lang.System.arraycopy(char[], int, char[], int, int)",
1035 &UnstartedSystemArraycopy },
1036 { "void java.lang.System.arraycopy(int[], int, int[], int, int)",
1037 &UnstartedSystemArraycopy },
1038 { "long java.lang.Double.doubleToRawLongBits(double)",
1039 &UnstartedDoubleDoubleToRawLongBits },
1040 { "double java.lang.Math.ceil(double)",
1041 &UnstartedMathCeil },
1042 { "java.lang.Object java.lang.ThreadLocal.get()",
1043 &UnstartedThreadLocalGet },
Andreas Gampedd9d0552015-03-09 12:57:41 -07001044 { "com.android.dex.Dex java.lang.DexCache.getDexNative()",
1045 &UnstartedDexCacheGetDexNative },
1046 { "byte libcore.io.Memory.peekByte(long)",
1047 &UnstartedMemoryPeekEntry },
1048 { "short libcore.io.Memory.peekShortNative(long)",
1049 &UnstartedMemoryPeekEntry },
1050 { "int libcore.io.Memory.peekIntNative(long)",
1051 &UnstartedMemoryPeekEntry },
1052 { "long libcore.io.Memory.peekLongNative(long)",
1053 &UnstartedMemoryPeekEntry },
1054 { "void libcore.io.Memory.peekByteArray(long, byte[], int, int)",
1055 &UnstartedMemoryPeekArrayEntry },
Andreas Gampef778eb22015-04-13 14:17:09 -07001056 { "java.io.Reader java.security.Security.getSecurityPropertiesReader()",
1057 &UnstartedSecurityGetSecurityPropertiesReader },
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001058 };
1059
1060 for (auto& def : defs) {
1061 invoke_handlers_.insert(std::make_pair(def.name, def.function));
1062 }
1063}
1064
1065static void UnstartedRuntimeInitializeJNIHandlers() {
1066 struct JNIHandlerDef {
1067 std::string name;
1068 JNIHandler function;
1069 };
1070
1071 JNIHandlerDef defs[] {
1072 { "java.lang.Object dalvik.system.VMRuntime.newUnpaddedArray(java.lang.Class, int)",
1073 &UnstartedJNIVMRuntimeNewUnpaddedArray },
1074 { "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()",
1075 &UnstartedJNIVMStackGetCallingClassLoader },
1076 { "java.lang.Class dalvik.system.VMStack.getStackClass2()",
1077 &UnstartedJNIVMStackGetStackClass2 },
1078 { "double java.lang.Math.log(double)",
1079 &UnstartedJNIMathLog },
1080 { "java.lang.String java.lang.Class.getNameNative()",
1081 &UnstartedJNIClassGetNameNative },
1082 { "int java.lang.Float.floatToRawIntBits(float)",
1083 &UnstartedJNIFloatFloatToRawIntBits },
1084 { "float java.lang.Float.intBitsToFloat(int)",
1085 &UnstartedJNIFloatIntBitsToFloat },
1086 { "double java.lang.Math.exp(double)",
1087 &UnstartedJNIMathExp },
1088 { "java.lang.Object java.lang.Object.internalClone()",
1089 &UnstartedJNIObjectInternalClone },
1090 { "void java.lang.Object.notifyAll()",
1091 &UnstartedJNIObjectNotifyAll},
1092 { "int java.lang.String.compareTo(java.lang.String)",
1093 &UnstartedJNIStringCompareTo },
1094 { "java.lang.String java.lang.String.intern()",
1095 &UnstartedJNIStringIntern },
1096 { "int java.lang.String.fastIndexOf(int, int)",
1097 &UnstartedJNIStringFastIndexOf },
1098 { "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])",
1099 &UnstartedJNIArrayCreateMultiArray },
Andreas Gampee598e042015-04-10 14:57:10 -07001100 { "java.lang.Object java.lang.reflect.Array.createObjectArray(java.lang.Class, int)",
1101 &UnstartedJNIArrayCreateObjectArray },
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001102 { "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()",
1103 &UnstartedJNIThrowableNativeFillInStackTrace },
1104 { "int java.lang.System.identityHashCode(java.lang.Object)",
1105 &UnstartedJNISystemIdentityHashCode },
1106 { "boolean java.nio.ByteOrder.isLittleEndian()",
1107 &UnstartedJNIByteOrderIsLittleEndian },
1108 { "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)",
1109 &UnstartedJNIUnsafeCompareAndSwapInt },
1110 { "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)",
1111 &UnstartedJNIUnsafePutObject },
1112 { "int sun.misc.Unsafe.getArrayBaseOffsetForComponentType(java.lang.Class)",
1113 &UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType },
1114 { "int sun.misc.Unsafe.getArrayIndexScaleForComponentType(java.lang.Class)",
1115 &UnstartedJNIUnsafeGetArrayIndexScaleForComponentType },
1116 };
1117
1118 for (auto& def : defs) {
1119 jni_handlers_.insert(std::make_pair(def.name, def.function));
1120 }
1121}
1122
1123void UnstartedRuntimeInitialize() {
1124 CHECK(!tables_initialized_);
1125
1126 UnstartedRuntimeInitializeInvokeHandlers();
1127 UnstartedRuntimeInitializeJNIHandlers();
1128
1129 tables_initialized_ = true;
1130}
1131
1132void UnstartedRuntimeInvoke(Thread* self, const DexFile::CodeItem* code_item,
1133 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1134 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
1135 // problems in core libraries.
1136 CHECK(tables_initialized_);
1137
1138 std::string name(PrettyMethod(shadow_frame->GetMethod()));
1139 const auto& iter = invoke_handlers_.find(name);
1140 if (iter != invoke_handlers_.end()) {
1141 (*iter->second)(self, shadow_frame, result, arg_offset);
1142 } else {
1143 // Not special, continue with regular interpreter execution.
1144 artInterpreterToInterpreterBridge(self, code_item, shadow_frame, result);
1145 }
1146}
1147
1148// Hand select a number of methods to be run in a not yet started runtime without using JNI.
1149void UnstartedRuntimeJni(Thread* self, mirror::ArtMethod* method, mirror::Object* receiver,
1150 uint32_t* args, JValue* result) {
1151 std::string name(PrettyMethod(method));
1152 const auto& iter = jni_handlers_.find(name);
1153 if (iter != jni_handlers_.end()) {
1154 (*iter->second)(self, method, receiver, args, result);
1155 } else if (Runtime::Current()->IsActiveTransaction()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +02001156 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
1157 name.c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -07001158 } else {
1159 LOG(FATAL) << "Calling native method " << PrettyMethod(method) << " in an unstarted "
1160 "non-transactional runtime";
1161 }
1162}
1163
1164} // namespace interpreter
1165} // namespace art