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