blob: 6ea3f25a1340c45e5a304f494023c5064e57f5b0 [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
100static void UnstartedClassForName(Thread* self, ShadowFrame* shadow_frame, JValue* result,
101 size_t arg_offset)
102 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
111static void UnstartedClassForNameLong(Thread* self, ShadowFrame* shadow_frame, JValue* result,
112 size_t arg_offset)
113 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
126static void UnstartedClassClassForName(Thread* self, ShadowFrame* shadow_frame, JValue* result,
127 size_t arg_offset)
128 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
141static void UnstartedClassNewInstance(Thread* self, ShadowFrame* shadow_frame, JValue* result,
142 size_t arg_offset)
143 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));
147 // There are two situations in which we'll abort this run.
148 // 1) If the class isn't yet initialized and initialization fails.
149 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
150 // Note that 2) could likely be handled here, but for safety abort the transaction.
151 bool ok = false;
152 if (Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
153 Handle<mirror::ArtMethod> h_cons(hs.NewHandle(
154 h_klass->FindDeclaredDirectMethod("<init>", "()V")));
155 if (h_cons.Get() != nullptr) {
156 Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
157 CHECK(h_obj.Get() != nullptr); // We don't expect OOM at compile-time.
158 EnterInterpreterFromInvoke(self, h_cons.Get(), h_obj.Get(), nullptr, nullptr);
159 if (!self->IsExceptionPending()) {
160 result->SetL(h_obj.Get());
161 ok = true;
162 }
163 } else {
164 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
165 "Could not find default constructor for '%s'",
166 PrettyClass(h_klass.Get()).c_str());
167 }
168 }
169 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700170 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
171 PrettyClass(h_klass.Get()).c_str(),
172 PrettyTypeOf(self->GetException()).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700173 }
174}
175
176static void UnstartedClassGetDeclaredField(Thread* self, ShadowFrame* shadow_frame, JValue* result,
177 size_t arg_offset)
178 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
179 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
180 // going the reflective Dex way.
181 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
182 mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
183 mirror::ArtField* found = nullptr;
184 mirror::ObjectArray<mirror::ArtField>* fields = klass->GetIFields();
185 for (int32_t i = 0; i < fields->GetLength() && found == nullptr; ++i) {
186 mirror::ArtField* f = fields->Get(i);
187 if (name2->Equals(f->GetName())) {
188 found = f;
189 }
190 }
191 if (found == nullptr) {
192 fields = klass->GetSFields();
193 for (int32_t i = 0; i < fields->GetLength() && found == nullptr; ++i) {
194 mirror::ArtField* f = fields->Get(i);
195 if (name2->Equals(f->GetName())) {
196 found = f;
197 }
198 }
199 }
Andreas Gampe068b0c02015-03-11 12:44:47 -0700200 if (found == nullptr) {
201 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
202 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
203 PrettyDescriptor(klass).c_str());
204 return;
205 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700206 // TODO: getDeclaredField calls GetType once the field is found to ensure a
207 // NoClassDefFoundError is thrown if the field's type cannot be resolved.
208 mirror::Class* jlr_Field = self->DecodeJObject(
209 WellKnownClasses::java_lang_reflect_Field)->AsClass();
210 StackHandleScope<1> hs(self);
211 Handle<mirror::Object> field(hs.NewHandle(jlr_Field->AllocNonMovableObject(self)));
212 CHECK(field.Get() != nullptr);
213 mirror::ArtMethod* c = jlr_Field->FindDeclaredDirectMethod("<init>",
214 "(Ljava/lang/reflect/ArtField;)V");
215 uint32_t args[1];
216 args[0] = StackReference<mirror::Object>::FromMirrorPtr(found).AsVRegValue();
217 EnterInterpreterFromInvoke(self, c, field.Get(), args, nullptr);
218 result->SetL(field.Get());
219}
220
221static void UnstartedVmClassLoaderFindLoadedClass(Thread* self, ShadowFrame* shadow_frame,
222 JValue* result, size_t arg_offset)
223 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
224 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
225 mirror::ClassLoader* class_loader =
226 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
227 StackHandleScope<2> hs(self);
228 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
229 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
230 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
231 "VMClassLoader.findLoadedClass", false, false);
232 // This might have an error pending. But semantics are to just return null.
233 if (self->IsExceptionPending()) {
234 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
235 std::string type(PrettyTypeOf(self->GetException()));
236 if (type != "java.lang.InternalError") {
237 self->ClearException();
238 }
239 }
240}
241
242static void UnstartedVoidLookupType(Thread* self ATTRIBUTE_UNUSED,
243 ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
244 JValue* result,
245 size_t arg_offset ATTRIBUTE_UNUSED)
246 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
247 result->SetL(Runtime::Current()->GetClassLinker()->FindPrimitiveClass('V'));
248}
249
250static void UnstartedSystemArraycopy(Thread* self, ShadowFrame* shadow_frame,
251 JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
252 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
253 // Special case array copying without initializing System.
254 mirror::Class* ctype = shadow_frame->GetVRegReference(arg_offset)->GetClass()->GetComponentType();
255 jint srcPos = shadow_frame->GetVReg(arg_offset + 1);
256 jint dstPos = shadow_frame->GetVReg(arg_offset + 3);
257 jint length = shadow_frame->GetVReg(arg_offset + 4);
258 if (!ctype->IsPrimitive()) {
259 mirror::ObjectArray<mirror::Object>* src = shadow_frame->GetVRegReference(arg_offset)->
260 AsObjectArray<mirror::Object>();
261 mirror::ObjectArray<mirror::Object>* dst = shadow_frame->GetVRegReference(arg_offset + 2)->
262 AsObjectArray<mirror::Object>();
263 for (jint i = 0; i < length; ++i) {
264 dst->Set(dstPos + i, src->Get(srcPos + i));
265 }
266 } else if (ctype->IsPrimitiveChar()) {
267 mirror::CharArray* src = shadow_frame->GetVRegReference(arg_offset)->AsCharArray();
268 mirror::CharArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray();
269 for (jint i = 0; i < length; ++i) {
270 dst->Set(dstPos + i, src->Get(srcPos + i));
271 }
272 } else if (ctype->IsPrimitiveInt()) {
273 mirror::IntArray* src = shadow_frame->GetVRegReference(arg_offset)->AsIntArray();
274 mirror::IntArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsIntArray();
275 for (jint i = 0; i < length; ++i) {
276 dst->Set(dstPos + i, src->Get(srcPos + i));
277 }
278 } else {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700279 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
280 PrettyDescriptor(ctype).c_str());
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700281 }
282}
283
284static void UnstartedThreadLocalGet(Thread* self, ShadowFrame* shadow_frame, JValue* result,
285 size_t arg_offset ATTRIBUTE_UNUSED)
286 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
287 std::string caller(PrettyMethod(shadow_frame->GetLink()->GetMethod()));
288 bool ok = false;
289 if (caller == "java.lang.String java.lang.IntegralToString.convertInt"
290 "(java.lang.AbstractStringBuilder, int)") {
291 // Allocate non-threadlocal buffer.
292 result->SetL(mirror::CharArray::Alloc(self, 11));
293 ok = true;
294 } else if (caller == "java.lang.RealToString java.lang.RealToString.getInstance()") {
295 // Note: RealToString is implemented and used in a different fashion than IntegralToString.
296 // Conversion is done over an actual object of RealToString (the conversion method is an
297 // instance method). This means it is not as clear whether it is correct to return a new
298 // object each time. The caller needs to be inspected by hand to see whether it (incorrectly)
299 // stores the object for later use.
300 // See also b/19548084 for a possible rewrite and bringing it in line with IntegralToString.
301 if (shadow_frame->GetLink()->GetLink() != nullptr) {
302 std::string caller2(PrettyMethod(shadow_frame->GetLink()->GetLink()->GetMethod()));
303 if (caller2 == "java.lang.String java.lang.Double.toString(double)") {
304 // Allocate new object.
305 StackHandleScope<2> hs(self);
306 Handle<mirror::Class> h_real_to_string_class(hs.NewHandle(
307 shadow_frame->GetLink()->GetMethod()->GetDeclaringClass()));
308 Handle<mirror::Object> h_real_to_string_obj(hs.NewHandle(
309 h_real_to_string_class->AllocObject(self)));
310 if (h_real_to_string_obj.Get() != nullptr) {
311 mirror::ArtMethod* init_method =
312 h_real_to_string_class->FindDirectMethod("<init>", "()V");
313 if (init_method == nullptr) {
314 h_real_to_string_class->DumpClass(LOG(FATAL), mirror::Class::kDumpClassFullDetail);
315 } else {
316 JValue invoke_result;
317 EnterInterpreterFromInvoke(self, init_method, h_real_to_string_obj.Get(), nullptr,
318 nullptr);
319 if (!self->IsExceptionPending()) {
320 result->SetL(h_real_to_string_obj.Get());
321 ok = true;
322 }
323 }
324 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700325 }
326 }
327 }
328
329 if (!ok) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700330 AbortTransactionOrFail(self, "Could not create RealToString object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700331 }
332}
333
334static void UnstartedMathCeil(Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame,
335 JValue* result, size_t arg_offset) {
336 double in = shadow_frame->GetVRegDouble(arg_offset);
337 double out;
338 // Special cases:
339 // 1) NaN, infinity, +0, -0 -> out := in. All are guaranteed by cmath.
340 // -1 < in < 0 -> out := -0.
341 if (-1.0 < in && in < 0) {
342 out = -0.0;
343 } else {
344 out = ceil(in);
345 }
346 result->SetD(out);
347}
348
349static void UnstartedArtMethodGetMethodName(Thread* self, ShadowFrame* shadow_frame,
350 JValue* result, size_t arg_offset)
351 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
352 mirror::ArtMethod* method = shadow_frame->GetVRegReference(arg_offset)->AsArtMethod();
353 result->SetL(method->GetNameAsString(self));
354}
355
356static void UnstartedObjectHashCode(Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame,
357 JValue* result, size_t arg_offset)
358 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
359 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
360 result->SetI(obj->IdentityHashCode());
361}
362
363static void UnstartedDoubleDoubleToRawLongBits(Thread* self ATTRIBUTE_UNUSED,
364 ShadowFrame* shadow_frame, JValue* result,
365 size_t arg_offset) {
366 double in = shadow_frame->GetVRegDouble(arg_offset);
367 result->SetJ(bit_cast<int64_t>(in));
368}
369
370static void UnstartedJNIVMRuntimeNewUnpaddedArray(Thread* self,
371 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
372 mirror::Object* receiver ATTRIBUTE_UNUSED,
373 uint32_t* args,
374 JValue* result)
375 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
376 int32_t length = args[1];
377 DCHECK_GE(length, 0);
378 mirror::Class* element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
379 Runtime* runtime = Runtime::Current();
380 mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(self, &element_class);
381 DCHECK(array_class != nullptr);
382 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
383 result->SetL(mirror::Array::Alloc<true, true>(self, array_class, length,
384 array_class->GetComponentSizeShift(), allocator));
385}
386
387static void UnstartedJNIVMStackGetCallingClassLoader(Thread* self ATTRIBUTE_UNUSED,
388 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
389 mirror::Object* receiver ATTRIBUTE_UNUSED,
390 uint32_t* args ATTRIBUTE_UNUSED,
391 JValue* result) {
392 result->SetL(nullptr);
393}
394
395static void UnstartedJNIVMStackGetStackClass2(Thread* self,
396 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
397 mirror::Object* receiver ATTRIBUTE_UNUSED,
398 uint32_t* args ATTRIBUTE_UNUSED,
399 JValue* result)
400 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
401 NthCallerVisitor visitor(self, 3);
402 visitor.WalkStack();
403 if (visitor.caller != nullptr) {
404 result->SetL(visitor.caller->GetDeclaringClass());
405 }
406}
407
408static void UnstartedJNIMathLog(Thread* self ATTRIBUTE_UNUSED,
409 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
410 mirror::Object* receiver ATTRIBUTE_UNUSED,
411 uint32_t* args,
412 JValue* result) {
413 JValue value;
414 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
415 result->SetD(log(value.GetD()));
416}
417
418static void UnstartedJNIMathExp(Thread* self ATTRIBUTE_UNUSED,
419 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
420 mirror::Object* receiver ATTRIBUTE_UNUSED,
421 uint32_t* args,
422 JValue* result) {
423 JValue value;
424 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
425 result->SetD(exp(value.GetD()));
426}
427
428static void UnstartedJNIClassGetNameNative(Thread* self,
429 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
430 mirror::Object* receiver,
431 uint32_t* args ATTRIBUTE_UNUSED,
432 JValue* result)
433 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
434 StackHandleScope<1> hs(self);
435 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
436}
437
438static void UnstartedJNIFloatFloatToRawIntBits(Thread* self ATTRIBUTE_UNUSED,
439 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
440 mirror::Object* receiver ATTRIBUTE_UNUSED,
441 uint32_t* args,
442 JValue* result) {
443 result->SetI(args[0]);
444}
445
446static void UnstartedJNIFloatIntBitsToFloat(Thread* self ATTRIBUTE_UNUSED,
447 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
448 mirror::Object* receiver ATTRIBUTE_UNUSED,
449 uint32_t* args,
450 JValue* result) {
451 result->SetI(args[0]);
452}
453
454static void UnstartedJNIObjectInternalClone(Thread* self ATTRIBUTE_UNUSED,
455 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
456 mirror::Object* receiver,
457 uint32_t* args ATTRIBUTE_UNUSED,
458 JValue* result)
459 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
460 result->SetL(receiver->Clone(self));
461}
462
463static void UnstartedJNIObjectNotifyAll(Thread* self ATTRIBUTE_UNUSED,
464 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
465 mirror::Object* receiver,
466 uint32_t* args ATTRIBUTE_UNUSED,
467 JValue* result ATTRIBUTE_UNUSED)
468 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
469 receiver->NotifyAll(self);
470}
471
472static void UnstartedJNIStringCompareTo(Thread* self,
473 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
474 mirror::Object* receiver,
475 uint32_t* args,
476 JValue* result)
477 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
478 mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
479 if (rhs == nullptr) {
Andreas Gampe068b0c02015-03-11 12:44:47 -0700480 AbortTransactionOrFail(self, "String.compareTo with null object");
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700481 }
482 result->SetI(receiver->AsString()->CompareTo(rhs));
483}
484
485static void UnstartedJNIStringIntern(Thread* self ATTRIBUTE_UNUSED,
486 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
487 mirror::Object* receiver,
488 uint32_t* args ATTRIBUTE_UNUSED,
489 JValue* result)
490 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
491 result->SetL(receiver->AsString()->Intern());
492}
493
494static void UnstartedJNIStringFastIndexOf(Thread* self ATTRIBUTE_UNUSED,
495 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
496 mirror::Object* receiver,
497 uint32_t* args,
498 JValue* result)
499 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
500 result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1]));
501}
502
503static void UnstartedJNIArrayCreateMultiArray(Thread* self,
504 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
505 mirror::Object* receiver ATTRIBUTE_UNUSED,
506 uint32_t* args,
507 JValue* result)
508 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
509 StackHandleScope<2> hs(self);
510 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
511 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
512 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
513}
514
515static void UnstartedJNIThrowableNativeFillInStackTrace(Thread* self,
516 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
517 mirror::Object* receiver ATTRIBUTE_UNUSED,
518 uint32_t* args ATTRIBUTE_UNUSED,
519 JValue* result)
520 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
521 ScopedObjectAccessUnchecked soa(self);
522 if (Runtime::Current()->IsActiveTransaction()) {
523 result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<true>(soa)));
524 } else {
525 result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<false>(soa)));
526 }
527}
528
529static void UnstartedJNISystemIdentityHashCode(Thread* self ATTRIBUTE_UNUSED,
530 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
531 mirror::Object* receiver ATTRIBUTE_UNUSED,
532 uint32_t* args,
533 JValue* result)
534 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
535 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
536 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
537}
538
539static void UnstartedJNIByteOrderIsLittleEndian(Thread* self ATTRIBUTE_UNUSED,
540 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
541 mirror::Object* receiver ATTRIBUTE_UNUSED,
542 uint32_t* args ATTRIBUTE_UNUSED,
543 JValue* result) {
544 result->SetZ(JNI_TRUE);
545}
546
547static void UnstartedJNIUnsafeCompareAndSwapInt(Thread* self ATTRIBUTE_UNUSED,
548 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
549 mirror::Object* receiver ATTRIBUTE_UNUSED,
550 uint32_t* args,
551 JValue* result)
552 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
553 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
554 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
555 jint expectedValue = args[3];
556 jint newValue = args[4];
557 bool success;
558 if (Runtime::Current()->IsActiveTransaction()) {
559 success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
560 expectedValue, newValue);
561 } else {
562 success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
563 expectedValue, newValue);
564 }
565 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
566}
567
568static void UnstartedJNIUnsafePutObject(Thread* self ATTRIBUTE_UNUSED,
569 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
570 mirror::Object* receiver ATTRIBUTE_UNUSED,
571 uint32_t* args,
572 JValue* result ATTRIBUTE_UNUSED)
573 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
574 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
575 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
576 mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
577 if (Runtime::Current()->IsActiveTransaction()) {
578 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
579 } else {
580 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
581 }
582}
583
584static void UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
585 Thread* self ATTRIBUTE_UNUSED,
586 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
587 mirror::Object* receiver ATTRIBUTE_UNUSED,
588 uint32_t* args,
589 JValue* result)
590 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
591 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
592 Primitive::Type primitive_type = component->GetPrimitiveType();
593 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
594}
595
596static void UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
597 Thread* self ATTRIBUTE_UNUSED,
598 mirror::ArtMethod* method ATTRIBUTE_UNUSED,
599 mirror::Object* receiver ATTRIBUTE_UNUSED,
600 uint32_t* args,
601 JValue* result)
602 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
603 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
604 Primitive::Type primitive_type = component->GetPrimitiveType();
605 result->SetI(Primitive::ComponentSize(primitive_type));
606}
607
608typedef void(*InvokeHandler)(Thread* self, ShadowFrame* shadow_frame, JValue* result,
609 size_t arg_size);
610
611typedef void(*JNIHandler)(Thread* self, mirror::ArtMethod* method, mirror::Object* receiver,
612 uint32_t* args, JValue* result);
613
614static bool tables_initialized_ = false;
615static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
616static std::unordered_map<std::string, JNIHandler> jni_handlers_;
617
618static void UnstartedRuntimeInitializeInvokeHandlers() {
619 struct InvokeHandlerDef {
620 std::string name;
621 InvokeHandler function;
622 };
623
624 InvokeHandlerDef defs[] {
625 { "java.lang.Class java.lang.Class.forName(java.lang.String)",
626 &UnstartedClassForName },
627 { "java.lang.Class java.lang.Class.forName(java.lang.String, boolean, java.lang.ClassLoader)",
628 &UnstartedClassForNameLong },
629 { "java.lang.Class java.lang.Class.classForName(java.lang.String, boolean, java.lang.ClassLoader)",
630 &UnstartedClassClassForName },
631 { "java.lang.Class java.lang.VMClassLoader.findLoadedClass(java.lang.ClassLoader, java.lang.String)",
632 &UnstartedVmClassLoaderFindLoadedClass },
633 { "java.lang.Class java.lang.Void.lookupType()",
634 &UnstartedVoidLookupType },
635 { "java.lang.Object java.lang.Class.newInstance()",
636 &UnstartedClassNewInstance },
637 { "java.lang.reflect.Field java.lang.Class.getDeclaredField(java.lang.String)",
638 &UnstartedClassGetDeclaredField },
639 { "int java.lang.Object.hashCode()",
640 &UnstartedObjectHashCode },
641 { "java.lang.String java.lang.reflect.ArtMethod.getMethodName(java.lang.reflect.ArtMethod)",
642 &UnstartedArtMethodGetMethodName },
643 { "void java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int)",
644 &UnstartedSystemArraycopy},
645 { "void java.lang.System.arraycopy(char[], int, char[], int, int)",
646 &UnstartedSystemArraycopy },
647 { "void java.lang.System.arraycopy(int[], int, int[], int, int)",
648 &UnstartedSystemArraycopy },
649 { "long java.lang.Double.doubleToRawLongBits(double)",
650 &UnstartedDoubleDoubleToRawLongBits },
651 { "double java.lang.Math.ceil(double)",
652 &UnstartedMathCeil },
653 { "java.lang.Object java.lang.ThreadLocal.get()",
654 &UnstartedThreadLocalGet },
655 };
656
657 for (auto& def : defs) {
658 invoke_handlers_.insert(std::make_pair(def.name, def.function));
659 }
660}
661
662static void UnstartedRuntimeInitializeJNIHandlers() {
663 struct JNIHandlerDef {
664 std::string name;
665 JNIHandler function;
666 };
667
668 JNIHandlerDef defs[] {
669 { "java.lang.Object dalvik.system.VMRuntime.newUnpaddedArray(java.lang.Class, int)",
670 &UnstartedJNIVMRuntimeNewUnpaddedArray },
671 { "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()",
672 &UnstartedJNIVMStackGetCallingClassLoader },
673 { "java.lang.Class dalvik.system.VMStack.getStackClass2()",
674 &UnstartedJNIVMStackGetStackClass2 },
675 { "double java.lang.Math.log(double)",
676 &UnstartedJNIMathLog },
677 { "java.lang.String java.lang.Class.getNameNative()",
678 &UnstartedJNIClassGetNameNative },
679 { "int java.lang.Float.floatToRawIntBits(float)",
680 &UnstartedJNIFloatFloatToRawIntBits },
681 { "float java.lang.Float.intBitsToFloat(int)",
682 &UnstartedJNIFloatIntBitsToFloat },
683 { "double java.lang.Math.exp(double)",
684 &UnstartedJNIMathExp },
685 { "java.lang.Object java.lang.Object.internalClone()",
686 &UnstartedJNIObjectInternalClone },
687 { "void java.lang.Object.notifyAll()",
688 &UnstartedJNIObjectNotifyAll},
689 { "int java.lang.String.compareTo(java.lang.String)",
690 &UnstartedJNIStringCompareTo },
691 { "java.lang.String java.lang.String.intern()",
692 &UnstartedJNIStringIntern },
693 { "int java.lang.String.fastIndexOf(int, int)",
694 &UnstartedJNIStringFastIndexOf },
695 { "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])",
696 &UnstartedJNIArrayCreateMultiArray },
697 { "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()",
698 &UnstartedJNIThrowableNativeFillInStackTrace },
699 { "int java.lang.System.identityHashCode(java.lang.Object)",
700 &UnstartedJNISystemIdentityHashCode },
701 { "boolean java.nio.ByteOrder.isLittleEndian()",
702 &UnstartedJNIByteOrderIsLittleEndian },
703 { "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)",
704 &UnstartedJNIUnsafeCompareAndSwapInt },
705 { "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)",
706 &UnstartedJNIUnsafePutObject },
707 { "int sun.misc.Unsafe.getArrayBaseOffsetForComponentType(java.lang.Class)",
708 &UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType },
709 { "int sun.misc.Unsafe.getArrayIndexScaleForComponentType(java.lang.Class)",
710 &UnstartedJNIUnsafeGetArrayIndexScaleForComponentType },
711 };
712
713 for (auto& def : defs) {
714 jni_handlers_.insert(std::make_pair(def.name, def.function));
715 }
716}
717
718void UnstartedRuntimeInitialize() {
719 CHECK(!tables_initialized_);
720
721 UnstartedRuntimeInitializeInvokeHandlers();
722 UnstartedRuntimeInitializeJNIHandlers();
723
724 tables_initialized_ = true;
725}
726
727void UnstartedRuntimeInvoke(Thread* self, const DexFile::CodeItem* code_item,
728 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
729 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
730 // problems in core libraries.
731 CHECK(tables_initialized_);
732
733 std::string name(PrettyMethod(shadow_frame->GetMethod()));
734 const auto& iter = invoke_handlers_.find(name);
735 if (iter != invoke_handlers_.end()) {
736 (*iter->second)(self, shadow_frame, result, arg_offset);
737 } else {
738 // Not special, continue with regular interpreter execution.
739 artInterpreterToInterpreterBridge(self, code_item, shadow_frame, result);
740 }
741}
742
743// Hand select a number of methods to be run in a not yet started runtime without using JNI.
744void UnstartedRuntimeJni(Thread* self, mirror::ArtMethod* method, mirror::Object* receiver,
745 uint32_t* args, JValue* result) {
746 std::string name(PrettyMethod(method));
747 const auto& iter = jni_handlers_.find(name);
748 if (iter != jni_handlers_.end()) {
749 (*iter->second)(self, method, receiver, args, result);
750 } else if (Runtime::Current()->IsActiveTransaction()) {
751 AbortTransaction(self, "Attempt to invoke native method in non-started runtime: %s",
752 name.c_str());
753 } else {
754 LOG(FATAL) << "Calling native method " << PrettyMethod(method) << " in an unstarted "
755 "non-transactional runtime";
756 }
757}
758
759} // namespace interpreter
760} // namespace art