1 /*
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 <ctype.h>
20 #include <errno.h>
21 #include <stdlib.h>
22
23 #include <cmath>
24 #include <initializer_list>
25 #include <limits>
26 #include <locale>
27 #include <unordered_map>
28
29 #include <android-base/logging.h>
30 #include <android-base/stringprintf.h>
31
32 #include "art_method-inl.h"
33 #include "base/casts.h"
34 #include "base/enums.h"
35 #include "base/macros.h"
36 #include "base/quasi_atomic.h"
37 #include "class_linker.h"
38 #include "common_throws.h"
39 #include "dex/descriptors_names.h"
40 #include "entrypoints/entrypoint_utils-inl.h"
41 #include "gc/reference_processor.h"
42 #include "handle_scope-inl.h"
43 #include "hidden_api.h"
44 #include "interpreter/interpreter_common.h"
45 #include "jvalue-inl.h"
46 #include "mirror/array-inl.h"
47 #include "mirror/class.h"
48 #include "mirror/field-inl.h"
49 #include "mirror/method.h"
50 #include "mirror/object-inl.h"
51 #include "mirror/object_array-inl.h"
52 #include "mirror/string-inl.h"
53 #include "nativehelper/scoped_local_ref.h"
54 #include "nth_caller_visitor.h"
55 #include "reflection.h"
56 #include "thread-inl.h"
57 #include "transaction.h"
58 #include "well_known_classes.h"
59 #include "zip_archive.h"
60
61 namespace art {
62 namespace interpreter {
63
64 using android::base::StringAppendV;
65 using android::base::StringPrintf;
66
67 static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
68 __attribute__((__format__(__printf__, 2, 3)))
69 REQUIRES_SHARED(Locks::mutator_lock_);
70
AbortTransactionOrFail(Thread * self,const char * fmt,...)71 static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
72 va_list args;
73 if (Runtime::Current()->IsActiveTransaction()) {
74 va_start(args, fmt);
75 AbortTransactionV(self, fmt, args);
76 va_end(args);
77 } else {
78 va_start(args, fmt);
79 std::string msg;
80 StringAppendV(&msg, fmt, args);
81 va_end(args);
82 LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
83 UNREACHABLE();
84 }
85 }
86
87 // Restricted support for character upper case / lower case. Only support ASCII, where
88 // it's easy. Abort the transaction otherwise.
CharacterLowerUpper(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset,bool to_lower_case)89 static void CharacterLowerUpper(Thread* self,
90 ShadowFrame* shadow_frame,
91 JValue* result,
92 size_t arg_offset,
93 bool to_lower_case) REQUIRES_SHARED(Locks::mutator_lock_) {
94 uint32_t int_value = static_cast<uint32_t>(shadow_frame->GetVReg(arg_offset));
95
96 // Only ASCII (7-bit).
97 if (!isascii(int_value)) {
98 AbortTransactionOrFail(self,
99 "Only support ASCII characters for toLowerCase/toUpperCase: %u",
100 int_value);
101 return;
102 }
103
104 std::locale c_locale("C");
105 char char_value = static_cast<char>(int_value);
106
107 if (to_lower_case) {
108 result->SetI(std::tolower(char_value, c_locale));
109 } else {
110 result->SetI(std::toupper(char_value, c_locale));
111 }
112 }
113
UnstartedCharacterToLowerCase(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)114 void UnstartedRuntime::UnstartedCharacterToLowerCase(
115 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
116 CharacterLowerUpper(self, shadow_frame, result, arg_offset, true);
117 }
118
UnstartedCharacterToUpperCase(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)119 void UnstartedRuntime::UnstartedCharacterToUpperCase(
120 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
121 CharacterLowerUpper(self, shadow_frame, result, arg_offset, false);
122 }
123
124 // Helper function to deal with class loading in an unstarted runtime.
UnstartedRuntimeFindClass(Thread * self,Handle<mirror::String> className,Handle<mirror::ClassLoader> class_loader,JValue * result,const std::string & method_name,bool initialize_class,bool abort_if_not_found)125 static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> className,
126 Handle<mirror::ClassLoader> class_loader, JValue* result,
127 const std::string& method_name, bool initialize_class,
128 bool abort_if_not_found)
129 REQUIRES_SHARED(Locks::mutator_lock_) {
130 CHECK(className != nullptr);
131 std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
132 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
133
134 mirror::Class* found = class_linker->FindClass(self, descriptor.c_str(), class_loader);
135 if (found == nullptr && abort_if_not_found) {
136 if (!self->IsExceptionPending()) {
137 AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s",
138 method_name.c_str(),
139 PrettyDescriptor(descriptor.c_str()).c_str());
140 }
141 return;
142 }
143 if (found != nullptr && initialize_class) {
144 StackHandleScope<1> hs(self);
145 Handle<mirror::Class> h_class(hs.NewHandle(found));
146 if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
147 CHECK(self->IsExceptionPending());
148 return;
149 }
150 }
151 result->SetL(found);
152 }
153
154 // Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
155 // rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
156 // ClassNotFoundException), so need to do the same. The only exception is if the exception is
157 // actually the transaction abort exception. This must not be wrapped, as it signals an
158 // initialization abort.
CheckExceptionGenerateClassNotFound(Thread * self)159 static void CheckExceptionGenerateClassNotFound(Thread* self)
160 REQUIRES_SHARED(Locks::mutator_lock_) {
161 if (self->IsExceptionPending()) {
162 // If it is not the transaction abort exception, wrap it.
163 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
164 if (type != Transaction::kAbortExceptionDescriptor) {
165 self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
166 "ClassNotFoundException");
167 }
168 }
169 }
170
GetClassName(Thread * self,ShadowFrame * shadow_frame,size_t arg_offset)171 static mirror::String* GetClassName(Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
172 REQUIRES_SHARED(Locks::mutator_lock_) {
173 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
174 if (param == nullptr) {
175 AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
176 return nullptr;
177 }
178 return param->AsString();
179 }
180
181 template<typename T>
ShouldBlockAccessToMember(T * member,ShadowFrame * frame)182 static ALWAYS_INLINE bool ShouldBlockAccessToMember(T* member, ShadowFrame* frame)
183 REQUIRES_SHARED(Locks::mutator_lock_) {
184 // All uses in this file are from reflection
185 constexpr hiddenapi::AccessMethod access_method = hiddenapi::kReflection;
186 return hiddenapi::GetMemberAction(
187 member,
188 frame->GetMethod()->GetDeclaringClass()->GetClassLoader(),
189 frame->GetMethod()->GetDeclaringClass()->GetDexCache(),
190 access_method) == hiddenapi::kDeny;
191 }
192
UnstartedClassForNameCommon(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset,bool long_form,const char * caller)193 void UnstartedRuntime::UnstartedClassForNameCommon(Thread* self,
194 ShadowFrame* shadow_frame,
195 JValue* result,
196 size_t arg_offset,
197 bool long_form,
198 const char* caller) {
199 mirror::String* class_name = GetClassName(self, shadow_frame, arg_offset);
200 if (class_name == nullptr) {
201 return;
202 }
203 bool initialize_class;
204 mirror::ClassLoader* class_loader;
205 if (long_form) {
206 initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
207 class_loader = down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset + 2));
208 } else {
209 initialize_class = true;
210 // TODO: This is really only correct for the boot classpath, and for robustness we should
211 // check the caller.
212 class_loader = nullptr;
213 }
214
215 ScopedObjectAccessUnchecked soa(self);
216 if (class_loader != nullptr && !ClassLinker::IsBootClassLoader(soa, class_loader)) {
217 AbortTransactionOrFail(self,
218 "Only the boot classloader is supported: %s",
219 mirror::Object::PrettyTypeOf(class_loader).c_str());
220 return;
221 }
222
223 StackHandleScope<1> hs(self);
224 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
225 UnstartedRuntimeFindClass(self,
226 h_class_name,
227 ScopedNullHandle<mirror::ClassLoader>(),
228 result,
229 caller,
230 initialize_class,
231 false);
232 CheckExceptionGenerateClassNotFound(self);
233 }
234
UnstartedClassForName(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)235 void UnstartedRuntime::UnstartedClassForName(
236 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
237 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, false, "Class.forName");
238 }
239
UnstartedClassForNameLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)240 void UnstartedRuntime::UnstartedClassForNameLong(
241 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
242 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.forName");
243 }
244
UnstartedClassGetPrimitiveClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)245 void UnstartedRuntime::UnstartedClassGetPrimitiveClass(
246 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
247 ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
248 ObjPtr<mirror::Class> klass = mirror::Class::GetPrimitiveClass(class_name);
249 if (UNLIKELY(klass == nullptr)) {
250 DCHECK(self->IsExceptionPending());
251 AbortTransactionOrFail(self,
252 "Class.getPrimitiveClass() failed: %s",
253 self->GetException()->GetDetailMessage()->ToModifiedUtf8().c_str());
254 return;
255 }
256 result->SetL(klass);
257 }
258
UnstartedClassClassForName(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)259 void UnstartedRuntime::UnstartedClassClassForName(
260 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
261 UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, true, "Class.classForName");
262 }
263
UnstartedClassNewInstance(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)264 void UnstartedRuntime::UnstartedClassNewInstance(
265 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
266 StackHandleScope<2> hs(self); // Class, constructor, object.
267 mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
268 if (param == nullptr) {
269 AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
270 return;
271 }
272 mirror::Class* klass = param->AsClass();
273 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
274
275 // Check that it's not null.
276 if (h_klass == nullptr) {
277 AbortTransactionOrFail(self, "Class reference is null for newInstance");
278 return;
279 }
280
281 // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
282 if (Runtime::Current()->IsActiveTransaction()) {
283 if (h_klass.Get()->IsFinalizable()) {
284 AbortTransactionF(self, "Class for newInstance is finalizable: '%s'",
285 h_klass->PrettyClass().c_str());
286 return;
287 }
288 }
289
290 // There are two situations in which we'll abort this run.
291 // 1) If the class isn't yet initialized and initialization fails.
292 // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
293 // Note that 2) could likely be handled here, but for safety abort the transaction.
294 bool ok = false;
295 auto* cl = Runtime::Current()->GetClassLinker();
296 if (cl->EnsureInitialized(self, h_klass, true, true)) {
297 ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
298 if (cons != nullptr && ShouldBlockAccessToMember(cons, shadow_frame)) {
299 cons = nullptr;
300 }
301 if (cons != nullptr) {
302 Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self)));
303 CHECK(h_obj != nullptr); // We don't expect OOM at compile-time.
304 EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
305 if (!self->IsExceptionPending()) {
306 result->SetL(h_obj.Get());
307 ok = true;
308 }
309 } else {
310 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
311 "Could not find default constructor for '%s'",
312 h_klass->PrettyClass().c_str());
313 }
314 }
315 if (!ok) {
316 AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
317 h_klass->PrettyClass().c_str(),
318 mirror::Object::PrettyTypeOf(self->GetException()).c_str());
319 }
320 }
321
UnstartedClassGetDeclaredField(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)322 void UnstartedRuntime::UnstartedClassGetDeclaredField(
323 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
324 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
325 // going the reflective Dex way.
326 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
327 mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
328 ArtField* found = nullptr;
329 for (ArtField& field : klass->GetIFields()) {
330 if (name2->Equals(field.GetName())) {
331 found = &field;
332 break;
333 }
334 }
335 if (found == nullptr) {
336 for (ArtField& field : klass->GetSFields()) {
337 if (name2->Equals(field.GetName())) {
338 found = &field;
339 break;
340 }
341 }
342 }
343 if (found != nullptr && ShouldBlockAccessToMember(found, shadow_frame)) {
344 found = nullptr;
345 }
346 if (found == nullptr) {
347 AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
348 " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
349 klass->PrettyDescriptor().c_str());
350 return;
351 }
352 Runtime* runtime = Runtime::Current();
353 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
354 mirror::Field* field;
355 if (runtime->IsActiveTransaction()) {
356 if (pointer_size == PointerSize::k64) {
357 field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
358 self, found, true);
359 } else {
360 field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
361 self, found, true);
362 }
363 } else {
364 if (pointer_size == PointerSize::k64) {
365 field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
366 self, found, true);
367 } else {
368 field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
369 self, found, true);
370 }
371 }
372 result->SetL(field);
373 }
374
375 // This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
UnstartedClassGetDeclaredMethod(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)376 void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
377 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
378 // Special managed code cut-out to allow method lookup in a un-started runtime.
379 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
380 if (klass == nullptr) {
381 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
382 return;
383 }
384 mirror::String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
385 mirror::ObjectArray<mirror::Class>* args =
386 shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
387 Runtime* runtime = Runtime::Current();
388 bool transaction = runtime->IsActiveTransaction();
389 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
390 ObjPtr<mirror::Method> method;
391 if (transaction) {
392 if (pointer_size == PointerSize::k64) {
393 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
394 self, klass, name, args);
395 } else {
396 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
397 self, klass, name, args);
398 }
399 } else {
400 if (pointer_size == PointerSize::k64) {
401 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
402 self, klass, name, args);
403 } else {
404 method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
405 self, klass, name, args);
406 }
407 }
408 if (method != nullptr && ShouldBlockAccessToMember(method->GetArtMethod(), shadow_frame)) {
409 method = nullptr;
410 }
411 result->SetL(method);
412 }
413
414 // Special managed code cut-out to allow constructor lookup in a un-started runtime.
UnstartedClassGetDeclaredConstructor(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)415 void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
416 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
417 mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
418 if (klass == nullptr) {
419 ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
420 return;
421 }
422 mirror::ObjectArray<mirror::Class>* args =
423 shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
424 Runtime* runtime = Runtime::Current();
425 bool transaction = runtime->IsActiveTransaction();
426 PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
427 ObjPtr<mirror::Constructor> constructor;
428 if (transaction) {
429 if (pointer_size == PointerSize::k64) {
430 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
431 true>(self, klass, args);
432 } else {
433 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
434 true>(self, klass, args);
435 }
436 } else {
437 if (pointer_size == PointerSize::k64) {
438 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
439 false>(self, klass, args);
440 } else {
441 constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
442 false>(self, klass, args);
443 }
444 }
445 if (constructor != nullptr &&
446 ShouldBlockAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
447 constructor = nullptr;
448 }
449 result->SetL(constructor);
450 }
451
UnstartedClassGetDeclaringClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)452 void UnstartedRuntime::UnstartedClassGetDeclaringClass(
453 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
454 StackHandleScope<1> hs(self);
455 Handle<mirror::Class> klass(hs.NewHandle(
456 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
457 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
458 result->SetL(nullptr);
459 return;
460 }
461 // Return null for anonymous classes.
462 JValue is_anon_result;
463 UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
464 if (is_anon_result.GetZ() != 0) {
465 result->SetL(nullptr);
466 return;
467 }
468 result->SetL(annotations::GetDeclaringClass(klass));
469 }
470
UnstartedClassGetEnclosingClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)471 void UnstartedRuntime::UnstartedClassGetEnclosingClass(
472 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
473 StackHandleScope<1> hs(self);
474 Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
475 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
476 result->SetL(nullptr);
477 }
478 result->SetL(annotations::GetEnclosingClass(klass));
479 }
480
UnstartedClassGetInnerClassFlags(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)481 void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
482 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
483 StackHandleScope<1> hs(self);
484 Handle<mirror::Class> klass(hs.NewHandle(
485 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
486 const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
487 result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
488 }
489
UnstartedClassGetSignatureAnnotation(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)490 void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
491 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
492 StackHandleScope<1> hs(self);
493 Handle<mirror::Class> klass(hs.NewHandle(
494 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
495
496 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
497 result->SetL(nullptr);
498 return;
499 }
500
501 result->SetL(annotations::GetSignatureAnnotationForClass(klass));
502 }
503
UnstartedClassIsAnonymousClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)504 void UnstartedRuntime::UnstartedClassIsAnonymousClass(
505 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
506 StackHandleScope<1> hs(self);
507 Handle<mirror::Class> klass(hs.NewHandle(
508 reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
509 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
510 result->SetZ(false);
511 return;
512 }
513 mirror::String* class_name = nullptr;
514 if (!annotations::GetInnerClass(klass, &class_name)) {
515 result->SetZ(false);
516 return;
517 }
518 result->SetZ(class_name == nullptr);
519 }
520
FindAndExtractEntry(const std::string & jar_file,const char * entry_name,size_t * size,std::string * error_msg)521 static std::unique_ptr<MemMap> FindAndExtractEntry(const std::string& jar_file,
522 const char* entry_name,
523 size_t* size,
524 std::string* error_msg) {
525 CHECK(size != nullptr);
526
527 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
528 if (zip_archive == nullptr) {
529 return nullptr;
530 }
531 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
532 if (zip_entry == nullptr) {
533 return nullptr;
534 }
535 std::unique_ptr<MemMap> tmp_map(
536 zip_entry->ExtractToMemMap(jar_file.c_str(), entry_name, error_msg));
537 if (tmp_map == nullptr) {
538 return nullptr;
539 }
540
541 // OK, from here everything seems fine.
542 *size = zip_entry->GetUncompressedLength();
543 return tmp_map;
544 }
545
GetResourceAsStream(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)546 static void GetResourceAsStream(Thread* self,
547 ShadowFrame* shadow_frame,
548 JValue* result,
549 size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
550 mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
551 if (resource_obj == nullptr) {
552 AbortTransactionOrFail(self, "null name for getResourceAsStream");
553 return;
554 }
555 CHECK(resource_obj->IsString());
556 mirror::String* resource_name = resource_obj->AsString();
557
558 std::string resource_name_str = resource_name->ToModifiedUtf8();
559 if (resource_name_str.empty() || resource_name_str == "/") {
560 AbortTransactionOrFail(self,
561 "Unsupported name %s for getResourceAsStream",
562 resource_name_str.c_str());
563 return;
564 }
565 const char* resource_cstr = resource_name_str.c_str();
566 if (resource_cstr[0] == '/') {
567 resource_cstr++;
568 }
569
570 Runtime* runtime = Runtime::Current();
571
572 std::vector<std::string> split;
573 Split(runtime->GetBootClassPathString(), ':', &split);
574 if (split.empty()) {
575 AbortTransactionOrFail(self,
576 "Boot classpath not set or split error:: %s",
577 runtime->GetBootClassPathString().c_str());
578 return;
579 }
580
581 std::unique_ptr<MemMap> mem_map;
582 size_t map_size;
583 std::string last_error_msg; // Only store the last message (we could concatenate).
584
585 for (const std::string& jar_file : split) {
586 mem_map = FindAndExtractEntry(jar_file, resource_cstr, &map_size, &last_error_msg);
587 if (mem_map != nullptr) {
588 break;
589 }
590 }
591
592 if (mem_map == nullptr) {
593 // Didn't find it. There's a good chance this will be the same at runtime, but still
594 // conservatively abort the transaction here.
595 AbortTransactionOrFail(self,
596 "Could not find resource %s. Last error was %s.",
597 resource_name_str.c_str(),
598 last_error_msg.c_str());
599 return;
600 }
601
602 StackHandleScope<3> hs(self);
603
604 // Create byte array for content.
605 Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
606 if (h_array == nullptr) {
607 AbortTransactionOrFail(self, "Could not find/create byte array class");
608 return;
609 }
610 // Copy in content.
611 memcpy(h_array->GetData(), mem_map->Begin(), map_size);
612 // Be proactive releasing memory.
613 mem_map.reset();
614
615 // Create a ByteArrayInputStream.
616 Handle<mirror::Class> h_class(hs.NewHandle(
617 runtime->GetClassLinker()->FindClass(self,
618 "Ljava/io/ByteArrayInputStream;",
619 ScopedNullHandle<mirror::ClassLoader>())));
620 if (h_class == nullptr) {
621 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
622 return;
623 }
624 if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
625 AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
626 return;
627 }
628
629 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
630 if (h_obj == nullptr) {
631 AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
632 return;
633 }
634
635 auto* cl = Runtime::Current()->GetClassLinker();
636 ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
637 if (constructor == nullptr) {
638 AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
639 return;
640 }
641
642 uint32_t args[1];
643 args[0] = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_array.Get()));
644 EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
645
646 if (self->IsExceptionPending()) {
647 AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
648 return;
649 }
650
651 result->SetL(h_obj.Get());
652 }
653
UnstartedClassLoaderGetResourceAsStream(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)654 void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
655 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
656 {
657 mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
658 CHECK(this_obj != nullptr);
659 CHECK(this_obj->IsClassLoader());
660
661 StackHandleScope<1> hs(self);
662 Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
663
664 if (self->DecodeJObject(WellKnownClasses::java_lang_BootClassLoader) !=
665 this_classloader_class.Get()) {
666 AbortTransactionOrFail(self,
667 "Unsupported classloader type %s for getResourceAsStream",
668 mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
669 return;
670 }
671 }
672
673 GetResourceAsStream(self, shadow_frame, result, arg_offset);
674 }
675
UnstartedConstructorNewInstance0(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)676 void UnstartedRuntime::UnstartedConstructorNewInstance0(
677 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
678 // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
679 StackHandleScope<4> hs(self);
680 Handle<mirror::Constructor> m = hs.NewHandle(
681 reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
682 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
683 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
684 shadow_frame->GetVRegReference(arg_offset + 1)));
685 Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
686 if (UNLIKELY(c->IsAbstract())) {
687 AbortTransactionOrFail(self, "Cannot handle abstract classes");
688 return;
689 }
690 // Verify that we can access the class.
691 if (!m->IsAccessible() && !c->IsPublic()) {
692 // Go 2 frames back, this method is always called from newInstance0, which is called from
693 // Constructor.newInstance(Object... args).
694 ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
695 // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
696 // access checks anyways. TODO: Investigate if this the correct behavior.
697 if (caller != nullptr && !caller->CanAccess(c.Get())) {
698 AbortTransactionOrFail(self, "Cannot access class");
699 return;
700 }
701 }
702 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
703 DCHECK(self->IsExceptionPending());
704 return;
705 }
706 if (c->IsClassClass()) {
707 AbortTransactionOrFail(self, "new Class() is not supported");
708 return;
709 }
710
711 // String constructor is replaced by a StringFactory method in InvokeMethod.
712 if (c->IsStringClass()) {
713 // We don't support strings.
714 AbortTransactionOrFail(self, "String construction is not supported");
715 return;
716 }
717
718 Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
719 if (receiver == nullptr) {
720 AbortTransactionOrFail(self, "Could not allocate");
721 return;
722 }
723
724 // It's easier to use reflection to make the call, than create the uint32_t array.
725 {
726 ScopedObjectAccessUnchecked soa(self);
727 ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
728 soa.AddLocalReference<jobject>(m.Get()));
729 ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
730 soa.AddLocalReference<jobject>(receiver.Get()));
731 ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
732 soa.AddLocalReference<jobject>(args.Get()));
733 InvokeMethod(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
734 }
735 if (self->IsExceptionPending()) {
736 AbortTransactionOrFail(self, "Failed running constructor");
737 } else {
738 result->SetL(receiver.Get());
739 }
740 }
741
UnstartedVmClassLoaderFindLoadedClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)742 void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
743 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
744 mirror::String* class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
745 mirror::ClassLoader* class_loader =
746 down_cast<mirror::ClassLoader*>(shadow_frame->GetVRegReference(arg_offset));
747 StackHandleScope<2> hs(self);
748 Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
749 Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
750 UnstartedRuntimeFindClass(self, h_class_name, h_class_loader, result,
751 "VMClassLoader.findLoadedClass", false, false);
752 // This might have an error pending. But semantics are to just return null.
753 if (self->IsExceptionPending()) {
754 // If it is an InternalError, keep it. See CheckExceptionGenerateClassNotFound.
755 std::string type(mirror::Object::PrettyTypeOf(self->GetException()));
756 if (type != "java.lang.InternalError") {
757 self->ClearException();
758 }
759 }
760 }
761
762 // Arraycopy emulation.
763 // Note: we can't use any fast copy functions, as they are not available under transaction.
764
765 template <typename T>
PrimitiveArrayCopy(Thread * self,mirror::Array * src_array,int32_t src_pos,mirror::Array * dst_array,int32_t dst_pos,int32_t length)766 static void PrimitiveArrayCopy(Thread* self,
767 mirror::Array* src_array, int32_t src_pos,
768 mirror::Array* dst_array, int32_t dst_pos,
769 int32_t length)
770 REQUIRES_SHARED(Locks::mutator_lock_) {
771 if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
772 AbortTransactionOrFail(self,
773 "Types mismatched in arraycopy: %s vs %s.",
774 mirror::Class::PrettyDescriptor(
775 src_array->GetClass()->GetComponentType()).c_str(),
776 mirror::Class::PrettyDescriptor(
777 dst_array->GetClass()->GetComponentType()).c_str());
778 return;
779 }
780 mirror::PrimitiveArray<T>* src = down_cast<mirror::PrimitiveArray<T>*>(src_array);
781 mirror::PrimitiveArray<T>* dst = down_cast<mirror::PrimitiveArray<T>*>(dst_array);
782 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
783 if (copy_forward) {
784 for (int32_t i = 0; i < length; ++i) {
785 dst->Set(dst_pos + i, src->Get(src_pos + i));
786 }
787 } else {
788 for (int32_t i = 1; i <= length; ++i) {
789 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
790 }
791 }
792 }
793
UnstartedSystemArraycopy(Thread * self,ShadowFrame * shadow_frame,JValue * result ATTRIBUTE_UNUSED,size_t arg_offset)794 void UnstartedRuntime::UnstartedSystemArraycopy(
795 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
796 // Special case array copying without initializing System.
797 jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
798 jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
799 jint length = shadow_frame->GetVReg(arg_offset + 4);
800
801 mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
802 mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
803 // Null checking. For simplicity, abort transaction.
804 if (src_obj == nullptr) {
805 AbortTransactionOrFail(self, "src is null in arraycopy.");
806 return;
807 }
808 if (dst_obj == nullptr) {
809 AbortTransactionOrFail(self, "dst is null in arraycopy.");
810 return;
811 }
812 // Test for arrayness. Throw ArrayStoreException.
813 if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
814 self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
815 return;
816 }
817
818 mirror::Array* src_array = src_obj->AsArray();
819 mirror::Array* dst_array = dst_obj->AsArray();
820
821 // Bounds checking. Throw IndexOutOfBoundsException.
822 if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
823 UNLIKELY(src_pos > src_array->GetLength() - length) ||
824 UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
825 self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
826 "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
827 src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
828 length);
829 return;
830 }
831
832 // Type checking.
833 mirror::Class* src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
834 GetComponentType();
835
836 if (!src_type->IsPrimitive()) {
837 // Check that the second type is not primitive.
838 mirror::Class* trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
839 GetComponentType();
840 if (trg_type->IsPrimitiveInt()) {
841 AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
842 mirror::Class::PrettyDescriptor(
843 src_array->GetClass()->GetComponentType()).c_str(),
844 mirror::Class::PrettyDescriptor(
845 dst_array->GetClass()->GetComponentType()).c_str());
846 return;
847 }
848
849 mirror::ObjectArray<mirror::Object>* src = src_array->AsObjectArray<mirror::Object>();
850 mirror::ObjectArray<mirror::Object>* dst = dst_array->AsObjectArray<mirror::Object>();
851 if (src == dst) {
852 // Can overlap, but not have type mismatches.
853 // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
854 const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
855 if (copy_forward) {
856 for (int32_t i = 0; i < length; ++i) {
857 dst->Set(dst_pos + i, src->Get(src_pos + i));
858 }
859 } else {
860 for (int32_t i = 1; i <= length; ++i) {
861 dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
862 }
863 }
864 } else {
865 // We're being lazy here. Optimally this could be a memcpy (if component types are
866 // assignable), but the ObjectArray implementation doesn't support transactions. The
867 // checking version, however, does.
868 if (Runtime::Current()->IsActiveTransaction()) {
869 dst->AssignableCheckingMemcpy<true>(
870 dst_pos, src, src_pos, length, true /* throw_exception */);
871 } else {
872 dst->AssignableCheckingMemcpy<false>(
873 dst_pos, src, src_pos, length, true /* throw_exception */);
874 }
875 }
876 } else if (src_type->IsPrimitiveByte()) {
877 PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
878 } else if (src_type->IsPrimitiveChar()) {
879 PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
880 } else if (src_type->IsPrimitiveInt()) {
881 PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
882 } else {
883 AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
884 src_type->PrettyDescriptor().c_str());
885 }
886 }
887
UnstartedSystemArraycopyByte(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)888 void UnstartedRuntime::UnstartedSystemArraycopyByte(
889 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
890 // Just forward.
891 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
892 }
893
UnstartedSystemArraycopyChar(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)894 void UnstartedRuntime::UnstartedSystemArraycopyChar(
895 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
896 // Just forward.
897 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
898 }
899
UnstartedSystemArraycopyInt(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)900 void UnstartedRuntime::UnstartedSystemArraycopyInt(
901 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
902 // Just forward.
903 UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
904 }
905
UnstartedSystemGetSecurityManager(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame ATTRIBUTE_UNUSED,JValue * result,size_t arg_offset ATTRIBUTE_UNUSED)906 void UnstartedRuntime::UnstartedSystemGetSecurityManager(
907 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
908 JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
909 result->SetL(nullptr);
910 }
911
912 static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
913
GetSystemProperty(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset,bool is_default_version)914 static void GetSystemProperty(Thread* self,
915 ShadowFrame* shadow_frame,
916 JValue* result,
917 size_t arg_offset,
918 bool is_default_version)
919 REQUIRES_SHARED(Locks::mutator_lock_) {
920 StackHandleScope<4> hs(self);
921 Handle<mirror::String> h_key(
922 hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
923 if (h_key == nullptr) {
924 AbortTransactionOrFail(self, "getProperty key was null");
925 return;
926 }
927
928 // This is overall inefficient, but reflecting the values here is not great, either. So
929 // for simplicity, and with the assumption that the number of getProperty calls is not
930 // too great, just iterate each time.
931
932 // Get the storage class.
933 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
934 Handle<mirror::Class> h_props_class(hs.NewHandle(
935 class_linker->FindClass(self,
936 "Ljava/lang/AndroidHardcodedSystemProperties;",
937 ScopedNullHandle<mirror::ClassLoader>())));
938 if (h_props_class == nullptr) {
939 AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
940 return;
941 }
942 if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
943 AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
944 return;
945 }
946
947 // Get the storage array.
948 ArtField* static_properties =
949 h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
950 "[[Ljava/lang/String;");
951 if (static_properties == nullptr) {
952 AbortTransactionOrFail(self,
953 "Could not find %s field",
954 kAndroidHardcodedSystemPropertiesFieldName);
955 return;
956 }
957 ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
958 Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
959 props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
960 if (h_2string_array == nullptr) {
961 AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
962 return;
963 }
964
965 // Iterate over it.
966 const int32_t prop_count = h_2string_array->GetLength();
967 // Use the third handle as mutable.
968 MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
969 hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
970 for (int32_t i = 0; i < prop_count; ++i) {
971 h_string_array.Assign(h_2string_array->Get(i));
972 if (h_string_array == nullptr ||
973 h_string_array->GetLength() != 2 ||
974 h_string_array->Get(0) == nullptr) {
975 AbortTransactionOrFail(self,
976 "Unexpected content of %s",
977 kAndroidHardcodedSystemPropertiesFieldName);
978 return;
979 }
980 if (h_key->Equals(h_string_array->Get(0))) {
981 // Found a value.
982 if (h_string_array->Get(1) == nullptr && is_default_version) {
983 // Null is being delegated to the default map, and then resolved to the given default value.
984 // As there's no default map, return the given value.
985 result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
986 } else {
987 result->SetL(h_string_array->Get(1));
988 }
989 return;
990 }
991 }
992
993 // Key is not supported.
994 AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
995 }
996
UnstartedSystemGetProperty(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)997 void UnstartedRuntime::UnstartedSystemGetProperty(
998 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
999 GetSystemProperty(self, shadow_frame, result, arg_offset, false);
1000 }
1001
UnstartedSystemGetPropertyWithDefault(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1002 void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
1003 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1004 GetSystemProperty(self, shadow_frame, result, arg_offset, true);
1005 }
1006
GetImmediateCaller(ShadowFrame * shadow_frame)1007 static std::string GetImmediateCaller(ShadowFrame* shadow_frame)
1008 REQUIRES_SHARED(Locks::mutator_lock_) {
1009 if (shadow_frame->GetLink() == nullptr) {
1010 return "<no caller>";
1011 }
1012 return ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1013 }
1014
CheckCallers(ShadowFrame * shadow_frame,std::initializer_list<std::string> allowed_call_stack)1015 static bool CheckCallers(ShadowFrame* shadow_frame,
1016 std::initializer_list<std::string> allowed_call_stack)
1017 REQUIRES_SHARED(Locks::mutator_lock_) {
1018 for (const std::string& allowed_caller : allowed_call_stack) {
1019 if (shadow_frame->GetLink() == nullptr) {
1020 return false;
1021 }
1022
1023 std::string found_caller = ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1024 if (allowed_caller != found_caller) {
1025 return false;
1026 }
1027
1028 shadow_frame = shadow_frame->GetLink();
1029 }
1030 return true;
1031 }
1032
CreateInstanceOf(Thread * self,const char * class_descriptor)1033 static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_descriptor)
1034 REQUIRES_SHARED(Locks::mutator_lock_) {
1035 // Find the requested class.
1036 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1037 ObjPtr<mirror::Class> klass =
1038 class_linker->FindClass(self, class_descriptor, ScopedNullHandle<mirror::ClassLoader>());
1039 if (klass == nullptr) {
1040 AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
1041 return nullptr;
1042 }
1043
1044 StackHandleScope<2> hs(self);
1045 Handle<mirror::Class> h_class(hs.NewHandle(klass));
1046 Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
1047 if (h_obj != nullptr) {
1048 ArtMethod* init_method = h_class->FindConstructor("()V", class_linker->GetImagePointerSize());
1049 if (init_method == nullptr) {
1050 AbortTransactionOrFail(self, "Could not find <init> for %s", class_descriptor);
1051 return nullptr;
1052 } else {
1053 JValue invoke_result;
1054 EnterInterpreterFromInvoke(self, init_method, h_obj.Get(), nullptr, nullptr);
1055 if (!self->IsExceptionPending()) {
1056 return h_obj.Get();
1057 }
1058 AbortTransactionOrFail(self, "Could not run <init> for %s", class_descriptor);
1059 }
1060 }
1061 AbortTransactionOrFail(self, "Could not allocate instance of %s", class_descriptor);
1062 return nullptr;
1063 }
1064
UnstartedThreadLocalGet(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset ATTRIBUTE_UNUSED)1065 void UnstartedRuntime::UnstartedThreadLocalGet(
1066 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1067 if (CheckCallers(shadow_frame, { "sun.misc.FloatingDecimal$BinaryToASCIIBuffer "
1068 "sun.misc.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1069 result->SetL(CreateInstanceOf(self, "Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;"));
1070 } else {
1071 AbortTransactionOrFail(self,
1072 "ThreadLocal.get() does not support %s",
1073 GetImmediateCaller(shadow_frame).c_str());
1074 }
1075 }
1076
UnstartedThreadCurrentThread(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset ATTRIBUTE_UNUSED)1077 void UnstartedRuntime::UnstartedThreadCurrentThread(
1078 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1079 if (CheckCallers(shadow_frame,
1080 { "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1081 "java.lang.String, long)",
1082 "void java.lang.Thread.<init>()",
1083 "void java.util.logging.LogManager$Cleaner.<init>("
1084 "java.util.logging.LogManager)" })) {
1085 // Whitelist LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
1086 // Thread constructor only asks for the current thread to set up defaults and add the
1087 // thread as unstarted to the ThreadGroup. A faked-up main thread peer is good enough for
1088 // these purposes.
1089 Runtime::Current()->InitThreadGroups(self);
1090 jobject main_peer =
1091 self->CreateCompileTimePeer(self->GetJniEnv(),
1092 "main",
1093 false,
1094 Runtime::Current()->GetMainThreadGroup());
1095 if (main_peer == nullptr) {
1096 AbortTransactionOrFail(self, "Failed allocating peer");
1097 return;
1098 }
1099
1100 result->SetL(self->DecodeJObject(main_peer));
1101 self->GetJniEnv()->DeleteLocalRef(main_peer);
1102 } else {
1103 AbortTransactionOrFail(self,
1104 "Thread.currentThread() does not support %s",
1105 GetImmediateCaller(shadow_frame).c_str());
1106 }
1107 }
1108
UnstartedThreadGetNativeState(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset ATTRIBUTE_UNUSED)1109 void UnstartedRuntime::UnstartedThreadGetNativeState(
1110 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1111 if (CheckCallers(shadow_frame,
1112 { "java.lang.Thread$State java.lang.Thread.getState()",
1113 "java.lang.ThreadGroup java.lang.Thread.getThreadGroup()",
1114 "void java.lang.Thread.init(java.lang.ThreadGroup, java.lang.Runnable, "
1115 "java.lang.String, long)",
1116 "void java.lang.Thread.<init>()",
1117 "void java.util.logging.LogManager$Cleaner.<init>("
1118 "java.util.logging.LogManager)" })) {
1119 // Whitelist reading the state of the "main" thread when creating another (unstarted) thread
1120 // for LogManager. Report the thread as "new" (it really only counts that it isn't terminated).
1121 constexpr int32_t kJavaRunnable = 1;
1122 result->SetI(kJavaRunnable);
1123 } else {
1124 AbortTransactionOrFail(self,
1125 "Thread.getNativeState() does not support %s",
1126 GetImmediateCaller(shadow_frame).c_str());
1127 }
1128 }
1129
UnstartedMathCeil(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1130 void UnstartedRuntime::UnstartedMathCeil(
1131 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1132 result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
1133 }
1134
UnstartedMathFloor(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1135 void UnstartedRuntime::UnstartedMathFloor(
1136 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1137 result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
1138 }
1139
UnstartedMathSin(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1140 void UnstartedRuntime::UnstartedMathSin(
1141 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1142 result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
1143 }
1144
UnstartedMathCos(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1145 void UnstartedRuntime::UnstartedMathCos(
1146 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1147 result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
1148 }
1149
UnstartedMathPow(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1150 void UnstartedRuntime::UnstartedMathPow(
1151 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1152 result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
1153 shadow_frame->GetVRegDouble(arg_offset + 2)));
1154 }
1155
UnstartedObjectHashCode(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1156 void UnstartedRuntime::UnstartedObjectHashCode(
1157 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1158 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1159 result->SetI(obj->IdentityHashCode());
1160 }
1161
UnstartedDoubleDoubleToRawLongBits(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1162 void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits(
1163 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1164 double in = shadow_frame->GetVRegDouble(arg_offset);
1165 result->SetJ(bit_cast<int64_t, double>(in));
1166 }
1167
UnstartedMemoryPeek(Primitive::Type type,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1168 static void UnstartedMemoryPeek(
1169 Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1170 int64_t address = shadow_frame->GetVRegLong(arg_offset);
1171 // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
1172 // aborting the transaction.
1173
1174 switch (type) {
1175 case Primitive::kPrimByte: {
1176 result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
1177 return;
1178 }
1179
1180 case Primitive::kPrimShort: {
1181 typedef int16_t unaligned_short __attribute__ ((aligned (1)));
1182 result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
1183 return;
1184 }
1185
1186 case Primitive::kPrimInt: {
1187 typedef int32_t unaligned_int __attribute__ ((aligned (1)));
1188 result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
1189 return;
1190 }
1191
1192 case Primitive::kPrimLong: {
1193 typedef int64_t unaligned_long __attribute__ ((aligned (1)));
1194 result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
1195 return;
1196 }
1197
1198 case Primitive::kPrimBoolean:
1199 case Primitive::kPrimChar:
1200 case Primitive::kPrimFloat:
1201 case Primitive::kPrimDouble:
1202 case Primitive::kPrimVoid:
1203 case Primitive::kPrimNot:
1204 LOG(FATAL) << "Not in the Memory API: " << type;
1205 UNREACHABLE();
1206 }
1207 LOG(FATAL) << "Should not reach here";
1208 UNREACHABLE();
1209 }
1210
UnstartedMemoryPeekByte(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1211 void UnstartedRuntime::UnstartedMemoryPeekByte(
1212 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1213 UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
1214 }
1215
UnstartedMemoryPeekShort(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1216 void UnstartedRuntime::UnstartedMemoryPeekShort(
1217 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1218 UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
1219 }
1220
UnstartedMemoryPeekInt(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1221 void UnstartedRuntime::UnstartedMemoryPeekInt(
1222 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1223 UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
1224 }
1225
UnstartedMemoryPeekLong(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1226 void UnstartedRuntime::UnstartedMemoryPeekLong(
1227 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1228 UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
1229 }
1230
UnstartedMemoryPeekArray(Primitive::Type type,Thread * self,ShadowFrame * shadow_frame,size_t arg_offset)1231 static void UnstartedMemoryPeekArray(
1232 Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
1233 REQUIRES_SHARED(Locks::mutator_lock_) {
1234 int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1235 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1236 if (obj == nullptr) {
1237 Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
1238 return;
1239 }
1240 mirror::Array* array = obj->AsArray();
1241
1242 int offset = shadow_frame->GetVReg(arg_offset + 3);
1243 int count = shadow_frame->GetVReg(arg_offset + 4);
1244 if (offset < 0 || offset + count > array->GetLength()) {
1245 std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
1246 offset, count, array->GetLength()));
1247 Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
1248 return;
1249 }
1250
1251 switch (type) {
1252 case Primitive::kPrimByte: {
1253 int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
1254 mirror::ByteArray* byte_array = array->AsByteArray();
1255 for (int32_t i = 0; i < count; ++i, ++address) {
1256 byte_array->SetWithoutChecks<true>(i + offset, *address);
1257 }
1258 return;
1259 }
1260
1261 case Primitive::kPrimShort:
1262 case Primitive::kPrimInt:
1263 case Primitive::kPrimLong:
1264 LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1265 UNREACHABLE();
1266
1267 case Primitive::kPrimBoolean:
1268 case Primitive::kPrimChar:
1269 case Primitive::kPrimFloat:
1270 case Primitive::kPrimDouble:
1271 case Primitive::kPrimVoid:
1272 case Primitive::kPrimNot:
1273 LOG(FATAL) << "Not in the Memory API: " << type;
1274 UNREACHABLE();
1275 }
1276 LOG(FATAL) << "Should not reach here";
1277 UNREACHABLE();
1278 }
1279
UnstartedMemoryPeekByteArray(Thread * self,ShadowFrame * shadow_frame,JValue * result ATTRIBUTE_UNUSED,size_t arg_offset)1280 void UnstartedRuntime::UnstartedMemoryPeekByteArray(
1281 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
1282 UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
1283 }
1284
1285 // This allows reading the new style of String objects during compilation.
UnstartedStringGetCharsNoCheck(Thread * self,ShadowFrame * shadow_frame,JValue * result ATTRIBUTE_UNUSED,size_t arg_offset)1286 void UnstartedRuntime::UnstartedStringGetCharsNoCheck(
1287 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) {
1288 jint start = shadow_frame->GetVReg(arg_offset + 1);
1289 jint end = shadow_frame->GetVReg(arg_offset + 2);
1290 jint index = shadow_frame->GetVReg(arg_offset + 4);
1291 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1292 if (string == nullptr) {
1293 AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1294 return;
1295 }
1296 DCHECK_GE(start, 0);
1297 DCHECK_LE(start, end);
1298 DCHECK_LE(end, string->GetLength());
1299 StackHandleScope<1> hs(self);
1300 Handle<mirror::CharArray> h_char_array(
1301 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
1302 DCHECK_GE(index, 0);
1303 DCHECK_LE(index, h_char_array->GetLength());
1304 DCHECK_LE(end - start, h_char_array->GetLength() - index);
1305 string->GetChars(start, end, h_char_array, index);
1306 }
1307
1308 // This allows reading chars from the new style of String objects during compilation.
UnstartedStringCharAt(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1309 void UnstartedRuntime::UnstartedStringCharAt(
1310 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1311 jint index = shadow_frame->GetVReg(arg_offset + 1);
1312 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1313 if (string == nullptr) {
1314 AbortTransactionOrFail(self, "String.charAt with null object");
1315 return;
1316 }
1317 result->SetC(string->CharAt(index));
1318 }
1319
1320 // This allows creating String objects with replaced characters during compilation.
1321 // String.doReplace(char, char) is called from String.replace(char, char) when there is a match.
UnstartedStringDoReplace(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1322 void UnstartedRuntime::UnstartedStringDoReplace(
1323 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1324 jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
1325 jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
1326 StackHandleScope<1> hs(self);
1327 Handle<mirror::String> string =
1328 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
1329 if (string == nullptr) {
1330 AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
1331 return;
1332 }
1333 result->SetL(mirror::String::DoReplace(self, string, old_c, new_c));
1334 }
1335
1336 // This allows creating the new style of String objects during compilation.
UnstartedStringFactoryNewStringFromChars(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1337 void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
1338 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1339 jint offset = shadow_frame->GetVReg(arg_offset);
1340 jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1341 DCHECK_GE(char_count, 0);
1342 StackHandleScope<1> hs(self);
1343 Handle<mirror::CharArray> h_char_array(
1344 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
1345 Runtime* runtime = Runtime::Current();
1346 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1347 result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator));
1348 }
1349
1350 // This allows creating the new style of String objects during compilation.
UnstartedStringFactoryNewStringFromString(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1351 void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
1352 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1353 mirror::String* to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1354 if (to_copy == nullptr) {
1355 AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1356 return;
1357 }
1358 StackHandleScope<1> hs(self);
1359 Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1360 Runtime* runtime = Runtime::Current();
1361 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1362 result->SetL(mirror::String::AllocFromString<true>(self, h_string->GetLength(), h_string, 0,
1363 allocator));
1364 }
1365
UnstartedStringFastSubstring(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1366 void UnstartedRuntime::UnstartedStringFastSubstring(
1367 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1368 jint start = shadow_frame->GetVReg(arg_offset + 1);
1369 jint length = shadow_frame->GetVReg(arg_offset + 2);
1370 DCHECK_GE(start, 0);
1371 DCHECK_GE(length, 0);
1372 StackHandleScope<1> hs(self);
1373 Handle<mirror::String> h_string(
1374 hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
1375 DCHECK_LE(start, h_string->GetLength());
1376 DCHECK_LE(start + length, h_string->GetLength());
1377 Runtime* runtime = Runtime::Current();
1378 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1379 result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator));
1380 }
1381
1382 // This allows getting the char array for new style of String objects during compilation.
UnstartedStringToCharArray(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1383 void UnstartedRuntime::UnstartedStringToCharArray(
1384 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1385 REQUIRES_SHARED(Locks::mutator_lock_) {
1386 mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1387 if (string == nullptr) {
1388 AbortTransactionOrFail(self, "String.charAt with null object");
1389 return;
1390 }
1391 result->SetL(string->ToCharArray(self));
1392 }
1393
1394 // This allows statically initializing ConcurrentHashMap and SynchronousQueue.
UnstartedReferenceGetReferent(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1395 void UnstartedRuntime::UnstartedReferenceGetReferent(
1396 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1397 ObjPtr<mirror::Reference> const ref = down_cast<mirror::Reference*>(
1398 shadow_frame->GetVRegReference(arg_offset));
1399 if (ref == nullptr) {
1400 AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1401 return;
1402 }
1403 ObjPtr<mirror::Object> const referent =
1404 Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1405 result->SetL(referent);
1406 }
1407
1408 // This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1409 // conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1410 // where we can predict the behavior (somewhat).
1411 // Note: this is required (instead of lazy initialization) as these classes are used in the static
1412 // initialization of other classes, so will *use* the value.
UnstartedRuntimeAvailableProcessors(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset ATTRIBUTE_UNUSED)1413 void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(
1414 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset ATTRIBUTE_UNUSED) {
1415 if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
1416 // SynchronousQueue really only separates between single- and multiprocessor case. Return
1417 // 8 as a conservative upper approximation.
1418 result->SetI(8);
1419 } else if (CheckCallers(shadow_frame,
1420 { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
1421 // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1422 // a good upper bound.
1423 // TODO: Consider resetting in the zygote?
1424 result->SetI(8);
1425 } else {
1426 // Not supported.
1427 AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1428 }
1429 }
1430
1431 // This allows accessing ConcurrentHashMap/SynchronousQueue.
1432
UnstartedUnsafeCompareAndSwapLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1433 void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1434 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1435 // Argument 0 is the Unsafe instance, skip.
1436 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1437 if (obj == nullptr) {
1438 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1439 return;
1440 }
1441 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1442 int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1443 int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
1444 bool success;
1445 // Check whether we're in a transaction, call accordingly.
1446 if (Runtime::Current()->IsActiveTransaction()) {
1447 success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1448 expectedValue,
1449 newValue);
1450 } else {
1451 success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1452 expectedValue,
1453 newValue);
1454 }
1455 result->SetZ(success ? 1 : 0);
1456 }
1457
UnstartedUnsafeCompareAndSwapObject(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1458 void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1459 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1460 // Argument 0 is the Unsafe instance, skip.
1461 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1462 if (obj == nullptr) {
1463 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1464 return;
1465 }
1466 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1467 mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1468 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 5);
1469
1470 // Must use non transactional mode.
1471 if (kUseReadBarrier) {
1472 // Need to make sure the reference stored in the field is a to-space one before attempting the
1473 // CAS or the CAS could fail incorrectly.
1474 mirror::HeapReference<mirror::Object>* field_addr =
1475 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1476 reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
1477 ReadBarrier::Barrier<
1478 mirror::Object,
1479 /* kIsVolatile */ false,
1480 kWithReadBarrier,
1481 /* kAlwaysUpdateField */ true>(
1482 obj,
1483 MemberOffset(offset),
1484 field_addr);
1485 }
1486 bool success;
1487 // Check whether we're in a transaction, call accordingly.
1488 if (Runtime::Current()->IsActiveTransaction()) {
1489 success = obj->CasFieldStrongSequentiallyConsistentObject<true>(MemberOffset(offset),
1490 expected_value,
1491 newValue);
1492 } else {
1493 success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
1494 expected_value,
1495 newValue);
1496 }
1497 result->SetZ(success ? 1 : 0);
1498 }
1499
UnstartedUnsafeGetObjectVolatile(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1500 void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1501 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1502 REQUIRES_SHARED(Locks::mutator_lock_) {
1503 // Argument 0 is the Unsafe instance, skip.
1504 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1505 if (obj == nullptr) {
1506 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1507 return;
1508 }
1509 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1510 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1511 result->SetL(value);
1512 }
1513
UnstartedUnsafePutObjectVolatile(Thread * self,ShadowFrame * shadow_frame,JValue * result ATTRIBUTE_UNUSED,size_t arg_offset)1514 void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1515 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
1516 REQUIRES_SHARED(Locks::mutator_lock_) {
1517 // Argument 0 is the Unsafe instance, skip.
1518 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1519 if (obj == nullptr) {
1520 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1521 return;
1522 }
1523 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1524 mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1525 if (Runtime::Current()->IsActiveTransaction()) {
1526 obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1527 } else {
1528 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1529 }
1530 }
1531
UnstartedUnsafePutOrderedObject(Thread * self,ShadowFrame * shadow_frame,JValue * result ATTRIBUTE_UNUSED,size_t arg_offset)1532 void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1533 Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset)
1534 REQUIRES_SHARED(Locks::mutator_lock_) {
1535 // Argument 0 is the Unsafe instance, skip.
1536 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1537 if (obj == nullptr) {
1538 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1539 return;
1540 }
1541 int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1542 mirror::Object* newValue = shadow_frame->GetVRegReference(arg_offset + 4);
1543 QuasiAtomic::ThreadFenceRelease();
1544 if (Runtime::Current()->IsActiveTransaction()) {
1545 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1546 } else {
1547 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1548 }
1549 }
1550
1551 // A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1552 // of correctly handling the corner cases.
UnstartedIntegerParseInt(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1553 void UnstartedRuntime::UnstartedIntegerParseInt(
1554 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1555 REQUIRES_SHARED(Locks::mutator_lock_) {
1556 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1557 if (obj == nullptr) {
1558 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1559 return;
1560 }
1561
1562 std::string string_value = obj->AsString()->ToModifiedUtf8();
1563 if (string_value.empty()) {
1564 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1565 return;
1566 }
1567
1568 const char* c_str = string_value.c_str();
1569 char *end;
1570 // Can we set errno to 0? Is this always a variable, and not a macro?
1571 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1572 int64_t l = strtol(c_str, &end, 10);
1573
1574 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1575 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1576 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1577 return;
1578 }
1579 if (l == 0) {
1580 // Check whether the string wasn't exactly zero.
1581 if (string_value != "0") {
1582 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1583 return;
1584 }
1585 } else if (*end != '\0') {
1586 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1587 return;
1588 }
1589
1590 result->SetI(static_cast<int32_t>(l));
1591 }
1592
1593 // A cutout for Long.parseLong.
1594 //
1595 // Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1596 // well.
UnstartedLongParseLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1597 void UnstartedRuntime::UnstartedLongParseLong(
1598 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1599 REQUIRES_SHARED(Locks::mutator_lock_) {
1600 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1601 if (obj == nullptr) {
1602 AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1603 return;
1604 }
1605
1606 std::string string_value = obj->AsString()->ToModifiedUtf8();
1607 if (string_value.empty()) {
1608 AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1609 return;
1610 }
1611
1612 const char* c_str = string_value.c_str();
1613 char *end;
1614 // Can we set errno to 0? Is this always a variable, and not a macro?
1615 // Worst case, we'll incorrectly fail a transaction. Seems OK.
1616 int64_t l = strtol(c_str, &end, 10);
1617
1618 // Note: comparing against int32_t min/max is intentional here.
1619 if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1620 (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1621 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1622 return;
1623 }
1624 if (l == 0) {
1625 // Check whether the string wasn't exactly zero.
1626 if (string_value != "0") {
1627 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1628 return;
1629 }
1630 } else if (*end != '\0') {
1631 AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1632 return;
1633 }
1634
1635 result->SetJ(l);
1636 }
1637
UnstartedMethodInvoke(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1638 void UnstartedRuntime::UnstartedMethodInvoke(
1639 Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1640 REQUIRES_SHARED(Locks::mutator_lock_) {
1641 JNIEnvExt* env = self->GetJniEnv();
1642 ScopedObjectAccessUnchecked soa(self);
1643
1644 ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
1645 ScopedLocalRef<jobject> java_method(env,
1646 java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
1647
1648 ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
1649 ScopedLocalRef<jobject> java_receiver(env,
1650 java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1651
1652 ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
1653 ScopedLocalRef<jobject> java_args(env,
1654 java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1655
1656 ScopedLocalRef<jobject> result_jobj(env,
1657 InvokeMethod(soa, java_method.get(), java_receiver.get(), java_args.get()));
1658
1659 result->SetL(self->DecodeJObject(result_jobj.get()));
1660
1661 // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1662 // InvocationTargetExceptions.
1663 if (self->IsExceptionPending()) {
1664 AbortTransactionOrFail(self, "Failed Method.invoke");
1665 }
1666 }
1667
UnstartedSystemIdentityHashCode(Thread * self ATTRIBUTE_UNUSED,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1668 void UnstartedRuntime::UnstartedSystemIdentityHashCode(
1669 Thread* self ATTRIBUTE_UNUSED, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1670 REQUIRES_SHARED(Locks::mutator_lock_) {
1671 mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1672 result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1673 }
1674
1675 // Checks whether the runtime is s64-bit. This is needed for the clinit of
1676 // java.lang.invoke.VarHandle clinit. The clinit determines sets of
1677 // available VarHandle accessors and these differ based on machine
1678 // word size.
UnstartedJNIVMRuntimeIs64Bit(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1679 void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit(
1680 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1681 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1682 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1683 jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1684 result->SetZ(is64bit);
1685 }
1686
UnstartedJNIVMRuntimeNewUnpaddedArray(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1687 void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
1688 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1689 uint32_t* args, JValue* result) {
1690 int32_t length = args[1];
1691 DCHECK_GE(length, 0);
1692 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1693 Runtime* runtime = Runtime::Current();
1694 ObjPtr<mirror::Class> array_class =
1695 runtime->GetClassLinker()->FindArrayClass(self, &element_class);
1696 DCHECK(array_class != nullptr);
1697 gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1698 result->SetL(mirror::Array::Alloc<true, true>(self,
1699 array_class,
1700 length,
1701 array_class->GetComponentSizeShift(),
1702 allocator));
1703 }
1704
UnstartedJNIVMStackGetCallingClassLoader(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1705 void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1706 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1707 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1708 result->SetL(nullptr);
1709 }
1710
UnstartedJNIVMStackGetStackClass2(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1711 void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(
1712 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1713 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1714 NthCallerVisitor visitor(self, 3);
1715 visitor.WalkStack();
1716 if (visitor.caller != nullptr) {
1717 result->SetL(visitor.caller->GetDeclaringClass());
1718 }
1719 }
1720
UnstartedJNIMathLog(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1721 void UnstartedRuntime::UnstartedJNIMathLog(
1722 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1723 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1724 JValue value;
1725 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1726 result->SetD(log(value.GetD()));
1727 }
1728
UnstartedJNIMathExp(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1729 void UnstartedRuntime::UnstartedJNIMathExp(
1730 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1731 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1732 JValue value;
1733 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1734 result->SetD(exp(value.GetD()));
1735 }
1736
UnstartedJNIAtomicLongVMSupportsCS8(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1737 void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1738 Thread* self ATTRIBUTE_UNUSED,
1739 ArtMethod* method ATTRIBUTE_UNUSED,
1740 mirror::Object* receiver ATTRIBUTE_UNUSED,
1741 uint32_t* args ATTRIBUTE_UNUSED,
1742 JValue* result) {
1743 result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
1744 ? 0
1745 : 1);
1746 }
1747
UnstartedJNIClassGetNameNative(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1748 void UnstartedRuntime::UnstartedJNIClassGetNameNative(
1749 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1750 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1751 StackHandleScope<1> hs(self);
1752 result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
1753 }
1754
UnstartedJNIDoubleLongBitsToDouble(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1755 void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble(
1756 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1757 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1758 uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
1759 result->SetD(bit_cast<double>(long_input));
1760 }
1761
UnstartedJNIFloatFloatToRawIntBits(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1762 void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits(
1763 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1764 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1765 result->SetI(args[0]);
1766 }
1767
UnstartedJNIFloatIntBitsToFloat(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1768 void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat(
1769 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1770 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1771 result->SetI(args[0]);
1772 }
1773
UnstartedJNIObjectInternalClone(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1774 void UnstartedRuntime::UnstartedJNIObjectInternalClone(
1775 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1776 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1777 result->SetL(receiver->Clone(self));
1778 }
1779
UnstartedJNIObjectNotifyAll(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver,uint32_t * args ATTRIBUTE_UNUSED,JValue * result ATTRIBUTE_UNUSED)1780 void UnstartedRuntime::UnstartedJNIObjectNotifyAll(
1781 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1782 uint32_t* args ATTRIBUTE_UNUSED, JValue* result ATTRIBUTE_UNUSED) {
1783 receiver->NotifyAll(self);
1784 }
1785
UnstartedJNIStringCompareTo(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver,uint32_t * args,JValue * result)1786 void UnstartedRuntime::UnstartedJNIStringCompareTo(
1787 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver, uint32_t* args,
1788 JValue* result) {
1789 mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
1790 if (rhs == nullptr) {
1791 AbortTransactionOrFail(self, "String.compareTo with null object");
1792 }
1793 result->SetI(receiver->AsString()->CompareTo(rhs));
1794 }
1795
UnstartedJNIStringIntern(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1796 void UnstartedRuntime::UnstartedJNIStringIntern(
1797 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver,
1798 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1799 result->SetL(receiver->AsString()->Intern());
1800 }
1801
UnstartedJNIArrayCreateMultiArray(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1802 void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(
1803 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1804 uint32_t* args, JValue* result) {
1805 StackHandleScope<2> hs(self);
1806 auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
1807 auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
1808 result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
1809 }
1810
UnstartedJNIArrayCreateObjectArray(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1811 void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(
1812 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1813 uint32_t* args, JValue* result) {
1814 int32_t length = static_cast<int32_t>(args[1]);
1815 if (length < 0) {
1816 ThrowNegativeArraySizeException(length);
1817 return;
1818 }
1819 ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
1820 Runtime* runtime = Runtime::Current();
1821 ClassLinker* class_linker = runtime->GetClassLinker();
1822 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, &element_class);
1823 if (UNLIKELY(array_class == nullptr)) {
1824 CHECK(self->IsExceptionPending());
1825 return;
1826 }
1827 DCHECK(array_class->IsObjectArrayClass());
1828 mirror::Array* new_array = mirror::ObjectArray<mirror::Object*>::Alloc(
1829 self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
1830 result->SetL(new_array);
1831 }
1832
UnstartedJNIThrowableNativeFillInStackTrace(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1833 void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
1834 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1835 uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1836 ScopedObjectAccessUnchecked soa(self);
1837 if (Runtime::Current()->IsActiveTransaction()) {
1838 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<true>(soa)));
1839 } else {
1840 result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<false>(soa)));
1841 }
1842 }
1843
UnstartedJNIByteOrderIsLittleEndian(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result)1844 void UnstartedRuntime::UnstartedJNIByteOrderIsLittleEndian(
1845 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1846 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args ATTRIBUTE_UNUSED, JValue* result) {
1847 result->SetZ(JNI_TRUE);
1848 }
1849
UnstartedJNIUnsafeCompareAndSwapInt(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1850 void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
1851 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1852 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1853 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1854 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1855 jint expectedValue = args[3];
1856 jint newValue = args[4];
1857 bool success;
1858 if (Runtime::Current()->IsActiveTransaction()) {
1859 success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset),
1860 expectedValue, newValue);
1861 } else {
1862 success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
1863 expectedValue, newValue);
1864 }
1865 result->SetZ(success ? JNI_TRUE : JNI_FALSE);
1866 }
1867
UnstartedJNIUnsafeGetIntVolatile(Thread * self,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1868 void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(
1869 Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
1870 uint32_t* args, JValue* result) {
1871 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1872 if (obj == nullptr) {
1873 AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1874 return;
1875 }
1876
1877 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1878 result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
1879 }
1880
UnstartedJNIUnsafePutObject(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result ATTRIBUTE_UNUSED)1881 void UnstartedRuntime::UnstartedJNIUnsafePutObject(
1882 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1883 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result ATTRIBUTE_UNUSED) {
1884 mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
1885 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
1886 mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
1887 if (Runtime::Current()->IsActiveTransaction()) {
1888 obj->SetFieldObject<true>(MemberOffset(offset), newValue);
1889 } else {
1890 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
1891 }
1892 }
1893
UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1894 void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
1895 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1896 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1897 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1898 Primitive::Type primitive_type = component->GetPrimitiveType();
1899 result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
1900 }
1901
UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args,JValue * result)1902 void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
1903 Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
1904 mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
1905 mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
1906 Primitive::Type primitive_type = component->GetPrimitiveType();
1907 result->SetI(Primitive::ComponentSize(primitive_type));
1908 }
1909
1910 typedef void (*InvokeHandler)(Thread* self, ShadowFrame* shadow_frame, JValue* result,
1911 size_t arg_size);
1912
1913 typedef void (*JNIHandler)(Thread* self, ArtMethod* method, mirror::Object* receiver,
1914 uint32_t* args, JValue* result);
1915
1916 static bool tables_initialized_ = false;
1917 static std::unordered_map<std::string, InvokeHandler> invoke_handlers_;
1918 static std::unordered_map<std::string, JNIHandler> jni_handlers_;
1919
InitializeInvokeHandlers()1920 void UnstartedRuntime::InitializeInvokeHandlers() {
1921 #define UNSTARTED_DIRECT(ShortName, Sig) \
1922 invoke_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::Unstarted ## ShortName));
1923 #include "unstarted_runtime_list.h"
1924 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
1925 #undef UNSTARTED_RUNTIME_DIRECT_LIST
1926 #undef UNSTARTED_RUNTIME_JNI_LIST
1927 #undef UNSTARTED_DIRECT
1928 }
1929
InitializeJNIHandlers()1930 void UnstartedRuntime::InitializeJNIHandlers() {
1931 #define UNSTARTED_JNI(ShortName, Sig) \
1932 jni_handlers_.insert(std::make_pair(Sig, & UnstartedRuntime::UnstartedJNI ## ShortName));
1933 #include "unstarted_runtime_list.h"
1934 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
1935 #undef UNSTARTED_RUNTIME_DIRECT_LIST
1936 #undef UNSTARTED_RUNTIME_JNI_LIST
1937 #undef UNSTARTED_JNI
1938 }
1939
Initialize()1940 void UnstartedRuntime::Initialize() {
1941 CHECK(!tables_initialized_);
1942
1943 InitializeInvokeHandlers();
1944 InitializeJNIHandlers();
1945
1946 tables_initialized_ = true;
1947 }
1948
Invoke(Thread * self,const CodeItemDataAccessor & accessor,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1949 void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
1950 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1951 // In a runtime that's not started we intercept certain methods to avoid complicated dependency
1952 // problems in core libraries.
1953 CHECK(tables_initialized_);
1954
1955 std::string name(ArtMethod::PrettyMethod(shadow_frame->GetMethod()));
1956 const auto& iter = invoke_handlers_.find(name);
1957 if (iter != invoke_handlers_.end()) {
1958 // Clear out the result in case it's not zeroed out.
1959 result->SetL(0);
1960
1961 // Push the shadow frame. This is so the failing method can be seen in abort dumps.
1962 self->PushShadowFrame(shadow_frame);
1963
1964 (*iter->second)(self, shadow_frame, result, arg_offset);
1965
1966 self->PopShadowFrame();
1967 } else {
1968 // Not special, continue with regular interpreter execution.
1969 ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
1970 }
1971 }
1972
1973 // Hand select a number of methods to be run in a not yet started runtime without using JNI.
Jni(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)1974 void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
1975 uint32_t* args, JValue* result) {
1976 std::string name(ArtMethod::PrettyMethod(method));
1977 const auto& iter = jni_handlers_.find(name);
1978 if (iter != jni_handlers_.end()) {
1979 // Clear out the result in case it's not zeroed out.
1980 result->SetL(0);
1981 (*iter->second)(self, method, receiver, args, result);
1982 } else if (Runtime::Current()->IsActiveTransaction()) {
1983 AbortTransactionF(self, "Attempt to invoke native method in non-started runtime: %s",
1984 name.c_str());
1985 } else {
1986 LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method) << " in an unstarted "
1987 "non-transactional runtime";
1988 }
1989 }
1990
1991 } // namespace interpreter
1992 } // namespace art
1993