blob: 98dfdbd2ea0556cfdbb702ec6982c23671b1ff0f [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
22#include "base/logging.h"
23#include "base/macros.h"
24#include "class_linker.h"
25#include "common_throws.h"
26#include "entrypoints/entrypoint_utils-inl.h"
27#include "handle_scope-inl.h"
28#include "interpreter/interpreter_common.h"
29#include "mirror/array-inl.h"
30#include "mirror/art_method-inl.h"
31#include "mirror/class.h"
32#include "mirror/object-inl.h"
33#include "mirror/object_array-inl.h"
34#include "mirror/string-inl.h"
35#include "nth_caller_visitor.h"
36#include "thread.h"
37#include "well_known_classes.h"
38
39namespace art {
40namespace interpreter {
41
Andreas Gampe068b0c02015-03-11 12:44:47 -070042static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
43 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
44 va_list args;
45 va_start(args, fmt);
46 if (Runtime::Current()->IsActiveTransaction()) {
47 AbortTransaction(self, fmt, args);
48 va_end(args);
49 } else {
50 LOG(FATAL) << "Trying to abort, but not in transaction mode: " << StringPrintf(fmt, args);
51 UNREACHABLE();
52 }
53}
54
Andreas Gampe2969bcd2015-03-09 12:57:41 -070055// Helper function to deal with class loading in an unstarted runtime.
56static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
57 Handle<mirror::ClassLoader> class_loader, JValue* result,
58 const std::string& method_name, bool initialize_class,
59 bool abort_if_not_found)
60 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
61 CHECK(className.Get() != nullptr);
62 std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
63 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
64
65 mirror::Class* found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
66 if (found == nullptr && abort_if_not_found) {
67 if (!self->IsExceptionPending()) {
Andreas Gampe068b0c02015-03-11 12:44:47 -070068 AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
69 method_name.c_str(), PrettyDescriptor(descriptor.c_str()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -070070 }
71 return;
72 }
73 if (found != nullptr && initialize_class) {
74 StackHandleScope<1> hs(self);
75 Handle<mirror::Class> h_class(hs.NewHandle(found));
76 if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
77 CHECK(self->IsExceptionPending());
78 return;
79 }
80 }
81 result->SetL(found);
82}
83
84// Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
85// rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
86// ClassNotFoundException), so need to do the same. The only exception is if the exception is
87// actually InternalError. This must not be wrapped, as it signals an initialization abort.
88static void CheckExceptionGenerateClassNotFound(Thread* self)
89 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
90 if (self->IsExceptionPending()) {
91 // If it is not an InternalError, wrap it.
92 std::string type(PrettyTypeOf(self->GetException()));
93 if (type != "java.lang.InternalError") {
94 self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
95 "ClassNotFoundException");
96 }
97 }
98}
99
Andreas Gampedd9d0552015-03-09 12:57:41 -0700100static void UnstartedClassForName(
101 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700102 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
103 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset)->AsString();
104 StackHandleScope<1> hs(self);
105 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
106 UnstartedRuntimeFindClass(self, h_class_name, NullHandle<mirror::ClassLoader>(), result,
107 "Class.forName", true, false);
108 CheckExceptionGenerateClassNotFound(self);
109}
110
Andreas Gampedd9d0552015-03-09 12:57:41 -0700111static void UnstartedClassForNameLong(
112 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700113 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
114 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset)->AsString();
115 bool initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
116 mirror::ClassLoader* class_loader =
117 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
118 StackHandleScope<2> hs(self);
119 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
120 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
121 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result, "Class.forName",
122 initialize_class, false);
123 CheckExceptionGenerateClassNotFound(self);
124}
125
Andreas Gampedd9d0552015-03-09 12:57:41 -0700126static void UnstartedClassClassForName(
127 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700128 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
129 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset)->AsString();
130 bool initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
131 mirror::ClassLoader* class_loader =
132 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
133 StackHandleScope<2> hs(self);
134 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
135 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
136 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result, "Class.classForName",
137 initialize_class, false);
138 CheckExceptionGenerateClassNotFound(self);
139}
140
Andreas Gampedd9d0552015-03-09 12:57:41 -0700141static void UnstartedClassNewInstance(
142 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700143 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
144 StackHandleScope<3> hs(self); // Class, constructor, object.
145 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
146 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Andreas Gampe0f7e3d62015-03-11 13:24:35 -0700147
148 // Check that it's not null.
149 if (h_klass.Get() == nullptr) {
150 AbortTransactionOrFail(self, "Class reference is null for newInstance");
151 return;
152 }
153
154 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
155 if (Runtime::Current()->IsActiveTransaction()) {
156 if (h_klass.Get()->IsFinalizable()) {
157 AbortTransaction(self, "Class for newInstance is finalizable: '%s'",
158 PrettyClass(h_klass.Get()).c_str());
159 return;
160 }
161 }
162
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700163 // There are two situations in which we'll abort this run.
164 // 1) If the class isn't yet initialized and initialization fails.
165 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
166 // Note that 2) could likely be handled here, but for safety abort the transaction.
167 bool ok = false;
168 if (Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
169 Handle<mirror::ArtMethod> h_cons(hs.NewHandle(
170 h_klass->FindDeclaredDirectMethod("<init>", "()V")));
171 if (h_cons.Get() != nullptr) {
172 Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
173 CHECK(h_obj.Get() != nullptr); // We don't expect OOM at compile-time.
174 EnterInterpreterFromInvoke(self, h_cons.Get(), h_obj.Get(), nullptr, nullptr);
175 if (!self->IsExceptionPending()) {
176 result->SetL(h_obj.Get());
177 ok = true;
178 }
179 } else {
180 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
181 "Could not find default constructor for '%s'",
182 PrettyClass(h_klass.Get()).c_str());
183 }
184 }
185 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700186 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
187 PrettyClass(h_klass.Get()).c_str(),
188 PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700189 }
190}
191
Andreas Gampedd9d0552015-03-09 12:57:41 -0700192static void UnstartedClassGetDeclaredField(
193 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700194 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
195 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
196 // going the reflective Dex way.
197 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
198 mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
199 mirror::ArtField* found = nullptr;
200 mirror::ObjectArray<mirror::ArtField>* fields = klass->GetIFields();
201 for (int32_t i = 0; i < fields->GetLength() && found == nullptr; ++i) {
202 mirror::ArtField* f = fields->Get(i);
203 if (name2->Equals(f->GetName())) {
204 found = f;
205 }
206 }
207 if (found == nullptr) {
208 fields = klass->GetSFields();
209 for (int32_t i = 0; i < fields->GetLength() && found == nullptr; ++i) {
210 mirror::ArtField* f = fields->Get(i);
211 if (name2->Equals(f->GetName())) {
212 found = f;
213 }
214 }
215 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700216 if (found == nullptr) {
217 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
218 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
219 PrettyDescriptor(klass).c_str());
220 return;
221 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700222 // TODO: getDeclaredField calls GetType once the field is found to ensure a
223 // NoClassDefFoundError is thrown if the field's type cannot be resolved.
224 mirror::Class* jlr_Field = self->DecodeJObject(
225 WellKnownClasses::java_lang_reflect_Field)->AsClass();
226 StackHandleScope<1> hs(self);
227 Handle<mirror::Object> field(hs.NewHandle(jlr_Field->AllocNonMovableObject(self)));
228 CHECK(field.Get() != nullptr);
229 mirror::ArtMethod* c = jlr_Field->FindDeclaredDirectMethod("<init>",
230 "(Ljava/lang/reflect/ArtField;)V");
231 uint32_t args[1];
232 args[0] = StackReference<mirror::Object>::FromMirrorPtr(found).AsVRegValue();
233 EnterInterpreterFromInvoke(self, c, field.Get(), args, nullptr);
234 result->SetL(field.Get());
235}
236
Andreas Gampedd9d0552015-03-09 12:57:41 -0700237static void UnstartedVmClassLoaderFindLoadedClass(
238 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700239 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
240 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
241 mirror::ClassLoader* class_loader =
242 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
243 StackHandleScope<2> hs(self);
244 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
245 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
246 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
247 "VMClassLoader.findLoadedClass", false, false);
248 // This might have an error pending. But semantics are to just return null.
249 if (self->IsExceptionPending()) {
250 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
251 std::string type(PrettyTypeOf(self->GetException()));
252 if (type != "java.lang.InternalError") {
253 self->ClearException();
254 }
255 }
256}
257
258static void UnstartedVoidLookupType(Thread* self ATTRIBUTE_UNUSED,
259 ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
260 JValue* result,
261 size_t arg_offset ATTRIBUTE_UNUSED)
262 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
263 result->SetL(Runtime::Current()->GetClassLinker()->FindPrimitiveClass('V'));
264}
265
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700266// Arraycopy emulation.
267// Note: we can't use any fast copy functions, as they are not available under transaction.
268
269template <typename T>
270static void PrimitiveArrayCopy(Thread* self,
271 mirror::Array* src_array, int32_t src_pos,
272 mirror::Array* dst_array, int32_t dst_pos,
273 int32_t length)
274 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
275 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
276 AbortTransactionOrFail(self, "Types mismatched in arraycopy: %s vs %s.",
277 PrettyDescriptor(src_array->GetClass()->GetComponentType()).c_str(),
278 PrettyDescriptor(dst_array->GetClass()->GetComponentType()).c_str());
279 return;
280 }
281 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
282 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
283 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
284 if (copy_forward) {
285 for (int32_t i = 0; i < length; ++i) {
286 dst->Set(dst_pos + i, src->Get(src_pos + i));
287 }
288 } else {
289 for (int32_t i = 1; i <= length; ++i) {
290 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
291 }
292 }
293}
294
Andreas Gampedd9d0552015-03-09 12:57:41 -0700295static void UnstartedSystemArraycopy(
296 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700297 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
298 // Special case array copying without initializing System.
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700299 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
300 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700301 jint length = shadow_frame->GetVReg(arg_offset + 4);
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700302 mirror::Array* src_array = shadow_frame->GetVRegReference(arg_offset)->AsArray();
303 mirror::Array* dst_array = shadow_frame->GetVRegReference(arg_offset + 2)->AsArray();
304
305 // Null checking.
306 if (src_array == nullptr) {
307 AbortTransactionOrFail(self, "src is null in arraycopy.");
308 return;
309 }
310 if (dst_array == nullptr) {
311 AbortTransactionOrFail(self, "dst is null in arraycopy.");
312 return;
313 }
314
315 // Bounds checking.
316 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
317 UNLIKELY(src_pos > src_array->GetLength() - length) ||
318 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
319 self->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
320 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
321 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
322 length);
323 AbortTransactionOrFail(self, "Index out of bounds.");
324 return;
325 }
326
327 // Type checking.
328 mirror::Class* src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
329 GetComponentType();
330
331 if (!src_type->IsPrimitive()) {
332 // Check that the second type is not primitive.
333 mirror::Class* trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
334 GetComponentType();
335 if (trg_type->IsPrimitiveInt()) {
336 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
337 PrettyDescriptor(src_array->GetClass()->GetComponentType()).c_str(),
338 PrettyDescriptor(dst_array->GetClass()->GetComponentType()).c_str());
339 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700340 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700341
342 // For simplicity only do this if the component types are the same. Otherwise we have to copy
343 // even more code from the object-array functions.
344 if (src_type != trg_type) {
345 AbortTransactionOrFail(self, "Types not the same in arraycopy: %s vs %s",
346 PrettyDescriptor(src_array->GetClass()->GetComponentType()).c_str(),
347 PrettyDescriptor(dst_array->GetClass()->GetComponentType()).c_str());
348 return;
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700349 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700350
351 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
352 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
353 if (src == dst) {
354 // Can overlap, but not have type mismatches.
355 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
356 if (copy_forward) {
357 for (int32_t i = 0; i < length; ++i) {
358 dst->Set(dst_pos + i, src->Get(src_pos + i));
359 }
360 } else {
361 for (int32_t i = 1; i <= length; ++i) {
362 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
363 }
364 }
365 } else {
366 // Can't overlap. Would need type checks, but we abort above.
367 for (int32_t i = 0; i < length; ++i) {
368 dst->Set(dst_pos + i, src->Get(src_pos + i));
369 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700370 }
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700371 } else if (src_type->IsPrimitiveChar()) {
372 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
373 } else if (src_type->IsPrimitiveInt()) {
374 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700375 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700376 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
Andreas Gampe8e6c3fd2015-03-11 18:34:44 -0700377 PrettyDescriptor(src_type).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700378 }
379}
380
Andreas Gampedd9d0552015-03-09 12:57:41 -0700381static void UnstartedThreadLocalGet(
382 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700383 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
384 std::string caller(PrettyMethod(shadow_frame->GetLink()->GetMethod()));
385 bool ok = false;
386 if (caller == "java.lang.String java.lang.IntegralToString.convertInt"
387 "(java.lang.AbstractStringBuilder, int)") {
388 // Allocate non-threadlocal buffer.
389 result->SetL(mirror::CharArray::Alloc(self, 11));
390 ok = true;
391 } else if (caller == "java.lang.RealToString java.lang.RealToString.getInstance()") {
392 // Note: RealToString is implemented and used in a different fashion than IntegralToString.
393 // Conversion is done over an actual object of RealToString (the conversion method is an
394 // instance method). This means it is not as clear whether it is correct to return a new
395 // object each time. The caller needs to be inspected by hand to see whether it (incorrectly)
396 // stores the object for later use.
397 // See also b/19548084 for a possible rewrite and bringing it in line with IntegralToString.
398 if (shadow_frame->GetLink()->GetLink() != nullptr) {
399 std::string caller2(PrettyMethod(shadow_frame->GetLink()->GetLink()->GetMethod()));
400 if (caller2 == "java.lang.String java.lang.Double.toString(double)") {
401 // Allocate new object.
402 StackHandleScope<2> hs(self);
403 Handle<mirror::Class> h_real_to_string_class(hs.NewHandle(
404 shadow_frame->GetLink()->GetMethod()->GetDeclaringClass()));
405 Handle<mirror::Object> h_real_to_string_obj(hs.NewHandle(
406 h_real_to_string_class->AllocObject(self)));
407 if (h_real_to_string_obj.Get() != nullptr) {
408 mirror::ArtMethod* init_method =
409 h_real_to_string_class->FindDirectMethod("<init>", "()V");
410 if (init_method == nullptr) {
411 h_real_to_string_class->DumpClass(LOG(FATAL), mirror::Class::kDumpClassFullDetail);
412 } else {
413 JValue invoke_result;
414 EnterInterpreterFromInvoke(self, init_method, h_real_to_string_obj.Get(), nullptr,
415 nullptr);
416 if (!self->IsExceptionPending()) {
417 result->SetL(h_real_to_string_obj.Get());
418 ok = true;
419 }
420 }
421 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700422 }
423 }
424 }
425
426 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700427 AbortTransactionOrFail(self, "Could not create RealToString object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700428 }
429}
430
Andreas Gampedd9d0552015-03-09 12:57:41 -0700431static void UnstartedMathCeil(
432 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700433 double in = shadow_frame->GetVRegDouble(arg_offset);
434 double out;
435 // Special cases:
436 // 1) NaN, infinity, +0, -0 -> out := in. All are guaranteed by cmath.
437 // -1 < in < 0 -> out := -0.
438 if (-1.0 < in && in < 0) {
439 out = -0.0;
440 } else {
441 out = ceil(in);
442 }
443 result->SetD(out);
444}
445
Andreas Gampedd9d0552015-03-09 12:57:41 -0700446static void UnstartedArtMethodGetMethodName(
447 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700448 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
449 mirror::ArtMethod* method = shadow_frame->GetVRegReference(arg_offset)->AsArtMethod();
450 result->SetL(method->GetNameAsString(self));
451}
452
Andreas Gampedd9d0552015-03-09 12:57:41 -0700453static void UnstartedObjectHashCode(
454 Thread* self ATTRIBUTE_UNUSED, 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::Object* obj = shadow_frame->GetVRegReference(arg_offset);
457 result->SetI(obj->IdentityHashCode());
458}
459
Andreas Gampedd9d0552015-03-09 12:57:41 -0700460static void UnstartedDoubleDoubleToRawLongBits(
461 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700462 double in = shadow_frame->GetVRegDouble(arg_offset);
Roland Levillainda4d79b2015-03-24 14:36:11 +0000463 result->SetJ(bit_cast<int64_t, double>(in));
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700464}
465
Andreas Gampedd9d0552015-03-09 12:57:41 -0700466static mirror::Object* GetDexFromDexCache(Thread* self, mirror::DexCache* dex_cache)
467 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
468 const DexFile* dex_file = dex_cache->GetDexFile();
469 if (dex_file == nullptr) {
470 return nullptr;
471 }
472
473 // Create the direct byte buffer.
474 JNIEnv* env = self->GetJniEnv();
475 DCHECK(env != nullptr);
476 void* address = const_cast<void*>(reinterpret_cast<const void*>(dex_file->Begin()));
477 jobject byte_buffer = env->NewDirectByteBuffer(address, dex_file->Size());
478 if (byte_buffer == nullptr) {
479 DCHECK(self->IsExceptionPending());
480 return nullptr;
481 }
482
483 jvalue args[1];
484 args[0].l = byte_buffer;
485 return self->DecodeJObject(
486 env->CallStaticObjectMethodA(WellKnownClasses::com_android_dex_Dex,
487 WellKnownClasses::com_android_dex_Dex_create,
488 args));
489}
490
491static void UnstartedDexCacheGetDexNative(
492 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
493 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
494 // We will create the Dex object, but the image writer will release it before creating the
495 // art file.
496 mirror::Object* src = shadow_frame->GetVRegReference(arg_offset);
497 bool have_dex = false;
498 if (src != nullptr) {
499 mirror::Object* dex = GetDexFromDexCache(self, reinterpret_cast<mirror::DexCache*>(src));
500 if (dex != nullptr) {
501 have_dex = true;
502 result->SetL(dex);
503 }
504 }
505 if (!have_dex) {
506 self->ClearException();
507 Runtime::Current()->AbortTransactionAndThrowInternalError(self, "Could not create Dex object");
508 }
509}
510
511static void UnstartedMemoryPeek(
512 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
513 int64_t address = shadow_frame->GetVRegLong(arg_offset);
514 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
515 // aborting the transaction.
516
517 switch (type) {
518 case Primitive::kPrimByte: {
519 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
520 return;
521 }
522
523 case Primitive::kPrimShort: {
524 result->SetS(*reinterpret_cast<int16_t*>(static_cast<intptr_t>(address)));
525 return;
526 }
527
528 case Primitive::kPrimInt: {
529 result->SetI(*reinterpret_cast<int32_t*>(static_cast<intptr_t>(address)));
530 return;
531 }
532
533 case Primitive::kPrimLong: {
534 result->SetJ(*reinterpret_cast<int64_t*>(static_cast<intptr_t>(address)));
535 return;
536 }
537
538 case Primitive::kPrimBoolean:
539 case Primitive::kPrimChar:
540 case Primitive::kPrimFloat:
541 case Primitive::kPrimDouble:
542 case Primitive::kPrimVoid:
543 case Primitive::kPrimNot:
544 LOG(FATAL) << "Not in the Memory API: " << type;
545 UNREACHABLE();
546 }
547 LOG(FATAL) << "Should not reach here";
548 UNREACHABLE();
549}
550
551static void UnstartedMemoryPeekEntry(
552 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
553 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
554 std::string name(PrettyMethod(shadow_frame->GetMethod()));
555 if (name == "byte libcore.io.Memory.peekByte(long)") {
556 UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
557 } else if (name == "short libcore.io.Memory.peekShortNative(long)") {
558 UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
559 } else if (name == "int libcore.io.Memory.peekIntNative(long)") {
560 UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
561 } else if (name == "long libcore.io.Memory.peekLongNative(long)") {
562 UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
563 } else {
564 LOG(FATAL) << "Unsupported Memory.peek entry: " << name;
565 UNREACHABLE();
566 }
567}
568
569static void UnstartedMemoryPeekArray(
570 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
571 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
572 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
573 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
574 if (obj == nullptr) {
575 Runtime::Current()->AbortTransactionAndThrowInternalError(self, "Null pointer in peekArray");
576 return;
577 }
578 mirror::Array* array = obj->AsArray();
579
580 int offset = shadow_frame->GetVReg(arg_offset + 3);
581 int count = shadow_frame->GetVReg(arg_offset + 4);
582 if (offset < 0 || offset + count > array->GetLength()) {
583 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
584 offset, count, array->GetLength()));
585 Runtime::Current()->AbortTransactionAndThrowInternalError(self, error_msg.c_str());
586 return;
587 }
588
589 switch (type) {
590 case Primitive::kPrimByte: {
591 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
592 mirror::ByteArray* byte_array = array->AsByteArray();
593 for (int32_t i = 0; i < count; ++i, ++address) {
594 byte_array->SetWithoutChecks<true>(i + offset, *address);
595 }
596 return;
597 }
598
599 case Primitive::kPrimShort:
600 case Primitive::kPrimInt:
601 case Primitive::kPrimLong:
602 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
603 UNREACHABLE();
604
605 case Primitive::kPrimBoolean:
606 case Primitive::kPrimChar:
607 case Primitive::kPrimFloat:
608 case Primitive::kPrimDouble:
609 case Primitive::kPrimVoid:
610 case Primitive::kPrimNot:
611 LOG(FATAL) << "Not in the Memory API: " << type;
612 UNREACHABLE();
613 }
614 LOG(FATAL) << "Should not reach here";
615 UNREACHABLE();
616}
617
618static void UnstartedMemoryPeekArrayEntry(
619 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
620 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
621 std::string name(PrettyMethod(shadow_frame->GetMethod()));
622 if (name == "void libcore.io.Memory.peekByteArray(long, byte[], int, int)") {
623 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
624 } else {
625 LOG(FATAL) << "Unsupported Memory.peekArray entry: " << name;
626 UNREACHABLE();
627 }
628}
629
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700630static void UnstartedJNIVMRuntimeNewUnpaddedArray(Thread* self,
631 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
632 mirror::Object* receiver ATTRIBUTE_UNUSED,
633 uint32_t* args,
634 JValue* result)
635 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
636 int32_t length = args[1];
637 DCHECK_GE(length, 0);
638 mirror::Class* element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
639 Runtime* runtime = Runtime::Current();
640 mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(self, &element_class);
641 DCHECK(array_class != nullptr);
642 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
643 result->SetL(mirror::Array::Alloc<true, true>(self, array_class, length,
644 array_class->GetComponentSizeShift(), allocator));
645}
646
647static void UnstartedJNIVMStackGetCallingClassLoader(Thread* self ATTRIBUTE_UNUSED,
648 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
649 mirror::Object* receiver ATTRIBUTE_UNUSED,
650 uint32_t* args ATTRIBUTE_UNUSED,
651 JValue* result) {
652 result->SetL(nullptr);
653}
654
655static void UnstartedJNIVMStackGetStackClass2(Thread* self,
656 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
657 mirror::Object* receiver ATTRIBUTE_UNUSED,
658 uint32_t* args ATTRIBUTE_UNUSED,
659 JValue* result)
660 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
661 NthCallerVisitor visitor(self, 3);
662 visitor.WalkStack();
663 if (visitor.caller != nullptr) {
664 result->SetL(visitor.caller->GetDeclaringClass());
665 }
666}
667
668static void UnstartedJNIMathLog(Thread* self ATTRIBUTE_UNUSED,
669 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
670 mirror::Object* receiver ATTRIBUTE_UNUSED,
671 uint32_t* args,
672 JValue* result) {
673 JValue value;
674 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
675 result->SetD(log(value.GetD()));
676}
677
678static void UnstartedJNIMathExp(Thread* self ATTRIBUTE_UNUSED,
679 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
680 mirror::Object* receiver ATTRIBUTE_UNUSED,
681 uint32_t* args,
682 JValue* result) {
683 JValue value;
684 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
685 result->SetD(exp(value.GetD()));
686}
687
688static void UnstartedJNIClassGetNameNative(Thread* self,
689 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
690 mirror::Object* receiver,
691 uint32_t* args ATTRIBUTE_UNUSED,
692 JValue* result)
693 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
694 StackHandleScope<1> hs(self);
695 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
696}
697
698static void UnstartedJNIFloatFloatToRawIntBits(Thread* self ATTRIBUTE_UNUSED,
699 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
700 mirror::Object* receiver ATTRIBUTE_UNUSED,
701 uint32_t* args,
702 JValue* result) {
703 result->SetI(args[0]);
704}
705
706static void UnstartedJNIFloatIntBitsToFloat(Thread* self ATTRIBUTE_UNUSED,
707 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
708 mirror::Object* receiver ATTRIBUTE_UNUSED,
709 uint32_t* args,
710 JValue* result) {
711 result->SetI(args[0]);
712}
713
714static void UnstartedJNIObjectInternalClone(Thread* self ATTRIBUTE_UNUSED,
715 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
716 mirror::Object* receiver,
717 uint32_t* args ATTRIBUTE_UNUSED,
718 JValue* result)
719 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
720 result->SetL(receiver->Clone(self));
721}
722
723static void UnstartedJNIObjectNotifyAll(Thread* self ATTRIBUTE_UNUSED,
724 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
725 mirror::Object* receiver,
726 uint32_t* args ATTRIBUTE_UNUSED,
727 JValue* result ATTRIBUTE_UNUSED)
728 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
729 receiver->NotifyAll(self);
730}
731
732static void UnstartedJNIStringCompareTo(Thread* self,
733 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
734 mirror::Object* receiver,
735 uint32_t* args,
736 JValue* result)
737 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
738 mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
739 if (rhs == nullptr) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700740 AbortTransactionOrFail(self, "String.compareTo with null object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700741 }
742 result->SetI(receiver->AsString()->CompareTo(rhs));
743}
744
745static void UnstartedJNIStringIntern(Thread* self ATTRIBUTE_UNUSED,
746 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
747 mirror::Object* receiver,
748 uint32_t* args ATTRIBUTE_UNUSED,
749 JValue* result)
750 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
751 result->SetL(receiver->AsString()->Intern());
752}
753
754static void UnstartedJNIStringFastIndexOf(Thread* self ATTRIBUTE_UNUSED,
755 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
756 mirror::Object* receiver,
757 uint32_t* args,
758 JValue* result)
759 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
760 result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1]));
761}
762
763static void UnstartedJNIArrayCreateMultiArray(Thread* self,
764 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
765 mirror::Object* receiver ATTRIBUTE_UNUSED,
766 uint32_t* args,
767 JValue* result)
768 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
769 StackHandleScope<2> hs(self);
770 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
771 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
772 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
773}
774
775static void UnstartedJNIThrowableNativeFillInStackTrace(Thread* self,
776 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
777 mirror::Object* receiver ATTRIBUTE_UNUSED,
778 uint32_t* args ATTRIBUTE_UNUSED,
779 JValue* result)
780 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
781 ScopedObjectAccessUnchecked soa(self);
782 if (Runtime::Current()->IsActiveTransaction()) {
783 result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<true>(soa)));
784 } else {
785 result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<false>(soa)));
786 }
787}
788
789static void UnstartedJNISystemIdentityHashCode(Thread* self ATTRIBUTE_UNUSED,
790 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
791 mirror::Object* receiver ATTRIBUTE_UNUSED,
792 uint32_t* args,
793 JValue* result)
794 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
795 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
796 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
797}
798
799static void UnstartedJNIByteOrderIsLittleEndian(Thread* self ATTRIBUTE_UNUSED,
800 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
801 mirror::Object* receiver ATTRIBUTE_UNUSED,
802 uint32_t* args ATTRIBUTE_UNUSED,
803 JValue* result) {
804 result->SetZ(JNI_TRUE);
805}
806
807static void UnstartedJNIUnsafeCompareAndSwapInt(Thread* self ATTRIBUTE_UNUSED,
808 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
809 mirror::Object* receiver ATTRIBUTE_UNUSED,
810 uint32_t* args,
811 JValue* result)
812 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
813 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
814 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
815 jint expectedValue = args[3];
816 jint newValue = args[4];
817 bool success;
818 if (Runtime::Current()->IsActiveTransaction()) {
819 success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
820 expectedValue, newValue);
821 } else {
822 success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
823 expectedValue, newValue);
824 }
825 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
826}
827
828static void UnstartedJNIUnsafePutObject(Thread* self ATTRIBUTE_UNUSED,
829 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
830 mirror::Object* receiver ATTRIBUTE_UNUSED,
831 uint32_t* args,
832 JValue* result ATTRIBUTE_UNUSED)
833 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
834 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
835 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
836 mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
837 if (Runtime::Current()->IsActiveTransaction()) {
838 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
839 } else {
840 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
841 }
842}
843
844static void UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
845 Thread* self ATTRIBUTE_UNUSED,
846 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
847 mirror::Object* receiver ATTRIBUTE_UNUSED,
848 uint32_t* args,
849 JValue* result)
850 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
851 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
852 Primitive::Type primitive_type = component->GetPrimitiveType();
853 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
854}
855
856static void UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
857 Thread* self ATTRIBUTE_UNUSED,
858 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
859 mirror::Object* receiver ATTRIBUTE_UNUSED,
860 uint32_t* args,
861 JValue* result)
862 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
863 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
864 Primitive::Type primitive_type = component->GetPrimitiveType();
865 result->SetI(Primitive::ComponentSize(primitive_type));
866}
867
Andreas Gampedd9d0552015-03-09 12:57:41 -0700868typedef void (*InvokeHandler)(Thread* self, ShadowFrame* shadow_frame, JValue* result,
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700869 size_t arg_size);
870
Andreas Gampedd9d0552015-03-09 12:57:41 -0700871typedef void (*JNIHandler)(Thread* self, mirror::ArtMethod* method, mirror::Object* receiver,
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700872 uint32_t* args, JValue* result);
873
874static bool tables_initialized_ = false;
875static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
876static std::unordered_map<std::string, JNIHandler> jni_handlers_;
877
878static void UnstartedRuntimeInitializeInvokeHandlers() {
879 struct InvokeHandlerDef {
880 std::string name;
881 InvokeHandler function;
882 };
883
884 InvokeHandlerDef defs[] {
885 { "java.lang.Class java.lang.Class.forName(java.lang.String)",
886 &UnstartedClassForName },
887 { "java.lang.Class java.lang.Class.forName(java.lang.String, boolean, java.lang.ClassLoader)",
888 &UnstartedClassForNameLong },
889 { "java.lang.Class java.lang.Class.classForName(java.lang.String, boolean, java.lang.ClassLoader)",
890 &UnstartedClassClassForName },
891 { "java.lang.Class java.lang.VMClassLoader.findLoadedClass(java.lang.ClassLoader, java.lang.String)",
892 &UnstartedVmClassLoaderFindLoadedClass },
893 { "java.lang.Class java.lang.Void.lookupType()",
894 &UnstartedVoidLookupType },
895 { "java.lang.Object java.lang.Class.newInstance()",
896 &UnstartedClassNewInstance },
897 { "java.lang.reflect.Field java.lang.Class.getDeclaredField(java.lang.String)",
898 &UnstartedClassGetDeclaredField },
899 { "int java.lang.Object.hashCode()",
900 &UnstartedObjectHashCode },
901 { "java.lang.String java.lang.reflect.ArtMethod.getMethodName(java.lang.reflect.ArtMethod)",
902 &UnstartedArtMethodGetMethodName },
903 { "void java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int)",
904 &UnstartedSystemArraycopy},
905 { "void java.lang.System.arraycopy(char[], int, char[], int, int)",
906 &UnstartedSystemArraycopy },
907 { "void java.lang.System.arraycopy(int[], int, int[], int, int)",
908 &UnstartedSystemArraycopy },
909 { "long java.lang.Double.doubleToRawLongBits(double)",
910 &UnstartedDoubleDoubleToRawLongBits },
911 { "double java.lang.Math.ceil(double)",
912 &UnstartedMathCeil },
913 { "java.lang.Object java.lang.ThreadLocal.get()",
914 &UnstartedThreadLocalGet },
Andreas Gampedd9d0552015-03-09 12:57:41 -0700915 { "com.android.dex.Dex java.lang.DexCache.getDexNative()",
916 &UnstartedDexCacheGetDexNative },
917 { "byte libcore.io.Memory.peekByte(long)",
918 &UnstartedMemoryPeekEntry },
919 { "short libcore.io.Memory.peekShortNative(long)",
920 &UnstartedMemoryPeekEntry },
921 { "int libcore.io.Memory.peekIntNative(long)",
922 &UnstartedMemoryPeekEntry },
923 { "long libcore.io.Memory.peekLongNative(long)",
924 &UnstartedMemoryPeekEntry },
925 { "void libcore.io.Memory.peekByteArray(long, byte[], int, int)",
926 &UnstartedMemoryPeekArrayEntry },
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700927 };
928
929 for (auto& def : defs) {
930 invoke_handlers_.insert(std::make_pair(def.name, def.function));
931 }
932}
933
934static void UnstartedRuntimeInitializeJNIHandlers() {
935 struct JNIHandlerDef {
936 std::string name;
937 JNIHandler function;
938 };
939
940 JNIHandlerDef defs[] {
941 { "java.lang.Object dalvik.system.VMRuntime.newUnpaddedArray(java.lang.Class, int)",
942 &UnstartedJNIVMRuntimeNewUnpaddedArray },
943 { "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()",
944 &UnstartedJNIVMStackGetCallingClassLoader },
945 { "java.lang.Class dalvik.system.VMStack.getStackClass2()",
946 &UnstartedJNIVMStackGetStackClass2 },
947 { "double java.lang.Math.log(double)",
948 &UnstartedJNIMathLog },
949 { "java.lang.String java.lang.Class.getNameNative()",
950 &UnstartedJNIClassGetNameNative },
951 { "int java.lang.Float.floatToRawIntBits(float)",
952 &UnstartedJNIFloatFloatToRawIntBits },
953 { "float java.lang.Float.intBitsToFloat(int)",
954 &UnstartedJNIFloatIntBitsToFloat },
955 { "double java.lang.Math.exp(double)",
956 &UnstartedJNIMathExp },
957 { "java.lang.Object java.lang.Object.internalClone()",
958 &UnstartedJNIObjectInternalClone },
959 { "void java.lang.Object.notifyAll()",
960 &UnstartedJNIObjectNotifyAll},
961 { "int java.lang.String.compareTo(java.lang.String)",
962 &UnstartedJNIStringCompareTo },
963 { "java.lang.String java.lang.String.intern()",
964 &UnstartedJNIStringIntern },
965 { "int java.lang.String.fastIndexOf(int, int)",
966 &UnstartedJNIStringFastIndexOf },
967 { "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])",
968 &UnstartedJNIArrayCreateMultiArray },
969 { "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()",
970 &UnstartedJNIThrowableNativeFillInStackTrace },
971 { "int java.lang.System.identityHashCode(java.lang.Object)",
972 &UnstartedJNISystemIdentityHashCode },
973 { "boolean java.nio.ByteOrder.isLittleEndian()",
974 &UnstartedJNIByteOrderIsLittleEndian },
975 { "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)",
976 &UnstartedJNIUnsafeCompareAndSwapInt },
977 { "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)",
978 &UnstartedJNIUnsafePutObject },
979 { "int sun.misc.Unsafe.getArrayBaseOffsetForComponentType(java.lang.Class)",
980 &UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType },
981 { "int sun.misc.Unsafe.getArrayIndexScaleForComponentType(java.lang.Class)",
982 &UnstartedJNIUnsafeGetArrayIndexScaleForComponentType },
983 };
984
985 for (auto& def : defs) {
986 jni_handlers_.insert(std::make_pair(def.name, def.function));
987 }
988}
989
990void UnstartedRuntimeInitialize() {
991 CHECK(!tables_initialized_);
992
993 UnstartedRuntimeInitializeInvokeHandlers();
994 UnstartedRuntimeInitializeJNIHandlers();
995
996 tables_initialized_ = true;
997}
998
999void UnstartedRuntimeInvoke(Thread* self, const DexFile::CodeItem* code_item,
1000 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1001 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
1002 // problems in core libraries.
1003 CHECK(tables_initialized_);
1004
1005 std::string name(PrettyMethod(shadow_frame->GetMethod()));
1006 const auto& iter = invoke_handlers_.find(name);
1007 if (iter != invoke_handlers_.end()) {
1008 (*iter->second)(self, shadow_frame, result, arg_offset);
1009 } else {
1010 // Not special, continue with regular interpreter execution.
1011 artInterpreterToInterpreterBridge(self, code_item, shadow_frame, result);
1012 }
1013}
1014
1015// Hand select a number of methods to be run in a not yet started runtime without using JNI.
1016void UnstartedRuntimeJni(Thread* self, mirror::ArtMethod* method, mirror::Object* receiver,
1017 uint32_t* args, JValue* result) {
1018 std::string name(PrettyMethod(method));
1019 const auto& iter = jni_handlers_.find(name);
1020 if (iter != jni_handlers_.end()) {
1021 (*iter->second)(self, method, receiver, args, result);
1022 } else if (Runtime::Current()->IsActiveTransaction()) {
1023 AbortTransaction(self, "Attempt to invoke native method in non-started runtime: %s",
1024 name.c_str());
1025 } else {
1026 LOG(FATAL) << "Calling native method " << PrettyMethod(method) << " in an unstarted "
1027 "non-transactional runtime";
1028 }
1029}
1030
1031} // namespace interpreter
1032} // namespace art