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