1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "unstarted_runtime.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
20*795d594fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
21*795d594fSAndroid Build Coastguard Worker #include <ctype.h>
22*795d594fSAndroid Build Coastguard Worker #include <errno.h>
23*795d594fSAndroid Build Coastguard Worker #include <stdlib.h>
24*795d594fSAndroid Build Coastguard Worker
25*795d594fSAndroid Build Coastguard Worker #include <atomic>
26*795d594fSAndroid Build Coastguard Worker #include <cmath>
27*795d594fSAndroid Build Coastguard Worker #include <initializer_list>
28*795d594fSAndroid Build Coastguard Worker #include <limits>
29*795d594fSAndroid Build Coastguard Worker #include <locale>
30*795d594fSAndroid Build Coastguard Worker
31*795d594fSAndroid Build Coastguard Worker #include "art_method-inl.h"
32*795d594fSAndroid Build Coastguard Worker #include "base/casts.h"
33*795d594fSAndroid Build Coastguard Worker #include "base/hash_map.h"
34*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
35*795d594fSAndroid Build Coastguard Worker #include "base/os.h"
36*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h"
37*795d594fSAndroid Build Coastguard Worker #include "base/quasi_atomic.h"
38*795d594fSAndroid Build Coastguard Worker #include "base/unix_file/fd_file.h"
39*795d594fSAndroid Build Coastguard Worker #include "base/zip_archive.h"
40*795d594fSAndroid Build Coastguard Worker #include "class_linker.h"
41*795d594fSAndroid Build Coastguard Worker #include "common_throws.h"
42*795d594fSAndroid Build Coastguard Worker #include "dex/descriptors_names.h"
43*795d594fSAndroid Build Coastguard Worker #include "entrypoints/entrypoint_utils-inl.h"
44*795d594fSAndroid Build Coastguard Worker #include "gc/reference_processor.h"
45*795d594fSAndroid Build Coastguard Worker #include "handle_scope-inl.h"
46*795d594fSAndroid Build Coastguard Worker #include "hidden_api.h"
47*795d594fSAndroid Build Coastguard Worker #include "interpreter/interpreter_common.h"
48*795d594fSAndroid Build Coastguard Worker #include "jvalue-inl.h"
49*795d594fSAndroid Build Coastguard Worker #include "mirror/array-alloc-inl.h"
50*795d594fSAndroid Build Coastguard Worker #include "mirror/array-inl.h"
51*795d594fSAndroid Build Coastguard Worker #include "mirror/class-alloc-inl.h"
52*795d594fSAndroid Build Coastguard Worker #include "mirror/class.h"
53*795d594fSAndroid Build Coastguard Worker #include "mirror/executable-inl.h"
54*795d594fSAndroid Build Coastguard Worker #include "mirror/field.h"
55*795d594fSAndroid Build Coastguard Worker #include "mirror/method.h"
56*795d594fSAndroid Build Coastguard Worker #include "mirror/object-inl.h"
57*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-alloc-inl.h"
58*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-inl.h"
59*795d594fSAndroid Build Coastguard Worker #include "mirror/string-alloc-inl.h"
60*795d594fSAndroid Build Coastguard Worker #include "mirror/string-inl.h"
61*795d594fSAndroid Build Coastguard Worker #include "nativehelper/scoped_local_ref.h"
62*795d594fSAndroid Build Coastguard Worker #include "nth_caller_visitor.h"
63*795d594fSAndroid Build Coastguard Worker #include "reflection.h"
64*795d594fSAndroid Build Coastguard Worker #include "thread-inl.h"
65*795d594fSAndroid Build Coastguard Worker #include "unstarted_runtime_list.h"
66*795d594fSAndroid Build Coastguard Worker #include "well_known_classes-inl.h"
67*795d594fSAndroid Build Coastguard Worker
68*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
69*795d594fSAndroid Build Coastguard Worker namespace interpreter {
70*795d594fSAndroid Build Coastguard Worker
71*795d594fSAndroid Build Coastguard Worker using android::base::StringAppendV;
72*795d594fSAndroid Build Coastguard Worker using android::base::StringPrintf;
73*795d594fSAndroid Build Coastguard Worker
74*795d594fSAndroid Build Coastguard Worker static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
75*795d594fSAndroid Build Coastguard Worker __attribute__((__format__(__printf__, 2, 3)))
76*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_);
77*795d594fSAndroid Build Coastguard Worker
AbortTransactionOrFail(Thread * self,const char * fmt,...)78*795d594fSAndroid Build Coastguard Worker static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) {
79*795d594fSAndroid Build Coastguard Worker va_list args;
80*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
81*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction()) {
82*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
83*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->AbortTransactionV(self, fmt, args);
84*795d594fSAndroid Build Coastguard Worker va_end(args);
85*795d594fSAndroid Build Coastguard Worker } else {
86*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
87*795d594fSAndroid Build Coastguard Worker std::string msg;
88*795d594fSAndroid Build Coastguard Worker StringAppendV(&msg, fmt, args);
89*795d594fSAndroid Build Coastguard Worker va_end(args);
90*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Trying to abort, but not in transaction mode: " << msg;
91*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
92*795d594fSAndroid Build Coastguard Worker }
93*795d594fSAndroid Build Coastguard Worker }
94*795d594fSAndroid Build Coastguard Worker
95*795d594fSAndroid Build Coastguard Worker // Restricted support for character upper case / lower case. Only support ASCII, where
96*795d594fSAndroid Build Coastguard Worker // it's easy. Abort the transaction otherwise.
CharacterLowerUpper(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset,bool to_lower_case)97*795d594fSAndroid Build Coastguard Worker static void CharacterLowerUpper(Thread* self,
98*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
99*795d594fSAndroid Build Coastguard Worker JValue* result,
100*795d594fSAndroid Build Coastguard Worker size_t arg_offset,
101*795d594fSAndroid Build Coastguard Worker bool to_lower_case) REQUIRES_SHARED(Locks::mutator_lock_) {
102*795d594fSAndroid Build Coastguard Worker int32_t int_value = shadow_frame->GetVReg(arg_offset);
103*795d594fSAndroid Build Coastguard Worker
104*795d594fSAndroid Build Coastguard Worker // Only ASCII (7-bit).
105*795d594fSAndroid Build Coastguard Worker if (!isascii(int_value)) {
106*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
107*795d594fSAndroid Build Coastguard Worker "Only support ASCII characters for toLowerCase/toUpperCase: %u",
108*795d594fSAndroid Build Coastguard Worker int_value);
109*795d594fSAndroid Build Coastguard Worker return;
110*795d594fSAndroid Build Coastguard Worker }
111*795d594fSAndroid Build Coastguard Worker
112*795d594fSAndroid Build Coastguard Worker // Constructing a `std::locale("C")` is slow. Use an explicit calculation, compare in debug mode.
113*795d594fSAndroid Build Coastguard Worker int32_t masked_value = int_value & ~0x20; // Clear bit distinguishing `A`..`Z` from `a`..`z`.
114*795d594fSAndroid Build Coastguard Worker bool is_ascii_letter = ('A' <= masked_value) && (masked_value <= 'Z');
115*795d594fSAndroid Build Coastguard Worker int32_t result_value = is_ascii_letter ? (masked_value | (to_lower_case ? 0x20 : 0)) : int_value;
116*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(result_value,
117*795d594fSAndroid Build Coastguard Worker to_lower_case
118*795d594fSAndroid Build Coastguard Worker ? std::tolower(dchecked_integral_cast<char>(int_value), std::locale("C"))
119*795d594fSAndroid Build Coastguard Worker : std::toupper(dchecked_integral_cast<char>(int_value), std::locale("C")))
120*795d594fSAndroid Build Coastguard Worker << std::boolalpha << to_lower_case;
121*795d594fSAndroid Build Coastguard Worker result->SetI(result_value);
122*795d594fSAndroid Build Coastguard Worker }
123*795d594fSAndroid Build Coastguard Worker
UnstartedCharacterToLowerCase(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)124*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedCharacterToLowerCase(
125*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
126*795d594fSAndroid Build Coastguard Worker CharacterLowerUpper(self, shadow_frame, result, arg_offset, true);
127*795d594fSAndroid Build Coastguard Worker }
128*795d594fSAndroid Build Coastguard Worker
UnstartedCharacterToUpperCase(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)129*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedCharacterToUpperCase(
130*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
131*795d594fSAndroid Build Coastguard Worker CharacterLowerUpper(self, shadow_frame, result, arg_offset, false);
132*795d594fSAndroid Build Coastguard Worker }
133*795d594fSAndroid Build Coastguard Worker
134*795d594fSAndroid Build Coastguard Worker // 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,bool initialize_class)135*795d594fSAndroid Build Coastguard Worker static void UnstartedRuntimeFindClass(Thread* self,
136*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> className,
137*795d594fSAndroid Build Coastguard Worker Handle<mirror::ClassLoader> class_loader,
138*795d594fSAndroid Build Coastguard Worker JValue* result,
139*795d594fSAndroid Build Coastguard Worker bool initialize_class)
140*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
141*795d594fSAndroid Build Coastguard Worker CHECK(className != nullptr);
142*795d594fSAndroid Build Coastguard Worker std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str()));
143*795d594fSAndroid Build Coastguard Worker ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
144*795d594fSAndroid Build Coastguard Worker
145*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> found =
146*795d594fSAndroid Build Coastguard Worker class_linker->FindClass(self, descriptor.c_str(), descriptor.length(), class_loader);
147*795d594fSAndroid Build Coastguard Worker if (found != nullptr && !found->CheckIsVisibleWithTargetSdk(self)) {
148*795d594fSAndroid Build Coastguard Worker CHECK(self->IsExceptionPending());
149*795d594fSAndroid Build Coastguard Worker return;
150*795d594fSAndroid Build Coastguard Worker }
151*795d594fSAndroid Build Coastguard Worker if (found != nullptr && initialize_class) {
152*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
153*795d594fSAndroid Build Coastguard Worker HandleWrapperObjPtr<mirror::Class> h_class = hs.NewHandleWrapper(&found);
154*795d594fSAndroid Build Coastguard Worker if (!class_linker->EnsureInitialized(self, h_class, true, true)) {
155*795d594fSAndroid Build Coastguard Worker CHECK(self->IsExceptionPending());
156*795d594fSAndroid Build Coastguard Worker return;
157*795d594fSAndroid Build Coastguard Worker }
158*795d594fSAndroid Build Coastguard Worker }
159*795d594fSAndroid Build Coastguard Worker result->SetL(found);
160*795d594fSAndroid Build Coastguard Worker }
161*795d594fSAndroid Build Coastguard Worker
PendingExceptionHasAbortDescriptor(Thread * self)162*795d594fSAndroid Build Coastguard Worker static inline bool PendingExceptionHasAbortDescriptor(Thread* self)
163*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
164*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
165*795d594fSAndroid Build Coastguard Worker return self->GetException()->GetClass()->DescriptorEquals(kTransactionAbortErrorDescriptor);
166*795d594fSAndroid Build Coastguard Worker }
167*795d594fSAndroid Build Coastguard Worker
168*795d594fSAndroid Build Coastguard Worker // Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
169*795d594fSAndroid Build Coastguard Worker // rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
170*795d594fSAndroid Build Coastguard Worker // ClassNotFoundException), so need to do the same. The only exception is if the exception is
171*795d594fSAndroid Build Coastguard Worker // actually the transaction abort exception. This must not be wrapped, as it signals an
172*795d594fSAndroid Build Coastguard Worker // initialization abort.
CheckExceptionGenerateClassNotFound(Thread * self)173*795d594fSAndroid Build Coastguard Worker static void CheckExceptionGenerateClassNotFound(Thread* self)
174*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
175*795d594fSAndroid Build Coastguard Worker if (self->IsExceptionPending()) {
176*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
177*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction()) {
178*795d594fSAndroid Build Coastguard Worker // The boot class path at run time may contain additional dex files with
179*795d594fSAndroid Build Coastguard Worker // the required class definition(s). We cannot throw a normal exception at
180*795d594fSAndroid Build Coastguard Worker // compile time because a class initializer could catch it and successfully
181*795d594fSAndroid Build Coastguard Worker // initialize a class differently than when executing at run time.
182*795d594fSAndroid Build Coastguard Worker // If we're not aborting the transaction yet, abort now. b/183691501
183*795d594fSAndroid Build Coastguard Worker if (!runtime->GetClassLinker()->IsTransactionAborted()) {
184*795d594fSAndroid Build Coastguard Worker DCHECK(!PendingExceptionHasAbortDescriptor(self));
185*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->AbortTransactionF(self, "ClassNotFoundException");
186*795d594fSAndroid Build Coastguard Worker } else {
187*795d594fSAndroid Build Coastguard Worker DCHECK(PendingExceptionHasAbortDescriptor(self))
188*795d594fSAndroid Build Coastguard Worker << self->GetException()->GetClass()->PrettyDescriptor();
189*795d594fSAndroid Build Coastguard Worker }
190*795d594fSAndroid Build Coastguard Worker } else {
191*795d594fSAndroid Build Coastguard Worker // If not in a transaction, it cannot be the transaction abort exception. Wrap it.
192*795d594fSAndroid Build Coastguard Worker DCHECK(!PendingExceptionHasAbortDescriptor(self));
193*795d594fSAndroid Build Coastguard Worker self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
194*795d594fSAndroid Build Coastguard Worker "ClassNotFoundException");
195*795d594fSAndroid Build Coastguard Worker }
196*795d594fSAndroid Build Coastguard Worker }
197*795d594fSAndroid Build Coastguard Worker }
198*795d594fSAndroid Build Coastguard Worker
GetClassName(Thread * self,ShadowFrame * shadow_frame,size_t arg_offset)199*795d594fSAndroid Build Coastguard Worker static ObjPtr<mirror::String> GetClassName(Thread* self,
200*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
201*795d594fSAndroid Build Coastguard Worker size_t arg_offset)
202*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
203*795d594fSAndroid Build Coastguard Worker mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
204*795d594fSAndroid Build Coastguard Worker if (param == nullptr) {
205*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Null-pointer in Class.forName.");
206*795d594fSAndroid Build Coastguard Worker return nullptr;
207*795d594fSAndroid Build Coastguard Worker }
208*795d594fSAndroid Build Coastguard Worker return param->AsString();
209*795d594fSAndroid Build Coastguard Worker }
210*795d594fSAndroid Build Coastguard Worker
GetHiddenapiAccessContextFunction(ShadowFrame * frame)211*795d594fSAndroid Build Coastguard Worker static std::function<hiddenapi::AccessContext()> GetHiddenapiAccessContextFunction(
212*795d594fSAndroid Build Coastguard Worker ShadowFrame* frame) {
213*795d594fSAndroid Build Coastguard Worker return [=]() REQUIRES_SHARED(Locks::mutator_lock_) {
214*795d594fSAndroid Build Coastguard Worker return hiddenapi::AccessContext(frame->GetMethod()->GetDeclaringClass());
215*795d594fSAndroid Build Coastguard Worker };
216*795d594fSAndroid Build Coastguard Worker }
217*795d594fSAndroid Build Coastguard Worker
218*795d594fSAndroid Build Coastguard Worker template<typename T>
ShouldDenyAccessToMember(T * member,ShadowFrame * frame)219*795d594fSAndroid Build Coastguard Worker static ALWAYS_INLINE bool ShouldDenyAccessToMember(T* member, ShadowFrame* frame)
220*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
221*795d594fSAndroid Build Coastguard Worker // All uses in this file are from reflection
222*795d594fSAndroid Build Coastguard Worker constexpr hiddenapi::AccessMethod kAccessMethod = hiddenapi::AccessMethod::kReflection;
223*795d594fSAndroid Build Coastguard Worker return hiddenapi::ShouldDenyAccessToMember(member,
224*795d594fSAndroid Build Coastguard Worker GetHiddenapiAccessContextFunction(frame),
225*795d594fSAndroid Build Coastguard Worker kAccessMethod);
226*795d594fSAndroid Build Coastguard Worker }
227*795d594fSAndroid Build Coastguard Worker
UnstartedClassForNameCommon(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset,bool long_form)228*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassForNameCommon(Thread* self,
229*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
230*795d594fSAndroid Build Coastguard Worker JValue* result,
231*795d594fSAndroid Build Coastguard Worker size_t arg_offset,
232*795d594fSAndroid Build Coastguard Worker bool long_form) {
233*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
234*795d594fSAndroid Build Coastguard Worker if (class_name == nullptr) {
235*795d594fSAndroid Build Coastguard Worker return;
236*795d594fSAndroid Build Coastguard Worker }
237*795d594fSAndroid Build Coastguard Worker bool initialize_class;
238*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ClassLoader> class_loader;
239*795d594fSAndroid Build Coastguard Worker if (long_form) {
240*795d594fSAndroid Build Coastguard Worker initialize_class = shadow_frame->GetVReg(arg_offset + 1) != 0;
241*795d594fSAndroid Build Coastguard Worker class_loader =
242*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ClassLoader>::DownCast(shadow_frame->GetVRegReference(arg_offset + 2));
243*795d594fSAndroid Build Coastguard Worker } else {
244*795d594fSAndroid Build Coastguard Worker initialize_class = true;
245*795d594fSAndroid Build Coastguard Worker // TODO: This is really only correct for the boot classpath, and for robustness we should
246*795d594fSAndroid Build Coastguard Worker // check the caller.
247*795d594fSAndroid Build Coastguard Worker class_loader = nullptr;
248*795d594fSAndroid Build Coastguard Worker }
249*795d594fSAndroid Build Coastguard Worker
250*795d594fSAndroid Build Coastguard Worker if (class_loader != nullptr && !ClassLinker::IsBootClassLoader(class_loader)) {
251*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
252*795d594fSAndroid Build Coastguard Worker "Only the boot classloader is supported: %s",
253*795d594fSAndroid Build Coastguard Worker mirror::Object::PrettyTypeOf(class_loader).c_str());
254*795d594fSAndroid Build Coastguard Worker return;
255*795d594fSAndroid Build Coastguard Worker }
256*795d594fSAndroid Build Coastguard Worker
257*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
258*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
259*795d594fSAndroid Build Coastguard Worker UnstartedRuntimeFindClass(self,
260*795d594fSAndroid Build Coastguard Worker h_class_name,
261*795d594fSAndroid Build Coastguard Worker ScopedNullHandle<mirror::ClassLoader>(),
262*795d594fSAndroid Build Coastguard Worker result,
263*795d594fSAndroid Build Coastguard Worker initialize_class);
264*795d594fSAndroid Build Coastguard Worker CheckExceptionGenerateClassNotFound(self);
265*795d594fSAndroid Build Coastguard Worker }
266*795d594fSAndroid Build Coastguard Worker
UnstartedClassForName(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)267*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassForName(
268*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
269*795d594fSAndroid Build Coastguard Worker UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, /*long_form=*/ false);
270*795d594fSAndroid Build Coastguard Worker }
271*795d594fSAndroid Build Coastguard Worker
UnstartedClassForNameLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)272*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassForNameLong(
273*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
274*795d594fSAndroid Build Coastguard Worker UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, /*long_form=*/ true);
275*795d594fSAndroid Build Coastguard Worker }
276*795d594fSAndroid Build Coastguard Worker
UnstartedClassGetPrimitiveClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)277*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassGetPrimitiveClass(
278*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
279*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> class_name = GetClassName(self, shadow_frame, arg_offset);
280*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> klass = mirror::Class::GetPrimitiveClass(class_name);
281*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(klass == nullptr)) {
282*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
283*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
284*795d594fSAndroid Build Coastguard Worker "Class.getPrimitiveClass() failed: %s",
285*795d594fSAndroid Build Coastguard Worker self->GetException()->GetDetailMessage()->ToModifiedUtf8().c_str());
286*795d594fSAndroid Build Coastguard Worker return;
287*795d594fSAndroid Build Coastguard Worker }
288*795d594fSAndroid Build Coastguard Worker result->SetL(klass);
289*795d594fSAndroid Build Coastguard Worker }
290*795d594fSAndroid Build Coastguard Worker
UnstartedClassClassForName(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)291*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassClassForName(
292*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
293*795d594fSAndroid Build Coastguard Worker UnstartedClassForNameCommon(self, shadow_frame, result, arg_offset, /*long_form=*/ true);
294*795d594fSAndroid Build Coastguard Worker }
295*795d594fSAndroid Build Coastguard Worker
UnstartedClassNewInstance(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)296*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassNewInstance(
297*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
298*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self); // Class, constructor, object.
299*795d594fSAndroid Build Coastguard Worker mirror::Object* param = shadow_frame->GetVRegReference(arg_offset);
300*795d594fSAndroid Build Coastguard Worker if (param == nullptr) {
301*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Null-pointer in Class.newInstance.");
302*795d594fSAndroid Build Coastguard Worker return;
303*795d594fSAndroid Build Coastguard Worker }
304*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> h_klass(hs.NewHandle(param->AsClass()));
305*795d594fSAndroid Build Coastguard Worker
306*795d594fSAndroid Build Coastguard Worker // Check that it's not null.
307*795d594fSAndroid Build Coastguard Worker if (h_klass == nullptr) {
308*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Class reference is null for newInstance");
309*795d594fSAndroid Build Coastguard Worker return;
310*795d594fSAndroid Build Coastguard Worker }
311*795d594fSAndroid Build Coastguard Worker
312*795d594fSAndroid Build Coastguard Worker // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer).
313*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
314*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction() &&
315*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->TransactionAllocationConstraint(self, h_klass.Get())) {
316*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
317*795d594fSAndroid Build Coastguard Worker return;
318*795d594fSAndroid Build Coastguard Worker }
319*795d594fSAndroid Build Coastguard Worker
320*795d594fSAndroid Build Coastguard Worker // There are two situations in which we'll abort this run.
321*795d594fSAndroid Build Coastguard Worker // 1) If the class isn't yet initialized and initialization fails.
322*795d594fSAndroid Build Coastguard Worker // 2) If we can't find the default constructor. We'll postpone the exception to runtime.
323*795d594fSAndroid Build Coastguard Worker // Note that 2) could likely be handled here, but for safety abort the transaction.
324*795d594fSAndroid Build Coastguard Worker bool ok = false;
325*795d594fSAndroid Build Coastguard Worker auto* cl = runtime->GetClassLinker();
326*795d594fSAndroid Build Coastguard Worker if (cl->EnsureInitialized(self, h_klass, true, true)) {
327*795d594fSAndroid Build Coastguard Worker ArtMethod* cons = h_klass->FindConstructor("()V", cl->GetImagePointerSize());
328*795d594fSAndroid Build Coastguard Worker if (cons != nullptr && ShouldDenyAccessToMember(cons, shadow_frame)) {
329*795d594fSAndroid Build Coastguard Worker cons = nullptr;
330*795d594fSAndroid Build Coastguard Worker }
331*795d594fSAndroid Build Coastguard Worker if (cons != nullptr) {
332*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(self)));
333*795d594fSAndroid Build Coastguard Worker CHECK(h_obj != nullptr); // We don't expect OOM at compile-time.
334*795d594fSAndroid Build Coastguard Worker EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr);
335*795d594fSAndroid Build Coastguard Worker if (!self->IsExceptionPending()) {
336*795d594fSAndroid Build Coastguard Worker result->SetL(h_obj.Get());
337*795d594fSAndroid Build Coastguard Worker ok = true;
338*795d594fSAndroid Build Coastguard Worker }
339*795d594fSAndroid Build Coastguard Worker } else {
340*795d594fSAndroid Build Coastguard Worker self->ThrowNewExceptionF("Ljava/lang/InternalError;",
341*795d594fSAndroid Build Coastguard Worker "Could not find default constructor for '%s'",
342*795d594fSAndroid Build Coastguard Worker h_klass->PrettyClass().c_str());
343*795d594fSAndroid Build Coastguard Worker }
344*795d594fSAndroid Build Coastguard Worker }
345*795d594fSAndroid Build Coastguard Worker if (!ok) {
346*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Failed in Class.newInstance for '%s' with %s",
347*795d594fSAndroid Build Coastguard Worker h_klass->PrettyClass().c_str(),
348*795d594fSAndroid Build Coastguard Worker mirror::Object::PrettyTypeOf(self->GetException()).c_str());
349*795d594fSAndroid Build Coastguard Worker }
350*795d594fSAndroid Build Coastguard Worker }
351*795d594fSAndroid Build Coastguard Worker
UnstartedClassGetDeclaredField(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)352*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassGetDeclaredField(
353*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
354*795d594fSAndroid Build Coastguard Worker // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
355*795d594fSAndroid Build Coastguard Worker // going the reflective Dex way.
356*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
357*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
358*795d594fSAndroid Build Coastguard Worker ArtField* found = nullptr;
359*795d594fSAndroid Build Coastguard Worker for (ArtField& field : klass->GetIFields()) {
360*795d594fSAndroid Build Coastguard Worker if (name2->Equals(field.GetName())) {
361*795d594fSAndroid Build Coastguard Worker found = &field;
362*795d594fSAndroid Build Coastguard Worker break;
363*795d594fSAndroid Build Coastguard Worker }
364*795d594fSAndroid Build Coastguard Worker }
365*795d594fSAndroid Build Coastguard Worker if (found == nullptr) {
366*795d594fSAndroid Build Coastguard Worker for (ArtField& field : klass->GetSFields()) {
367*795d594fSAndroid Build Coastguard Worker if (name2->Equals(field.GetName())) {
368*795d594fSAndroid Build Coastguard Worker found = &field;
369*795d594fSAndroid Build Coastguard Worker break;
370*795d594fSAndroid Build Coastguard Worker }
371*795d594fSAndroid Build Coastguard Worker }
372*795d594fSAndroid Build Coastguard Worker }
373*795d594fSAndroid Build Coastguard Worker if (found != nullptr && ShouldDenyAccessToMember(found, shadow_frame)) {
374*795d594fSAndroid Build Coastguard Worker found = nullptr;
375*795d594fSAndroid Build Coastguard Worker }
376*795d594fSAndroid Build Coastguard Worker if (found == nullptr) {
377*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Failed to find field in Class.getDeclaredField in un-started "
378*795d594fSAndroid Build Coastguard Worker " runtime. name=%s class=%s", name2->ToModifiedUtf8().c_str(),
379*795d594fSAndroid Build Coastguard Worker klass->PrettyDescriptor().c_str());
380*795d594fSAndroid Build Coastguard Worker return;
381*795d594fSAndroid Build Coastguard Worker }
382*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Field> field = mirror::Field::CreateFromArtField(self, found, true);
383*795d594fSAndroid Build Coastguard Worker result->SetL(field);
384*795d594fSAndroid Build Coastguard Worker }
385*795d594fSAndroid Build Coastguard Worker
UnstartedClassGetDeclaredFields(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)386*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassGetDeclaredFields(
387*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
388*795d594fSAndroid Build Coastguard Worker // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
389*795d594fSAndroid Build Coastguard Worker // going the reflective Dex way.
390*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
391*795d594fSAndroid Build Coastguard Worker auto object_array = klass->GetDeclaredFields(self,
392*795d594fSAndroid Build Coastguard Worker /*public_only=*/ false,
393*795d594fSAndroid Build Coastguard Worker /*force_resolve=*/ true);
394*795d594fSAndroid Build Coastguard Worker if (object_array != nullptr) {
395*795d594fSAndroid Build Coastguard Worker result->SetL(object_array);
396*795d594fSAndroid Build Coastguard Worker }
397*795d594fSAndroid Build Coastguard Worker }
398*795d594fSAndroid Build Coastguard Worker
UnstartedClassGetPublicDeclaredFields(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)399*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassGetPublicDeclaredFields(
400*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
401*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
402*795d594fSAndroid Build Coastguard Worker auto object_array = klass->GetDeclaredFields(self,
403*795d594fSAndroid Build Coastguard Worker /*public_only=*/ true,
404*795d594fSAndroid Build Coastguard Worker /*force_resolve=*/ true);
405*795d594fSAndroid Build Coastguard Worker if (object_array != nullptr) {
406*795d594fSAndroid Build Coastguard Worker result->SetL(object_array);
407*795d594fSAndroid Build Coastguard Worker }
408*795d594fSAndroid Build Coastguard Worker }
409*795d594fSAndroid Build Coastguard Worker
410*795d594fSAndroid Build Coastguard Worker // 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)411*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
412*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
413*795d594fSAndroid Build Coastguard Worker // Special managed code cut-out to allow method lookup in a un-started runtime.
414*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
415*795d594fSAndroid Build Coastguard Worker if (klass == nullptr) {
416*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
417*795d594fSAndroid Build Coastguard Worker return;
418*795d594fSAndroid Build Coastguard Worker }
419*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
420*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> args =
421*795d594fSAndroid Build Coastguard Worker shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>();
422*795d594fSAndroid Build Coastguard Worker PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
423*795d594fSAndroid Build Coastguard Worker auto fn_hiddenapi_access_context = GetHiddenapiAccessContextFunction(shadow_frame);
424*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Method> method = (pointer_size == PointerSize::k64)
425*795d594fSAndroid Build Coastguard Worker ? mirror::Class::GetDeclaredMethodInternal<PointerSize::k64>(
426*795d594fSAndroid Build Coastguard Worker self, klass, name, args, fn_hiddenapi_access_context)
427*795d594fSAndroid Build Coastguard Worker : mirror::Class::GetDeclaredMethodInternal<PointerSize::k32>(
428*795d594fSAndroid Build Coastguard Worker self, klass, name, args, fn_hiddenapi_access_context);
429*795d594fSAndroid Build Coastguard Worker if (method != nullptr && ShouldDenyAccessToMember(method->GetArtMethod(), shadow_frame)) {
430*795d594fSAndroid Build Coastguard Worker method = nullptr;
431*795d594fSAndroid Build Coastguard Worker }
432*795d594fSAndroid Build Coastguard Worker result->SetL(method);
433*795d594fSAndroid Build Coastguard Worker }
434*795d594fSAndroid Build Coastguard Worker
435*795d594fSAndroid Build Coastguard Worker // 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)436*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
437*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
438*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
439*795d594fSAndroid Build Coastguard Worker if (klass == nullptr) {
440*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual);
441*795d594fSAndroid Build Coastguard Worker return;
442*795d594fSAndroid Build Coastguard Worker }
443*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Class>> args =
444*795d594fSAndroid Build Coastguard Worker shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
445*795d594fSAndroid Build Coastguard Worker PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
446*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Constructor> constructor = (pointer_size == PointerSize::k64)
447*795d594fSAndroid Build Coastguard Worker ? mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64>(self, klass, args)
448*795d594fSAndroid Build Coastguard Worker : mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32>(self, klass, args);
449*795d594fSAndroid Build Coastguard Worker if (constructor != nullptr &&
450*795d594fSAndroid Build Coastguard Worker ShouldDenyAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
451*795d594fSAndroid Build Coastguard Worker constructor = nullptr;
452*795d594fSAndroid Build Coastguard Worker }
453*795d594fSAndroid Build Coastguard Worker result->SetL(constructor);
454*795d594fSAndroid Build Coastguard Worker }
455*795d594fSAndroid Build Coastguard Worker
UnstartedClassGetDeclaringClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)456*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassGetDeclaringClass(
457*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
458*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
459*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> klass(hs.NewHandle(
460*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
461*795d594fSAndroid Build Coastguard Worker if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
462*795d594fSAndroid Build Coastguard Worker result->SetL(nullptr);
463*795d594fSAndroid Build Coastguard Worker return;
464*795d594fSAndroid Build Coastguard Worker }
465*795d594fSAndroid Build Coastguard Worker // Return null for anonymous classes.
466*795d594fSAndroid Build Coastguard Worker JValue is_anon_result;
467*795d594fSAndroid Build Coastguard Worker UnstartedClassIsAnonymousClass(self, shadow_frame, &is_anon_result, arg_offset);
468*795d594fSAndroid Build Coastguard Worker if (is_anon_result.GetZ() != 0) {
469*795d594fSAndroid Build Coastguard Worker result->SetL(nullptr);
470*795d594fSAndroid Build Coastguard Worker return;
471*795d594fSAndroid Build Coastguard Worker }
472*795d594fSAndroid Build Coastguard Worker result->SetL(annotations::GetDeclaringClass(klass));
473*795d594fSAndroid Build Coastguard Worker }
474*795d594fSAndroid Build Coastguard Worker
UnstartedClassGetEnclosingClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)475*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassGetEnclosingClass(
476*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
477*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
478*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> klass(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsClass()));
479*795d594fSAndroid Build Coastguard Worker if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
480*795d594fSAndroid Build Coastguard Worker result->SetL(nullptr);
481*795d594fSAndroid Build Coastguard Worker return;
482*795d594fSAndroid Build Coastguard Worker }
483*795d594fSAndroid Build Coastguard Worker result->SetL(annotations::GetEnclosingClass(klass));
484*795d594fSAndroid Build Coastguard Worker }
485*795d594fSAndroid Build Coastguard Worker
UnstartedClassGetInnerClassFlags(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)486*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassGetInnerClassFlags(
487*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
488*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
489*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> klass(hs.NewHandle(
490*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
491*795d594fSAndroid Build Coastguard Worker const int32_t default_value = shadow_frame->GetVReg(arg_offset + 1);
492*795d594fSAndroid Build Coastguard Worker result->SetI(mirror::Class::GetInnerClassFlags(klass, default_value));
493*795d594fSAndroid Build Coastguard Worker }
494*795d594fSAndroid Build Coastguard Worker
UnstartedClassGetSignatureAnnotation(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)495*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassGetSignatureAnnotation(
496*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
497*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
498*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> klass(hs.NewHandle(
499*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
500*795d594fSAndroid Build Coastguard Worker
501*795d594fSAndroid Build Coastguard Worker if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
502*795d594fSAndroid Build Coastguard Worker result->SetL(nullptr);
503*795d594fSAndroid Build Coastguard Worker return;
504*795d594fSAndroid Build Coastguard Worker }
505*795d594fSAndroid Build Coastguard Worker
506*795d594fSAndroid Build Coastguard Worker result->SetL(annotations::GetSignatureAnnotationForClass(klass));
507*795d594fSAndroid Build Coastguard Worker }
508*795d594fSAndroid Build Coastguard Worker
UnstartedClassIsAnonymousClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)509*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassIsAnonymousClass(
510*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
511*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
512*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> klass(hs.NewHandle(
513*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::Class*>(shadow_frame->GetVRegReference(arg_offset))));
514*795d594fSAndroid Build Coastguard Worker if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
515*795d594fSAndroid Build Coastguard Worker result->SetZ(false);
516*795d594fSAndroid Build Coastguard Worker return;
517*795d594fSAndroid Build Coastguard Worker }
518*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> class_name = nullptr;
519*795d594fSAndroid Build Coastguard Worker if (!annotations::GetInnerClass(klass, &class_name)) {
520*795d594fSAndroid Build Coastguard Worker result->SetZ(false);
521*795d594fSAndroid Build Coastguard Worker return;
522*795d594fSAndroid Build Coastguard Worker }
523*795d594fSAndroid Build Coastguard Worker result->SetZ(class_name == nullptr);
524*795d594fSAndroid Build Coastguard Worker }
525*795d594fSAndroid Build Coastguard Worker
FindAndExtractEntry(const std::string & bcp_jar_file,int jar_fd,const char * entry_name,size_t * size,std::string * error_msg)526*795d594fSAndroid Build Coastguard Worker static MemMap FindAndExtractEntry(const std::string& bcp_jar_file,
527*795d594fSAndroid Build Coastguard Worker int jar_fd,
528*795d594fSAndroid Build Coastguard Worker const char* entry_name,
529*795d594fSAndroid Build Coastguard Worker size_t* size,
530*795d594fSAndroid Build Coastguard Worker std::string* error_msg) {
531*795d594fSAndroid Build Coastguard Worker CHECK(size != nullptr);
532*795d594fSAndroid Build Coastguard Worker
533*795d594fSAndroid Build Coastguard Worker std::unique_ptr<ZipArchive> zip_archive;
534*795d594fSAndroid Build Coastguard Worker if (jar_fd >= 0) {
535*795d594fSAndroid Build Coastguard Worker zip_archive.reset(ZipArchive::OpenFromOwnedFd(jar_fd, bcp_jar_file.c_str(), error_msg));
536*795d594fSAndroid Build Coastguard Worker } else {
537*795d594fSAndroid Build Coastguard Worker zip_archive.reset(ZipArchive::Open(bcp_jar_file.c_str(), error_msg));
538*795d594fSAndroid Build Coastguard Worker }
539*795d594fSAndroid Build Coastguard Worker if (zip_archive == nullptr) {
540*795d594fSAndroid Build Coastguard Worker return MemMap::Invalid();
541*795d594fSAndroid Build Coastguard Worker }
542*795d594fSAndroid Build Coastguard Worker std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
543*795d594fSAndroid Build Coastguard Worker if (zip_entry == nullptr) {
544*795d594fSAndroid Build Coastguard Worker return MemMap::Invalid();
545*795d594fSAndroid Build Coastguard Worker }
546*795d594fSAndroid Build Coastguard Worker MemMap tmp_map = zip_entry->ExtractToMemMap(bcp_jar_file.c_str(), entry_name, error_msg);
547*795d594fSAndroid Build Coastguard Worker if (!tmp_map.IsValid()) {
548*795d594fSAndroid Build Coastguard Worker return MemMap::Invalid();
549*795d594fSAndroid Build Coastguard Worker }
550*795d594fSAndroid Build Coastguard Worker
551*795d594fSAndroid Build Coastguard Worker // OK, from here everything seems fine.
552*795d594fSAndroid Build Coastguard Worker *size = zip_entry->GetUncompressedLength();
553*795d594fSAndroid Build Coastguard Worker return tmp_map;
554*795d594fSAndroid Build Coastguard Worker }
555*795d594fSAndroid Build Coastguard Worker
GetResourceAsStream(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)556*795d594fSAndroid Build Coastguard Worker static void GetResourceAsStream(Thread* self,
557*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
558*795d594fSAndroid Build Coastguard Worker JValue* result,
559*795d594fSAndroid Build Coastguard Worker size_t arg_offset) REQUIRES_SHARED(Locks::mutator_lock_) {
560*795d594fSAndroid Build Coastguard Worker mirror::Object* resource_obj = shadow_frame->GetVRegReference(arg_offset + 1);
561*795d594fSAndroid Build Coastguard Worker if (resource_obj == nullptr) {
562*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "null name for getResourceAsStream");
563*795d594fSAndroid Build Coastguard Worker return;
564*795d594fSAndroid Build Coastguard Worker }
565*795d594fSAndroid Build Coastguard Worker CHECK(resource_obj->IsString());
566*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> resource_name = resource_obj->AsString();
567*795d594fSAndroid Build Coastguard Worker
568*795d594fSAndroid Build Coastguard Worker std::string resource_name_str = resource_name->ToModifiedUtf8();
569*795d594fSAndroid Build Coastguard Worker if (resource_name_str.empty() || resource_name_str == "/") {
570*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
571*795d594fSAndroid Build Coastguard Worker "Unsupported name %s for getResourceAsStream",
572*795d594fSAndroid Build Coastguard Worker resource_name_str.c_str());
573*795d594fSAndroid Build Coastguard Worker return;
574*795d594fSAndroid Build Coastguard Worker }
575*795d594fSAndroid Build Coastguard Worker const char* resource_cstr = resource_name_str.c_str();
576*795d594fSAndroid Build Coastguard Worker if (resource_cstr[0] == '/') {
577*795d594fSAndroid Build Coastguard Worker resource_cstr++;
578*795d594fSAndroid Build Coastguard Worker }
579*795d594fSAndroid Build Coastguard Worker
580*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
581*795d594fSAndroid Build Coastguard Worker
582*795d594fSAndroid Build Coastguard Worker const std::vector<std::string>& boot_class_path = Runtime::Current()->GetBootClassPath();
583*795d594fSAndroid Build Coastguard Worker if (boot_class_path.empty()) {
584*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Boot classpath not set");
585*795d594fSAndroid Build Coastguard Worker return;
586*795d594fSAndroid Build Coastguard Worker }
587*795d594fSAndroid Build Coastguard Worker
588*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_files = Runtime::Current()->GetBootClassPathFiles();
589*795d594fSAndroid Build Coastguard Worker DCHECK(boot_class_path_files.empty() || boot_class_path_files.size() == boot_class_path.size());
590*795d594fSAndroid Build Coastguard Worker
591*795d594fSAndroid Build Coastguard Worker MemMap mem_map;
592*795d594fSAndroid Build Coastguard Worker size_t map_size;
593*795d594fSAndroid Build Coastguard Worker std::string last_error_msg; // Only store the last message (we could concatenate).
594*795d594fSAndroid Build Coastguard Worker
595*795d594fSAndroid Build Coastguard Worker bool has_bcp_fds = !boot_class_path_files.empty();
596*795d594fSAndroid Build Coastguard Worker for (size_t i = 0; i < boot_class_path.size(); ++i) {
597*795d594fSAndroid Build Coastguard Worker const std::string& jar_file = boot_class_path[i];
598*795d594fSAndroid Build Coastguard Worker const int jar_fd = has_bcp_fds ? boot_class_path_files[i].Fd() : -1;
599*795d594fSAndroid Build Coastguard Worker mem_map = FindAndExtractEntry(jar_file, jar_fd, resource_cstr, &map_size, &last_error_msg);
600*795d594fSAndroid Build Coastguard Worker if (mem_map.IsValid()) {
601*795d594fSAndroid Build Coastguard Worker break;
602*795d594fSAndroid Build Coastguard Worker }
603*795d594fSAndroid Build Coastguard Worker }
604*795d594fSAndroid Build Coastguard Worker
605*795d594fSAndroid Build Coastguard Worker if (!mem_map.IsValid()) {
606*795d594fSAndroid Build Coastguard Worker // Didn't find it. There's a good chance this will be the same at runtime, but still
607*795d594fSAndroid Build Coastguard Worker // conservatively abort the transaction here.
608*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
609*795d594fSAndroid Build Coastguard Worker "Could not find resource %s. Last error was %s.",
610*795d594fSAndroid Build Coastguard Worker resource_name_str.c_str(),
611*795d594fSAndroid Build Coastguard Worker last_error_msg.c_str());
612*795d594fSAndroid Build Coastguard Worker return;
613*795d594fSAndroid Build Coastguard Worker }
614*795d594fSAndroid Build Coastguard Worker
615*795d594fSAndroid Build Coastguard Worker StackHandleScope<3> hs(self);
616*795d594fSAndroid Build Coastguard Worker
617*795d594fSAndroid Build Coastguard Worker // Create byte array for content.
618*795d594fSAndroid Build Coastguard Worker Handle<mirror::ByteArray> h_array(hs.NewHandle(mirror::ByteArray::Alloc(self, map_size)));
619*795d594fSAndroid Build Coastguard Worker if (h_array == nullptr) {
620*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not find/create byte array class");
621*795d594fSAndroid Build Coastguard Worker return;
622*795d594fSAndroid Build Coastguard Worker }
623*795d594fSAndroid Build Coastguard Worker // Copy in content.
624*795d594fSAndroid Build Coastguard Worker memcpy(h_array->GetData(), mem_map.Begin(), map_size);
625*795d594fSAndroid Build Coastguard Worker // Be proactive releasing memory.
626*795d594fSAndroid Build Coastguard Worker mem_map.Reset();
627*795d594fSAndroid Build Coastguard Worker
628*795d594fSAndroid Build Coastguard Worker // Create a ByteArrayInputStream.
629*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> h_class(hs.NewHandle(
630*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->FindSystemClass(self, "Ljava/io/ByteArrayInputStream;")));
631*795d594fSAndroid Build Coastguard Worker if (h_class == nullptr) {
632*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not find ByteArrayInputStream class");
633*795d594fSAndroid Build Coastguard Worker return;
634*795d594fSAndroid Build Coastguard Worker }
635*795d594fSAndroid Build Coastguard Worker if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
636*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not initialize ByteArrayInputStream class");
637*795d594fSAndroid Build Coastguard Worker return;
638*795d594fSAndroid Build Coastguard Worker }
639*795d594fSAndroid Build Coastguard Worker
640*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
641*795d594fSAndroid Build Coastguard Worker if (h_obj == nullptr) {
642*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not allocate ByteArrayInputStream object");
643*795d594fSAndroid Build Coastguard Worker return;
644*795d594fSAndroid Build Coastguard Worker }
645*795d594fSAndroid Build Coastguard Worker
646*795d594fSAndroid Build Coastguard Worker auto* cl = Runtime::Current()->GetClassLinker();
647*795d594fSAndroid Build Coastguard Worker ArtMethod* constructor = h_class->FindConstructor("([B)V", cl->GetImagePointerSize());
648*795d594fSAndroid Build Coastguard Worker if (constructor == nullptr) {
649*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not find ByteArrayInputStream constructor");
650*795d594fSAndroid Build Coastguard Worker return;
651*795d594fSAndroid Build Coastguard Worker }
652*795d594fSAndroid Build Coastguard Worker
653*795d594fSAndroid Build Coastguard Worker uint32_t args[1];
654*795d594fSAndroid Build Coastguard Worker args[0] = reinterpret_cast32<uint32_t>(h_array.Get());
655*795d594fSAndroid Build Coastguard Worker EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
656*795d594fSAndroid Build Coastguard Worker
657*795d594fSAndroid Build Coastguard Worker if (self->IsExceptionPending()) {
658*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not run ByteArrayInputStream constructor");
659*795d594fSAndroid Build Coastguard Worker return;
660*795d594fSAndroid Build Coastguard Worker }
661*795d594fSAndroid Build Coastguard Worker
662*795d594fSAndroid Build Coastguard Worker result->SetL(h_obj.Get());
663*795d594fSAndroid Build Coastguard Worker }
664*795d594fSAndroid Build Coastguard Worker
UnstartedClassLoaderGetResourceAsStream(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)665*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream(
666*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
667*795d594fSAndroid Build Coastguard Worker {
668*795d594fSAndroid Build Coastguard Worker mirror::Object* this_obj = shadow_frame->GetVRegReference(arg_offset);
669*795d594fSAndroid Build Coastguard Worker CHECK(this_obj != nullptr);
670*795d594fSAndroid Build Coastguard Worker CHECK(this_obj->IsClassLoader());
671*795d594fSAndroid Build Coastguard Worker
672*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
673*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> this_classloader_class(hs.NewHandle(this_obj->GetClass()));
674*795d594fSAndroid Build Coastguard Worker
675*795d594fSAndroid Build Coastguard Worker if (WellKnownClasses::java_lang_BootClassLoader != this_classloader_class.Get()) {
676*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
677*795d594fSAndroid Build Coastguard Worker "Unsupported classloader type %s for getResourceAsStream",
678*795d594fSAndroid Build Coastguard Worker mirror::Class::PrettyClass(this_classloader_class.Get()).c_str());
679*795d594fSAndroid Build Coastguard Worker return;
680*795d594fSAndroid Build Coastguard Worker }
681*795d594fSAndroid Build Coastguard Worker }
682*795d594fSAndroid Build Coastguard Worker
683*795d594fSAndroid Build Coastguard Worker GetResourceAsStream(self, shadow_frame, result, arg_offset);
684*795d594fSAndroid Build Coastguard Worker }
685*795d594fSAndroid Build Coastguard Worker
UnstartedConstructorNewInstance0(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)686*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedConstructorNewInstance0(
687*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
688*795d594fSAndroid Build Coastguard Worker // This is a cutdown version of java_lang_reflect_Constructor.cc's implementation.
689*795d594fSAndroid Build Coastguard Worker StackHandleScope<4> hs(self);
690*795d594fSAndroid Build Coastguard Worker Handle<mirror::Constructor> m = hs.NewHandle(
691*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::Constructor*>(shadow_frame->GetVRegReference(arg_offset)));
692*795d594fSAndroid Build Coastguard Worker Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
693*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(
694*795d594fSAndroid Build Coastguard Worker shadow_frame->GetVRegReference(arg_offset + 1)));
695*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
696*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(c->IsAbstract())) {
697*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot handle abstract classes");
698*795d594fSAndroid Build Coastguard Worker return;
699*795d594fSAndroid Build Coastguard Worker }
700*795d594fSAndroid Build Coastguard Worker // Verify that we can access the class.
701*795d594fSAndroid Build Coastguard Worker if (!m->IsAccessible() && !c->IsPublic()) {
702*795d594fSAndroid Build Coastguard Worker // Go 2 frames back, this method is always called from newInstance0, which is called from
703*795d594fSAndroid Build Coastguard Worker // Constructor.newInstance(Object... args).
704*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> caller = GetCallingClass(self, 2);
705*795d594fSAndroid Build Coastguard Worker // If caller is null, then we called from JNI, just avoid the check since JNI avoids most
706*795d594fSAndroid Build Coastguard Worker // access checks anyways. TODO: Investigate if this the correct behavior.
707*795d594fSAndroid Build Coastguard Worker if (caller != nullptr && !caller->CanAccess(c.Get())) {
708*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot access class");
709*795d594fSAndroid Build Coastguard Worker return;
710*795d594fSAndroid Build Coastguard Worker }
711*795d594fSAndroid Build Coastguard Worker }
712*795d594fSAndroid Build Coastguard Worker if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, c, true, true)) {
713*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
714*795d594fSAndroid Build Coastguard Worker return;
715*795d594fSAndroid Build Coastguard Worker }
716*795d594fSAndroid Build Coastguard Worker if (c->IsClassClass()) {
717*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "new Class() is not supported");
718*795d594fSAndroid Build Coastguard Worker return;
719*795d594fSAndroid Build Coastguard Worker }
720*795d594fSAndroid Build Coastguard Worker
721*795d594fSAndroid Build Coastguard Worker // String constructor is replaced by a StringFactory method in InvokeMethod.
722*795d594fSAndroid Build Coastguard Worker if (c->IsStringClass()) {
723*795d594fSAndroid Build Coastguard Worker // We don't support strings.
724*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "String construction is not supported");
725*795d594fSAndroid Build Coastguard Worker return;
726*795d594fSAndroid Build Coastguard Worker }
727*795d594fSAndroid Build Coastguard Worker
728*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> receiver = hs.NewHandle(c->AllocObject(self));
729*795d594fSAndroid Build Coastguard Worker if (receiver == nullptr) {
730*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not allocate");
731*795d594fSAndroid Build Coastguard Worker return;
732*795d594fSAndroid Build Coastguard Worker }
733*795d594fSAndroid Build Coastguard Worker
734*795d594fSAndroid Build Coastguard Worker // It's easier to use reflection to make the call, than create the uint32_t array.
735*795d594fSAndroid Build Coastguard Worker {
736*795d594fSAndroid Build Coastguard Worker ScopedObjectAccessUnchecked soa(self);
737*795d594fSAndroid Build Coastguard Worker ScopedLocalRef<jobject> method_ref(self->GetJniEnv(),
738*795d594fSAndroid Build Coastguard Worker soa.AddLocalReference<jobject>(m.Get()));
739*795d594fSAndroid Build Coastguard Worker ScopedLocalRef<jobject> object_ref(self->GetJniEnv(),
740*795d594fSAndroid Build Coastguard Worker soa.AddLocalReference<jobject>(receiver.Get()));
741*795d594fSAndroid Build Coastguard Worker ScopedLocalRef<jobject> args_ref(self->GetJniEnv(),
742*795d594fSAndroid Build Coastguard Worker soa.AddLocalReference<jobject>(args.Get()));
743*795d594fSAndroid Build Coastguard Worker PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
744*795d594fSAndroid Build Coastguard Worker if (pointer_size == PointerSize::k64) {
745*795d594fSAndroid Build Coastguard Worker InvokeMethod<PointerSize::k64>(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
746*795d594fSAndroid Build Coastguard Worker } else {
747*795d594fSAndroid Build Coastguard Worker InvokeMethod<PointerSize::k32>(soa, method_ref.get(), object_ref.get(), args_ref.get(), 2);
748*795d594fSAndroid Build Coastguard Worker }
749*795d594fSAndroid Build Coastguard Worker }
750*795d594fSAndroid Build Coastguard Worker if (self->IsExceptionPending()) {
751*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Failed running constructor");
752*795d594fSAndroid Build Coastguard Worker } else {
753*795d594fSAndroid Build Coastguard Worker result->SetL(receiver.Get());
754*795d594fSAndroid Build Coastguard Worker }
755*795d594fSAndroid Build Coastguard Worker }
756*795d594fSAndroid Build Coastguard Worker
UnstartedJNIExecutableGetParameterTypesInternal(Thread * self,ArtMethod *,mirror::Object * receiver,uint32_t *,JValue * result)757*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIExecutableGetParameterTypesInternal(
758*795d594fSAndroid Build Coastguard Worker Thread* self, ArtMethod*, mirror::Object* receiver, uint32_t*, JValue* result) {
759*795d594fSAndroid Build Coastguard Worker StackHandleScope<3> hs(self);
760*795d594fSAndroid Build Coastguard Worker ScopedObjectAccessUnchecked soa(self);
761*795d594fSAndroid Build Coastguard Worker Handle<mirror::Executable> executable(hs.NewHandle(
762*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::Executable*>(receiver)));
763*795d594fSAndroid Build Coastguard Worker if (executable == nullptr) {
764*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Receiver can't be null in GetParameterTypesInternal");
765*795d594fSAndroid Build Coastguard Worker }
766*795d594fSAndroid Build Coastguard Worker
767*795d594fSAndroid Build Coastguard Worker ArtMethod* method = executable->GetArtMethod();
768*795d594fSAndroid Build Coastguard Worker const dex::TypeList* params = method->GetParameterTypeList();
769*795d594fSAndroid Build Coastguard Worker if (params == nullptr) {
770*795d594fSAndroid Build Coastguard Worker result->SetL(nullptr);
771*795d594fSAndroid Build Coastguard Worker return;
772*795d594fSAndroid Build Coastguard Worker }
773*795d594fSAndroid Build Coastguard Worker
774*795d594fSAndroid Build Coastguard Worker const uint32_t num_params = params->Size();
775*795d594fSAndroid Build Coastguard Worker
776*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> class_array_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>();
777*795d594fSAndroid Build Coastguard Worker Handle<mirror::ObjectArray<mirror::Class>> ptypes = hs.NewHandle(
778*795d594fSAndroid Build Coastguard Worker mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, num_params));
779*795d594fSAndroid Build Coastguard Worker if (ptypes.IsNull()) {
780*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not allocate array of mirror::Class");
781*795d594fSAndroid Build Coastguard Worker return;
782*795d594fSAndroid Build Coastguard Worker }
783*795d594fSAndroid Build Coastguard Worker
784*795d594fSAndroid Build Coastguard Worker MutableHandle<mirror::Class> param(hs.NewHandle<mirror::Class>(nullptr));
785*795d594fSAndroid Build Coastguard Worker for (uint32_t i = 0; i < num_params; ++i) {
786*795d594fSAndroid Build Coastguard Worker const dex::TypeIndex type_idx = params->GetTypeItem(i).type_idx_;
787*795d594fSAndroid Build Coastguard Worker param.Assign(Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method));
788*795d594fSAndroid Build Coastguard Worker if (param.Get() == nullptr) {
789*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not resolve type");
790*795d594fSAndroid Build Coastguard Worker return;
791*795d594fSAndroid Build Coastguard Worker }
792*795d594fSAndroid Build Coastguard Worker ptypes->SetWithoutChecks<false>(i, param.Get());
793*795d594fSAndroid Build Coastguard Worker }
794*795d594fSAndroid Build Coastguard Worker
795*795d594fSAndroid Build Coastguard Worker result->SetL(ptypes.Get());
796*795d594fSAndroid Build Coastguard Worker }
797*795d594fSAndroid Build Coastguard Worker
UnstartedVmClassLoaderFindLoadedClass(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)798*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass(
799*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
800*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> class_name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
801*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ClassLoader> class_loader =
802*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ClassLoader>::DownCast(shadow_frame->GetVRegReference(arg_offset));
803*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
804*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> h_class_name(hs.NewHandle(class_name));
805*795d594fSAndroid Build Coastguard Worker Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(class_loader));
806*795d594fSAndroid Build Coastguard Worker UnstartedRuntimeFindClass(self,
807*795d594fSAndroid Build Coastguard Worker h_class_name,
808*795d594fSAndroid Build Coastguard Worker h_class_loader,
809*795d594fSAndroid Build Coastguard Worker result,
810*795d594fSAndroid Build Coastguard Worker /*initialize_class=*/ false);
811*795d594fSAndroid Build Coastguard Worker // This might have an error pending. But semantics are to just return null.
812*795d594fSAndroid Build Coastguard Worker if (self->IsExceptionPending()) {
813*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
814*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction()) {
815*795d594fSAndroid Build Coastguard Worker // If we're not aborting the transaction yet, abort now. b/183691501
816*795d594fSAndroid Build Coastguard Worker // See CheckExceptionGenerateClassNotFound() for more detailed explanation.
817*795d594fSAndroid Build Coastguard Worker if (!runtime->GetClassLinker()->IsTransactionAborted()) {
818*795d594fSAndroid Build Coastguard Worker DCHECK(!PendingExceptionHasAbortDescriptor(self));
819*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->AbortTransactionF(self, "ClassNotFoundException");
820*795d594fSAndroid Build Coastguard Worker } else {
821*795d594fSAndroid Build Coastguard Worker DCHECK(PendingExceptionHasAbortDescriptor(self))
822*795d594fSAndroid Build Coastguard Worker << self->GetException()->GetClass()->PrettyDescriptor();
823*795d594fSAndroid Build Coastguard Worker }
824*795d594fSAndroid Build Coastguard Worker } else {
825*795d594fSAndroid Build Coastguard Worker // If not in a transaction, it cannot be the transaction abort exception. Clear it.
826*795d594fSAndroid Build Coastguard Worker DCHECK(!PendingExceptionHasAbortDescriptor(self));
827*795d594fSAndroid Build Coastguard Worker self->ClearException();
828*795d594fSAndroid Build Coastguard Worker }
829*795d594fSAndroid Build Coastguard Worker }
830*795d594fSAndroid Build Coastguard Worker }
831*795d594fSAndroid Build Coastguard Worker
832*795d594fSAndroid Build Coastguard Worker // Arraycopy emulation.
833*795d594fSAndroid Build Coastguard Worker // Note: we can't use any fast copy functions, as they are not available under transaction.
834*795d594fSAndroid Build Coastguard Worker
835*795d594fSAndroid Build Coastguard Worker template <typename T>
PrimitiveArrayCopy(Thread * self,ObjPtr<mirror::Array> src_array,int32_t src_pos,ObjPtr<mirror::Array> dst_array,int32_t dst_pos,int32_t length)836*795d594fSAndroid Build Coastguard Worker static void PrimitiveArrayCopy(Thread* self,
837*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Array> src_array,
838*795d594fSAndroid Build Coastguard Worker int32_t src_pos,
839*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Array> dst_array,
840*795d594fSAndroid Build Coastguard Worker int32_t dst_pos,
841*795d594fSAndroid Build Coastguard Worker int32_t length)
842*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
843*795d594fSAndroid Build Coastguard Worker if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) {
844*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
845*795d594fSAndroid Build Coastguard Worker "Types mismatched in arraycopy: %s vs %s.",
846*795d594fSAndroid Build Coastguard Worker mirror::Class::PrettyDescriptor(
847*795d594fSAndroid Build Coastguard Worker src_array->GetClass()->GetComponentType()).c_str(),
848*795d594fSAndroid Build Coastguard Worker mirror::Class::PrettyDescriptor(
849*795d594fSAndroid Build Coastguard Worker dst_array->GetClass()->GetComponentType()).c_str());
850*795d594fSAndroid Build Coastguard Worker return;
851*795d594fSAndroid Build Coastguard Worker }
852*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::PrimitiveArray<T>> src = ObjPtr<mirror::PrimitiveArray<T>>::DownCast(src_array);
853*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::PrimitiveArray<T>> dst = ObjPtr<mirror::PrimitiveArray<T>>::DownCast(dst_array);
854*795d594fSAndroid Build Coastguard Worker const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
855*795d594fSAndroid Build Coastguard Worker if (copy_forward) {
856*795d594fSAndroid Build Coastguard Worker for (int32_t i = 0; i < length; ++i) {
857*795d594fSAndroid Build Coastguard Worker dst->Set(dst_pos + i, src->Get(src_pos + i));
858*795d594fSAndroid Build Coastguard Worker }
859*795d594fSAndroid Build Coastguard Worker } else {
860*795d594fSAndroid Build Coastguard Worker for (int32_t i = 1; i <= length; ++i) {
861*795d594fSAndroid Build Coastguard Worker dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
862*795d594fSAndroid Build Coastguard Worker }
863*795d594fSAndroid Build Coastguard Worker }
864*795d594fSAndroid Build Coastguard Worker }
865*795d594fSAndroid Build Coastguard Worker
UnstartedSystemArraycopy(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)866*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedSystemArraycopy(Thread* self,
867*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
868*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] JValue* result,
869*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
870*795d594fSAndroid Build Coastguard Worker // Special case array copying without initializing System.
871*795d594fSAndroid Build Coastguard Worker jint src_pos = shadow_frame->GetVReg(arg_offset + 1);
872*795d594fSAndroid Build Coastguard Worker jint dst_pos = shadow_frame->GetVReg(arg_offset + 3);
873*795d594fSAndroid Build Coastguard Worker jint length = shadow_frame->GetVReg(arg_offset + 4);
874*795d594fSAndroid Build Coastguard Worker
875*795d594fSAndroid Build Coastguard Worker mirror::Object* src_obj = shadow_frame->GetVRegReference(arg_offset);
876*795d594fSAndroid Build Coastguard Worker mirror::Object* dst_obj = shadow_frame->GetVRegReference(arg_offset + 2);
877*795d594fSAndroid Build Coastguard Worker // Null checking. For simplicity, abort transaction.
878*795d594fSAndroid Build Coastguard Worker if (src_obj == nullptr) {
879*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "src is null in arraycopy.");
880*795d594fSAndroid Build Coastguard Worker return;
881*795d594fSAndroid Build Coastguard Worker }
882*795d594fSAndroid Build Coastguard Worker if (dst_obj == nullptr) {
883*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "dst is null in arraycopy.");
884*795d594fSAndroid Build Coastguard Worker return;
885*795d594fSAndroid Build Coastguard Worker }
886*795d594fSAndroid Build Coastguard Worker // Test for arrayness. Throw ArrayStoreException.
887*795d594fSAndroid Build Coastguard Worker if (!src_obj->IsArrayInstance() || !dst_obj->IsArrayInstance()) {
888*795d594fSAndroid Build Coastguard Worker self->ThrowNewException("Ljava/lang/ArrayStoreException;", "src or trg is not an array");
889*795d594fSAndroid Build Coastguard Worker return;
890*795d594fSAndroid Build Coastguard Worker }
891*795d594fSAndroid Build Coastguard Worker
892*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Array> src_array = src_obj->AsArray();
893*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Array> dst_array = dst_obj->AsArray();
894*795d594fSAndroid Build Coastguard Worker
895*795d594fSAndroid Build Coastguard Worker // Bounds checking. Throw IndexOutOfBoundsException.
896*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(src_pos < 0) || UNLIKELY(dst_pos < 0) || UNLIKELY(length < 0) ||
897*795d594fSAndroid Build Coastguard Worker UNLIKELY(src_pos > src_array->GetLength() - length) ||
898*795d594fSAndroid Build Coastguard Worker UNLIKELY(dst_pos > dst_array->GetLength() - length)) {
899*795d594fSAndroid Build Coastguard Worker self->ThrowNewExceptionF("Ljava/lang/IndexOutOfBoundsException;",
900*795d594fSAndroid Build Coastguard Worker "src.length=%d srcPos=%d dst.length=%d dstPos=%d length=%d",
901*795d594fSAndroid Build Coastguard Worker src_array->GetLength(), src_pos, dst_array->GetLength(), dst_pos,
902*795d594fSAndroid Build Coastguard Worker length);
903*795d594fSAndroid Build Coastguard Worker return;
904*795d594fSAndroid Build Coastguard Worker }
905*795d594fSAndroid Build Coastguard Worker
906*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
907*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction() &&
908*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->TransactionWriteConstraint(self, dst_obj)) {
909*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
910*795d594fSAndroid Build Coastguard Worker return;
911*795d594fSAndroid Build Coastguard Worker }
912*795d594fSAndroid Build Coastguard Worker
913*795d594fSAndroid Build Coastguard Worker // Type checking.
914*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()->
915*795d594fSAndroid Build Coastguard Worker GetComponentType();
916*795d594fSAndroid Build Coastguard Worker
917*795d594fSAndroid Build Coastguard Worker if (!src_type->IsPrimitive()) {
918*795d594fSAndroid Build Coastguard Worker // Check that the second type is not primitive.
919*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()->
920*795d594fSAndroid Build Coastguard Worker GetComponentType();
921*795d594fSAndroid Build Coastguard Worker if (trg_type->IsPrimitiveInt()) {
922*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s",
923*795d594fSAndroid Build Coastguard Worker mirror::Class::PrettyDescriptor(
924*795d594fSAndroid Build Coastguard Worker src_array->GetClass()->GetComponentType()).c_str(),
925*795d594fSAndroid Build Coastguard Worker mirror::Class::PrettyDescriptor(
926*795d594fSAndroid Build Coastguard Worker dst_array->GetClass()->GetComponentType()).c_str());
927*795d594fSAndroid Build Coastguard Worker return;
928*795d594fSAndroid Build Coastguard Worker }
929*795d594fSAndroid Build Coastguard Worker
930*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> src = src_array->AsObjectArray<mirror::Object>();
931*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> dst = dst_array->AsObjectArray<mirror::Object>();
932*795d594fSAndroid Build Coastguard Worker if (src == dst) {
933*795d594fSAndroid Build Coastguard Worker // Can overlap, but not have type mismatches.
934*795d594fSAndroid Build Coastguard Worker // We cannot use ObjectArray::MemMove here, as it doesn't support transactions.
935*795d594fSAndroid Build Coastguard Worker const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= length);
936*795d594fSAndroid Build Coastguard Worker if (copy_forward) {
937*795d594fSAndroid Build Coastguard Worker for (int32_t i = 0; i < length; ++i) {
938*795d594fSAndroid Build Coastguard Worker dst->Set(dst_pos + i, src->Get(src_pos + i));
939*795d594fSAndroid Build Coastguard Worker }
940*795d594fSAndroid Build Coastguard Worker } else {
941*795d594fSAndroid Build Coastguard Worker for (int32_t i = 1; i <= length; ++i) {
942*795d594fSAndroid Build Coastguard Worker dst->Set(dst_pos + length - i, src->Get(src_pos + length - i));
943*795d594fSAndroid Build Coastguard Worker }
944*795d594fSAndroid Build Coastguard Worker }
945*795d594fSAndroid Build Coastguard Worker } else {
946*795d594fSAndroid Build Coastguard Worker // We're being lazy here. Optimally this could be a memcpy (if component types are
947*795d594fSAndroid Build Coastguard Worker // assignable), but the ObjectArray implementation doesn't support transactions. The
948*795d594fSAndroid Build Coastguard Worker // checking version, however, does.
949*795d594fSAndroid Build Coastguard Worker if (Runtime::Current()->IsActiveTransaction()) {
950*795d594fSAndroid Build Coastguard Worker dst->AssignableCheckingMemcpy<true>(
951*795d594fSAndroid Build Coastguard Worker dst_pos, src, src_pos, length, /* throw_exception= */ true);
952*795d594fSAndroid Build Coastguard Worker } else {
953*795d594fSAndroid Build Coastguard Worker dst->AssignableCheckingMemcpy<false>(
954*795d594fSAndroid Build Coastguard Worker dst_pos, src, src_pos, length, /* throw_exception= */ true);
955*795d594fSAndroid Build Coastguard Worker }
956*795d594fSAndroid Build Coastguard Worker }
957*795d594fSAndroid Build Coastguard Worker } else if (src_type->IsPrimitiveByte()) {
958*795d594fSAndroid Build Coastguard Worker PrimitiveArrayCopy<uint8_t>(self, src_array, src_pos, dst_array, dst_pos, length);
959*795d594fSAndroid Build Coastguard Worker } else if (src_type->IsPrimitiveChar()) {
960*795d594fSAndroid Build Coastguard Worker PrimitiveArrayCopy<uint16_t>(self, src_array, src_pos, dst_array, dst_pos, length);
961*795d594fSAndroid Build Coastguard Worker } else if (src_type->IsPrimitiveInt()) {
962*795d594fSAndroid Build Coastguard Worker PrimitiveArrayCopy<int32_t>(self, src_array, src_pos, dst_array, dst_pos, length);
963*795d594fSAndroid Build Coastguard Worker } else {
964*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Unimplemented System.arraycopy for type '%s'",
965*795d594fSAndroid Build Coastguard Worker src_type->PrettyDescriptor().c_str());
966*795d594fSAndroid Build Coastguard Worker }
967*795d594fSAndroid Build Coastguard Worker }
968*795d594fSAndroid Build Coastguard Worker
UnstartedSystemArraycopyByte(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)969*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedSystemArraycopyByte(
970*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
971*795d594fSAndroid Build Coastguard Worker // Just forward.
972*795d594fSAndroid Build Coastguard Worker UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
973*795d594fSAndroid Build Coastguard Worker }
974*795d594fSAndroid Build Coastguard Worker
UnstartedSystemArraycopyChar(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)975*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedSystemArraycopyChar(
976*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
977*795d594fSAndroid Build Coastguard Worker // Just forward.
978*795d594fSAndroid Build Coastguard Worker UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
979*795d594fSAndroid Build Coastguard Worker }
980*795d594fSAndroid Build Coastguard Worker
UnstartedSystemArraycopyInt(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)981*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedSystemArraycopyInt(
982*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
983*795d594fSAndroid Build Coastguard Worker // Just forward.
984*795d594fSAndroid Build Coastguard Worker UnstartedRuntime::UnstartedSystemArraycopy(self, shadow_frame, result, arg_offset);
985*795d594fSAndroid Build Coastguard Worker }
986*795d594fSAndroid Build Coastguard Worker
UnstartedSystemGetSecurityManager(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)987*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedSystemGetSecurityManager([[maybe_unused]] Thread* self,
988*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ShadowFrame* shadow_frame,
989*795d594fSAndroid Build Coastguard Worker JValue* result,
990*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] size_t arg_offset) {
991*795d594fSAndroid Build Coastguard Worker result->SetL(nullptr);
992*795d594fSAndroid Build Coastguard Worker }
993*795d594fSAndroid Build Coastguard Worker
994*795d594fSAndroid Build Coastguard Worker static constexpr const char* kAndroidHardcodedSystemPropertiesFieldName = "STATIC_PROPERTIES";
995*795d594fSAndroid Build Coastguard Worker
GetSystemProperty(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset,bool is_default_version)996*795d594fSAndroid Build Coastguard Worker static void GetSystemProperty(Thread* self,
997*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
998*795d594fSAndroid Build Coastguard Worker JValue* result,
999*795d594fSAndroid Build Coastguard Worker size_t arg_offset,
1000*795d594fSAndroid Build Coastguard Worker bool is_default_version)
1001*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1002*795d594fSAndroid Build Coastguard Worker StackHandleScope<4> hs(self);
1003*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> h_key(
1004*795d594fSAndroid Build Coastguard Worker hs.NewHandle(reinterpret_cast<mirror::String*>(shadow_frame->GetVRegReference(arg_offset))));
1005*795d594fSAndroid Build Coastguard Worker if (h_key == nullptr) {
1006*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "getProperty key was null");
1007*795d594fSAndroid Build Coastguard Worker return;
1008*795d594fSAndroid Build Coastguard Worker }
1009*795d594fSAndroid Build Coastguard Worker
1010*795d594fSAndroid Build Coastguard Worker // This is overall inefficient, but reflecting the values here is not great, either. So
1011*795d594fSAndroid Build Coastguard Worker // for simplicity, and with the assumption that the number of getProperty calls is not
1012*795d594fSAndroid Build Coastguard Worker // too great, just iterate each time.
1013*795d594fSAndroid Build Coastguard Worker
1014*795d594fSAndroid Build Coastguard Worker // Get the storage class.
1015*795d594fSAndroid Build Coastguard Worker ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1016*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> h_props_class(hs.NewHandle(
1017*795d594fSAndroid Build Coastguard Worker class_linker->FindSystemClass(self, "Ljava/lang/AndroidHardcodedSystemProperties;")));
1018*795d594fSAndroid Build Coastguard Worker if (h_props_class == nullptr) {
1019*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not find AndroidHardcodedSystemProperties");
1020*795d594fSAndroid Build Coastguard Worker return;
1021*795d594fSAndroid Build Coastguard Worker }
1022*795d594fSAndroid Build Coastguard Worker if (!class_linker->EnsureInitialized(self, h_props_class, true, true)) {
1023*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not initialize AndroidHardcodedSystemProperties");
1024*795d594fSAndroid Build Coastguard Worker return;
1025*795d594fSAndroid Build Coastguard Worker }
1026*795d594fSAndroid Build Coastguard Worker
1027*795d594fSAndroid Build Coastguard Worker // Get the storage array.
1028*795d594fSAndroid Build Coastguard Worker ArtField* static_properties =
1029*795d594fSAndroid Build Coastguard Worker h_props_class->FindDeclaredStaticField(kAndroidHardcodedSystemPropertiesFieldName,
1030*795d594fSAndroid Build Coastguard Worker "[[Ljava/lang/String;");
1031*795d594fSAndroid Build Coastguard Worker if (static_properties == nullptr) {
1032*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
1033*795d594fSAndroid Build Coastguard Worker "Could not find %s field",
1034*795d594fSAndroid Build Coastguard Worker kAndroidHardcodedSystemPropertiesFieldName);
1035*795d594fSAndroid Build Coastguard Worker return;
1036*795d594fSAndroid Build Coastguard Worker }
1037*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> props = static_properties->GetObject(h_props_class.Get());
1038*795d594fSAndroid Build Coastguard Worker Handle<mirror::ObjectArray<mirror::ObjectArray<mirror::String>>> h_2string_array(hs.NewHandle(
1039*795d594fSAndroid Build Coastguard Worker props->AsObjectArray<mirror::ObjectArray<mirror::String>>()));
1040*795d594fSAndroid Build Coastguard Worker if (h_2string_array == nullptr) {
1041*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Field %s is null", kAndroidHardcodedSystemPropertiesFieldName);
1042*795d594fSAndroid Build Coastguard Worker return;
1043*795d594fSAndroid Build Coastguard Worker }
1044*795d594fSAndroid Build Coastguard Worker
1045*795d594fSAndroid Build Coastguard Worker // Iterate over it.
1046*795d594fSAndroid Build Coastguard Worker const int32_t prop_count = h_2string_array->GetLength();
1047*795d594fSAndroid Build Coastguard Worker // Use the third handle as mutable.
1048*795d594fSAndroid Build Coastguard Worker MutableHandle<mirror::ObjectArray<mirror::String>> h_string_array(
1049*795d594fSAndroid Build Coastguard Worker hs.NewHandle<mirror::ObjectArray<mirror::String>>(nullptr));
1050*795d594fSAndroid Build Coastguard Worker for (int32_t i = 0; i < prop_count; ++i) {
1051*795d594fSAndroid Build Coastguard Worker h_string_array.Assign(h_2string_array->Get(i));
1052*795d594fSAndroid Build Coastguard Worker if (h_string_array == nullptr ||
1053*795d594fSAndroid Build Coastguard Worker h_string_array->GetLength() != 2 ||
1054*795d594fSAndroid Build Coastguard Worker h_string_array->Get(0) == nullptr) {
1055*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
1056*795d594fSAndroid Build Coastguard Worker "Unexpected content of %s",
1057*795d594fSAndroid Build Coastguard Worker kAndroidHardcodedSystemPropertiesFieldName);
1058*795d594fSAndroid Build Coastguard Worker return;
1059*795d594fSAndroid Build Coastguard Worker }
1060*795d594fSAndroid Build Coastguard Worker if (h_key->Equals(h_string_array->Get(0))) {
1061*795d594fSAndroid Build Coastguard Worker // Found a value.
1062*795d594fSAndroid Build Coastguard Worker if (h_string_array->Get(1) == nullptr && is_default_version) {
1063*795d594fSAndroid Build Coastguard Worker // Null is being delegated to the default map, and then resolved to the given default value.
1064*795d594fSAndroid Build Coastguard Worker // As there's no default map, return the given value.
1065*795d594fSAndroid Build Coastguard Worker result->SetL(shadow_frame->GetVRegReference(arg_offset + 1));
1066*795d594fSAndroid Build Coastguard Worker } else {
1067*795d594fSAndroid Build Coastguard Worker result->SetL(h_string_array->Get(1));
1068*795d594fSAndroid Build Coastguard Worker }
1069*795d594fSAndroid Build Coastguard Worker return;
1070*795d594fSAndroid Build Coastguard Worker }
1071*795d594fSAndroid Build Coastguard Worker }
1072*795d594fSAndroid Build Coastguard Worker
1073*795d594fSAndroid Build Coastguard Worker // Key is not supported.
1074*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "getProperty key %s not supported", h_key->ToModifiedUtf8().c_str());
1075*795d594fSAndroid Build Coastguard Worker }
1076*795d594fSAndroid Build Coastguard Worker
UnstartedSystemGetProperty(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1077*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedSystemGetProperty(
1078*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1079*795d594fSAndroid Build Coastguard Worker GetSystemProperty(self, shadow_frame, result, arg_offset, false);
1080*795d594fSAndroid Build Coastguard Worker }
1081*795d594fSAndroid Build Coastguard Worker
UnstartedSystemGetPropertyWithDefault(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1082*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedSystemGetPropertyWithDefault(
1083*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1084*795d594fSAndroid Build Coastguard Worker GetSystemProperty(self, shadow_frame, result, arg_offset, true);
1085*795d594fSAndroid Build Coastguard Worker }
1086*795d594fSAndroid Build Coastguard Worker
UnstartedSystemNanoTime(Thread * self,ShadowFrame *,JValue *,size_t)1087*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedSystemNanoTime(Thread* self, ShadowFrame*, JValue*, size_t) {
1088*795d594fSAndroid Build Coastguard Worker // We don't want `System.nanoTime` to be called at compile time because `java.util.Random`'s
1089*795d594fSAndroid Build Coastguard Worker // default constructor uses `nanoTime` to initialize seed and having it set during compile time
1090*795d594fSAndroid Build Coastguard Worker // makes that `java.util.Random` instance deterministic for given system image.
1091*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Should not be called by UnstartedRuntime");
1092*795d594fSAndroid Build Coastguard Worker }
1093*795d594fSAndroid Build Coastguard Worker
GetImmediateCaller(ShadowFrame * shadow_frame)1094*795d594fSAndroid Build Coastguard Worker static std::string GetImmediateCaller(ShadowFrame* shadow_frame)
1095*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1096*795d594fSAndroid Build Coastguard Worker if (shadow_frame->GetLink() == nullptr) {
1097*795d594fSAndroid Build Coastguard Worker return "<no caller>";
1098*795d594fSAndroid Build Coastguard Worker }
1099*795d594fSAndroid Build Coastguard Worker return ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1100*795d594fSAndroid Build Coastguard Worker }
1101*795d594fSAndroid Build Coastguard Worker
CheckCallers(ShadowFrame * shadow_frame,std::initializer_list<std::string> allowed_call_stack)1102*795d594fSAndroid Build Coastguard Worker static bool CheckCallers(ShadowFrame* shadow_frame,
1103*795d594fSAndroid Build Coastguard Worker std::initializer_list<std::string> allowed_call_stack)
1104*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1105*795d594fSAndroid Build Coastguard Worker for (const std::string& allowed_caller : allowed_call_stack) {
1106*795d594fSAndroid Build Coastguard Worker if (shadow_frame->GetLink() == nullptr) {
1107*795d594fSAndroid Build Coastguard Worker return false;
1108*795d594fSAndroid Build Coastguard Worker }
1109*795d594fSAndroid Build Coastguard Worker
1110*795d594fSAndroid Build Coastguard Worker std::string found_caller = ArtMethod::PrettyMethod(shadow_frame->GetLink()->GetMethod());
1111*795d594fSAndroid Build Coastguard Worker if (allowed_caller != found_caller) {
1112*795d594fSAndroid Build Coastguard Worker return false;
1113*795d594fSAndroid Build Coastguard Worker }
1114*795d594fSAndroid Build Coastguard Worker
1115*795d594fSAndroid Build Coastguard Worker shadow_frame = shadow_frame->GetLink();
1116*795d594fSAndroid Build Coastguard Worker }
1117*795d594fSAndroid Build Coastguard Worker return true;
1118*795d594fSAndroid Build Coastguard Worker }
1119*795d594fSAndroid Build Coastguard Worker
CreateInstanceOf(Thread * self,const char * class_descriptor)1120*795d594fSAndroid Build Coastguard Worker static ObjPtr<mirror::Object> CreateInstanceOf(Thread* self, const char* class_descriptor)
1121*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1122*795d594fSAndroid Build Coastguard Worker // Find the requested class.
1123*795d594fSAndroid Build Coastguard Worker ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1124*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> klass = class_linker->FindSystemClass(self, class_descriptor);
1125*795d594fSAndroid Build Coastguard Worker if (klass == nullptr) {
1126*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not load class %s", class_descriptor);
1127*795d594fSAndroid Build Coastguard Worker return nullptr;
1128*795d594fSAndroid Build Coastguard Worker }
1129*795d594fSAndroid Build Coastguard Worker
1130*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
1131*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> h_class(hs.NewHandle(klass));
1132*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
1133*795d594fSAndroid Build Coastguard Worker if (h_obj != nullptr) {
1134*795d594fSAndroid Build Coastguard Worker ArtMethod* init_method = h_class->FindConstructor("()V", class_linker->GetImagePointerSize());
1135*795d594fSAndroid Build Coastguard Worker if (init_method == nullptr) {
1136*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not find <init> for %s", class_descriptor);
1137*795d594fSAndroid Build Coastguard Worker return nullptr;
1138*795d594fSAndroid Build Coastguard Worker } else {
1139*795d594fSAndroid Build Coastguard Worker JValue invoke_result;
1140*795d594fSAndroid Build Coastguard Worker EnterInterpreterFromInvoke(self, init_method, h_obj.Get(), nullptr, nullptr);
1141*795d594fSAndroid Build Coastguard Worker if (!self->IsExceptionPending()) {
1142*795d594fSAndroid Build Coastguard Worker return h_obj.Get();
1143*795d594fSAndroid Build Coastguard Worker }
1144*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not run <init> for %s", class_descriptor);
1145*795d594fSAndroid Build Coastguard Worker }
1146*795d594fSAndroid Build Coastguard Worker }
1147*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Could not allocate instance of %s", class_descriptor);
1148*795d594fSAndroid Build Coastguard Worker return nullptr;
1149*795d594fSAndroid Build Coastguard Worker }
1150*795d594fSAndroid Build Coastguard Worker
UnstartedThreadLocalGet(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1151*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedThreadLocalGet(Thread* self,
1152*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1153*795d594fSAndroid Build Coastguard Worker JValue* result,
1154*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] size_t arg_offset) {
1155*795d594fSAndroid Build Coastguard Worker if (CheckCallers(shadow_frame,
1156*795d594fSAndroid Build Coastguard Worker { "jdk.internal.math.FloatingDecimal$BinaryToASCIIBuffer "
1157*795d594fSAndroid Build Coastguard Worker "jdk.internal.math.FloatingDecimal.getBinaryToASCIIBuffer()" })) {
1158*795d594fSAndroid Build Coastguard Worker result->SetL(CreateInstanceOf(self, "Ljdk/internal/math/FloatingDecimal$BinaryToASCIIBuffer;"));
1159*795d594fSAndroid Build Coastguard Worker } else {
1160*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
1161*795d594fSAndroid Build Coastguard Worker "ThreadLocal.get() does not support %s",
1162*795d594fSAndroid Build Coastguard Worker GetImmediateCaller(shadow_frame).c_str());
1163*795d594fSAndroid Build Coastguard Worker }
1164*795d594fSAndroid Build Coastguard Worker }
1165*795d594fSAndroid Build Coastguard Worker
UnstartedThreadCurrentThread(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1166*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedThreadCurrentThread(Thread* self,
1167*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1168*795d594fSAndroid Build Coastguard Worker JValue* result,
1169*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] size_t arg_offset) {
1170*795d594fSAndroid Build Coastguard Worker if (CheckCallers(shadow_frame,
1171*795d594fSAndroid Build Coastguard Worker { "void java.lang.Thread.<init>(java.lang.ThreadGroup, java.lang.Runnable, "
1172*795d594fSAndroid Build Coastguard Worker "java.lang.String, long, java.security.AccessControlContext, boolean)",
1173*795d594fSAndroid Build Coastguard Worker "void java.lang.Thread.<init>(java.lang.ThreadGroup, java.lang.Runnable, "
1174*795d594fSAndroid Build Coastguard Worker "java.lang.String, long)",
1175*795d594fSAndroid Build Coastguard Worker "void java.lang.Thread.<init>()",
1176*795d594fSAndroid Build Coastguard Worker "void java.util.logging.LogManager$Cleaner.<init>("
1177*795d594fSAndroid Build Coastguard Worker "java.util.logging.LogManager)" })) {
1178*795d594fSAndroid Build Coastguard Worker // Allow list LogManager$Cleaner, which is an unstarted Thread (for a shutdown hook). The
1179*795d594fSAndroid Build Coastguard Worker // Thread constructor only asks for the current thread to set up defaults and add the
1180*795d594fSAndroid Build Coastguard Worker // thread as unstarted to the ThreadGroup. A faked-up main thread peer is good enough for
1181*795d594fSAndroid Build Coastguard Worker // these purposes.
1182*795d594fSAndroid Build Coastguard Worker Runtime::Current()->InitThreadGroups(self);
1183*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> main_peer = self->CreateCompileTimePeer(
1184*795d594fSAndroid Build Coastguard Worker "main", /*as_daemon=*/ false, Runtime::Current()->GetMainThreadGroup());
1185*795d594fSAndroid Build Coastguard Worker if (main_peer == nullptr) {
1186*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Failed allocating peer");
1187*795d594fSAndroid Build Coastguard Worker return;
1188*795d594fSAndroid Build Coastguard Worker }
1189*795d594fSAndroid Build Coastguard Worker
1190*795d594fSAndroid Build Coastguard Worker result->SetL(main_peer);
1191*795d594fSAndroid Build Coastguard Worker } else {
1192*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
1193*795d594fSAndroid Build Coastguard Worker "Thread.currentThread() does not support %s",
1194*795d594fSAndroid Build Coastguard Worker GetImmediateCaller(shadow_frame).c_str());
1195*795d594fSAndroid Build Coastguard Worker }
1196*795d594fSAndroid Build Coastguard Worker }
1197*795d594fSAndroid Build Coastguard Worker
UnstartedThreadGetNativeState(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1198*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedThreadGetNativeState(Thread* self,
1199*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1200*795d594fSAndroid Build Coastguard Worker JValue* result,
1201*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] size_t arg_offset) {
1202*795d594fSAndroid Build Coastguard Worker if (CheckCallers(shadow_frame,
1203*795d594fSAndroid Build Coastguard Worker { "java.lang.Thread$State java.lang.Thread.getState()",
1204*795d594fSAndroid Build Coastguard Worker "java.lang.ThreadGroup java.lang.Thread.getThreadGroup()",
1205*795d594fSAndroid Build Coastguard Worker "void java.lang.Thread.<init>(java.lang.ThreadGroup, java.lang.Runnable, "
1206*795d594fSAndroid Build Coastguard Worker "java.lang.String, long, java.security.AccessControlContext, boolean)",
1207*795d594fSAndroid Build Coastguard Worker "void java.lang.Thread.<init>(java.lang.ThreadGroup, java.lang.Runnable, "
1208*795d594fSAndroid Build Coastguard Worker "java.lang.String, long)",
1209*795d594fSAndroid Build Coastguard Worker "void java.lang.Thread.<init>()",
1210*795d594fSAndroid Build Coastguard Worker "void java.util.logging.LogManager$Cleaner.<init>("
1211*795d594fSAndroid Build Coastguard Worker "java.util.logging.LogManager)" })) {
1212*795d594fSAndroid Build Coastguard Worker // Allow list reading the state of the "main" thread when creating another (unstarted) thread
1213*795d594fSAndroid Build Coastguard Worker // for LogManager. Report the thread as "new" (it really only counts that it isn't terminated).
1214*795d594fSAndroid Build Coastguard Worker constexpr int32_t kJavaRunnable = 1;
1215*795d594fSAndroid Build Coastguard Worker result->SetI(kJavaRunnable);
1216*795d594fSAndroid Build Coastguard Worker } else {
1217*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self,
1218*795d594fSAndroid Build Coastguard Worker "Thread.getNativeState() does not support %s",
1219*795d594fSAndroid Build Coastguard Worker GetImmediateCaller(shadow_frame).c_str());
1220*795d594fSAndroid Build Coastguard Worker }
1221*795d594fSAndroid Build Coastguard Worker }
1222*795d594fSAndroid Build Coastguard Worker
UnstartedMathCeil(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1223*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMathCeil([[maybe_unused]] Thread* self,
1224*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1225*795d594fSAndroid Build Coastguard Worker JValue* result,
1226*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1227*795d594fSAndroid Build Coastguard Worker result->SetD(ceil(shadow_frame->GetVRegDouble(arg_offset)));
1228*795d594fSAndroid Build Coastguard Worker }
1229*795d594fSAndroid Build Coastguard Worker
UnstartedMathFloor(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1230*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMathFloor([[maybe_unused]] Thread* self,
1231*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1232*795d594fSAndroid Build Coastguard Worker JValue* result,
1233*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1234*795d594fSAndroid Build Coastguard Worker result->SetD(floor(shadow_frame->GetVRegDouble(arg_offset)));
1235*795d594fSAndroid Build Coastguard Worker }
1236*795d594fSAndroid Build Coastguard Worker
UnstartedMathSin(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1237*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMathSin([[maybe_unused]] Thread* self,
1238*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1239*795d594fSAndroid Build Coastguard Worker JValue* result,
1240*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1241*795d594fSAndroid Build Coastguard Worker result->SetD(sin(shadow_frame->GetVRegDouble(arg_offset)));
1242*795d594fSAndroid Build Coastguard Worker }
1243*795d594fSAndroid Build Coastguard Worker
UnstartedMathCos(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1244*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMathCos([[maybe_unused]] Thread* self,
1245*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1246*795d594fSAndroid Build Coastguard Worker JValue* result,
1247*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1248*795d594fSAndroid Build Coastguard Worker result->SetD(cos(shadow_frame->GetVRegDouble(arg_offset)));
1249*795d594fSAndroid Build Coastguard Worker }
1250*795d594fSAndroid Build Coastguard Worker
UnstartedMathPow(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1251*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMathPow([[maybe_unused]] Thread* self,
1252*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1253*795d594fSAndroid Build Coastguard Worker JValue* result,
1254*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1255*795d594fSAndroid Build Coastguard Worker result->SetD(pow(shadow_frame->GetVRegDouble(arg_offset),
1256*795d594fSAndroid Build Coastguard Worker shadow_frame->GetVRegDouble(arg_offset + 2)));
1257*795d594fSAndroid Build Coastguard Worker }
1258*795d594fSAndroid Build Coastguard Worker
UnstartedMathTan(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1259*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMathTan([[maybe_unused]] Thread* self,
1260*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1261*795d594fSAndroid Build Coastguard Worker JValue* result,
1262*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1263*795d594fSAndroid Build Coastguard Worker result->SetD(tan(shadow_frame->GetVRegDouble(arg_offset)));
1264*795d594fSAndroid Build Coastguard Worker }
1265*795d594fSAndroid Build Coastguard Worker
UnstartedObjectHashCode(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1266*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedObjectHashCode([[maybe_unused]] Thread* self,
1267*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1268*795d594fSAndroid Build Coastguard Worker JValue* result,
1269*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1270*795d594fSAndroid Build Coastguard Worker mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1271*795d594fSAndroid Build Coastguard Worker result->SetI(obj->IdentityHashCode());
1272*795d594fSAndroid Build Coastguard Worker }
1273*795d594fSAndroid Build Coastguard Worker
UnstartedDoubleDoubleToRawLongBits(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1274*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits([[maybe_unused]] Thread* self,
1275*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1276*795d594fSAndroid Build Coastguard Worker JValue* result,
1277*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1278*795d594fSAndroid Build Coastguard Worker double in = shadow_frame->GetVRegDouble(arg_offset);
1279*795d594fSAndroid Build Coastguard Worker result->SetJ(bit_cast<int64_t, double>(in));
1280*795d594fSAndroid Build Coastguard Worker }
1281*795d594fSAndroid Build Coastguard Worker
UnstartedMemoryPeek(Primitive::Type type,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1282*795d594fSAndroid Build Coastguard Worker static void UnstartedMemoryPeek(
1283*795d594fSAndroid Build Coastguard Worker Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1284*795d594fSAndroid Build Coastguard Worker int64_t address = shadow_frame->GetVRegLong(arg_offset);
1285*795d594fSAndroid Build Coastguard Worker // TODO: Check that this is in the heap somewhere. Otherwise we will segfault instead of
1286*795d594fSAndroid Build Coastguard Worker // aborting the transaction.
1287*795d594fSAndroid Build Coastguard Worker
1288*795d594fSAndroid Build Coastguard Worker switch (type) {
1289*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimByte: {
1290*795d594fSAndroid Build Coastguard Worker result->SetB(*reinterpret_cast<int8_t*>(static_cast<intptr_t>(address)));
1291*795d594fSAndroid Build Coastguard Worker return;
1292*795d594fSAndroid Build Coastguard Worker }
1293*795d594fSAndroid Build Coastguard Worker
1294*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimShort: {
1295*795d594fSAndroid Build Coastguard Worker using unaligned_short __attribute__((__aligned__(1))) = int16_t;
1296*795d594fSAndroid Build Coastguard Worker result->SetS(*reinterpret_cast<unaligned_short*>(static_cast<intptr_t>(address)));
1297*795d594fSAndroid Build Coastguard Worker return;
1298*795d594fSAndroid Build Coastguard Worker }
1299*795d594fSAndroid Build Coastguard Worker
1300*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimInt: {
1301*795d594fSAndroid Build Coastguard Worker using unaligned_int __attribute__((__aligned__(1))) = int32_t;
1302*795d594fSAndroid Build Coastguard Worker result->SetI(*reinterpret_cast<unaligned_int*>(static_cast<intptr_t>(address)));
1303*795d594fSAndroid Build Coastguard Worker return;
1304*795d594fSAndroid Build Coastguard Worker }
1305*795d594fSAndroid Build Coastguard Worker
1306*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimLong: {
1307*795d594fSAndroid Build Coastguard Worker using unaligned_long __attribute__((__aligned__(1))) = int64_t;
1308*795d594fSAndroid Build Coastguard Worker result->SetJ(*reinterpret_cast<unaligned_long*>(static_cast<intptr_t>(address)));
1309*795d594fSAndroid Build Coastguard Worker return;
1310*795d594fSAndroid Build Coastguard Worker }
1311*795d594fSAndroid Build Coastguard Worker
1312*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimBoolean:
1313*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimChar:
1314*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimFloat:
1315*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimDouble:
1316*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimVoid:
1317*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimNot:
1318*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Not in the Memory API: " << type;
1319*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
1320*795d594fSAndroid Build Coastguard Worker }
1321*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Should not reach here";
1322*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
1323*795d594fSAndroid Build Coastguard Worker }
1324*795d594fSAndroid Build Coastguard Worker
UnstartedMemoryPeekByte(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1325*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMemoryPeekByte([[maybe_unused]] Thread* self,
1326*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1327*795d594fSAndroid Build Coastguard Worker JValue* result,
1328*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1329*795d594fSAndroid Build Coastguard Worker UnstartedMemoryPeek(Primitive::kPrimByte, shadow_frame, result, arg_offset);
1330*795d594fSAndroid Build Coastguard Worker }
1331*795d594fSAndroid Build Coastguard Worker
UnstartedMemoryPeekShort(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1332*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMemoryPeekShort([[maybe_unused]] Thread* self,
1333*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1334*795d594fSAndroid Build Coastguard Worker JValue* result,
1335*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1336*795d594fSAndroid Build Coastguard Worker UnstartedMemoryPeek(Primitive::kPrimShort, shadow_frame, result, arg_offset);
1337*795d594fSAndroid Build Coastguard Worker }
1338*795d594fSAndroid Build Coastguard Worker
UnstartedMemoryPeekInt(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1339*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMemoryPeekInt([[maybe_unused]] Thread* self,
1340*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1341*795d594fSAndroid Build Coastguard Worker JValue* result,
1342*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1343*795d594fSAndroid Build Coastguard Worker UnstartedMemoryPeek(Primitive::kPrimInt, shadow_frame, result, arg_offset);
1344*795d594fSAndroid Build Coastguard Worker }
1345*795d594fSAndroid Build Coastguard Worker
UnstartedMemoryPeekLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1346*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMemoryPeekLong([[maybe_unused]] Thread* self,
1347*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1348*795d594fSAndroid Build Coastguard Worker JValue* result,
1349*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1350*795d594fSAndroid Build Coastguard Worker UnstartedMemoryPeek(Primitive::kPrimLong, shadow_frame, result, arg_offset);
1351*795d594fSAndroid Build Coastguard Worker }
1352*795d594fSAndroid Build Coastguard Worker
UnstartedMemoryPeekArray(Primitive::Type type,Thread * self,ShadowFrame * shadow_frame,size_t arg_offset)1353*795d594fSAndroid Build Coastguard Worker static void UnstartedMemoryPeekArray(
1354*795d594fSAndroid Build Coastguard Worker Primitive::Type type, Thread* self, ShadowFrame* shadow_frame, size_t arg_offset)
1355*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1356*795d594fSAndroid Build Coastguard Worker int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
1357*795d594fSAndroid Build Coastguard Worker mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
1358*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
1359*795d594fSAndroid Build Coastguard Worker Runtime::Current()->GetClassLinker()->AbortTransactionF(self, "Null pointer in peekArray");
1360*795d594fSAndroid Build Coastguard Worker return;
1361*795d594fSAndroid Build Coastguard Worker }
1362*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Array> array = obj->AsArray();
1363*795d594fSAndroid Build Coastguard Worker
1364*795d594fSAndroid Build Coastguard Worker int offset = shadow_frame->GetVReg(arg_offset + 3);
1365*795d594fSAndroid Build Coastguard Worker int count = shadow_frame->GetVReg(arg_offset + 4);
1366*795d594fSAndroid Build Coastguard Worker if (offset < 0 || offset + count > array->GetLength()) {
1367*795d594fSAndroid Build Coastguard Worker Runtime::Current()->GetClassLinker()->AbortTransactionF(
1368*795d594fSAndroid Build Coastguard Worker self, "Array out of bounds in peekArray: %d/%d vs %d", offset, count, array->GetLength());
1369*795d594fSAndroid Build Coastguard Worker return;
1370*795d594fSAndroid Build Coastguard Worker }
1371*795d594fSAndroid Build Coastguard Worker
1372*795d594fSAndroid Build Coastguard Worker switch (type) {
1373*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimByte: {
1374*795d594fSAndroid Build Coastguard Worker int8_t* address = reinterpret_cast<int8_t*>(static_cast<intptr_t>(address_long));
1375*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ByteArray> byte_array = array->AsByteArray();
1376*795d594fSAndroid Build Coastguard Worker for (int32_t i = 0; i < count; ++i, ++address) {
1377*795d594fSAndroid Build Coastguard Worker byte_array->SetWithoutChecks<true>(i + offset, *address);
1378*795d594fSAndroid Build Coastguard Worker }
1379*795d594fSAndroid Build Coastguard Worker return;
1380*795d594fSAndroid Build Coastguard Worker }
1381*795d594fSAndroid Build Coastguard Worker
1382*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimShort:
1383*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimInt:
1384*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimLong:
1385*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Type unimplemented for Memory Array API, should not reach here: " << type;
1386*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
1387*795d594fSAndroid Build Coastguard Worker
1388*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimBoolean:
1389*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimChar:
1390*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimFloat:
1391*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimDouble:
1392*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimVoid:
1393*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimNot:
1394*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Not in the Memory API: " << type;
1395*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
1396*795d594fSAndroid Build Coastguard Worker }
1397*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Should not reach here";
1398*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
1399*795d594fSAndroid Build Coastguard Worker }
1400*795d594fSAndroid Build Coastguard Worker
UnstartedMemoryPeekByteArray(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1401*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMemoryPeekByteArray(Thread* self,
1402*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1403*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] JValue* result,
1404*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1405*795d594fSAndroid Build Coastguard Worker UnstartedMemoryPeekArray(Primitive::kPrimByte, self, shadow_frame, arg_offset);
1406*795d594fSAndroid Build Coastguard Worker }
1407*795d594fSAndroid Build Coastguard Worker
1408*795d594fSAndroid Build Coastguard Worker // This allows reading the new style of String objects during compilation.
UnstartedStringGetCharsNoCheck(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1409*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedStringGetCharsNoCheck(Thread* self,
1410*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1411*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] JValue* result,
1412*795d594fSAndroid Build Coastguard Worker size_t arg_offset) {
1413*795d594fSAndroid Build Coastguard Worker jint start = shadow_frame->GetVReg(arg_offset + 1);
1414*795d594fSAndroid Build Coastguard Worker jint end = shadow_frame->GetVReg(arg_offset + 2);
1415*795d594fSAndroid Build Coastguard Worker jint index = shadow_frame->GetVReg(arg_offset + 4);
1416*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1417*795d594fSAndroid Build Coastguard Worker if (string == nullptr) {
1418*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "String.getCharsNoCheck with null object");
1419*795d594fSAndroid Build Coastguard Worker return;
1420*795d594fSAndroid Build Coastguard Worker }
1421*795d594fSAndroid Build Coastguard Worker DCHECK_GE(start, 0);
1422*795d594fSAndroid Build Coastguard Worker DCHECK_LE(start, end);
1423*795d594fSAndroid Build Coastguard Worker DCHECK_LE(end, string->GetLength());
1424*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
1425*795d594fSAndroid Build Coastguard Worker Handle<mirror::CharArray> h_char_array(
1426*795d594fSAndroid Build Coastguard Worker hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray()));
1427*795d594fSAndroid Build Coastguard Worker DCHECK_GE(index, 0);
1428*795d594fSAndroid Build Coastguard Worker DCHECK_LE(index, h_char_array->GetLength());
1429*795d594fSAndroid Build Coastguard Worker DCHECK_LE(end - start, h_char_array->GetLength() - index);
1430*795d594fSAndroid Build Coastguard Worker string->GetChars(start, end, h_char_array, index);
1431*795d594fSAndroid Build Coastguard Worker }
1432*795d594fSAndroid Build Coastguard Worker
1433*795d594fSAndroid Build Coastguard Worker // 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)1434*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedStringCharAt(
1435*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1436*795d594fSAndroid Build Coastguard Worker jint index = shadow_frame->GetVReg(arg_offset + 1);
1437*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> string = shadow_frame->GetVRegReference(arg_offset)->AsString();
1438*795d594fSAndroid Build Coastguard Worker if (string == nullptr) {
1439*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "String.charAt with null object");
1440*795d594fSAndroid Build Coastguard Worker return;
1441*795d594fSAndroid Build Coastguard Worker }
1442*795d594fSAndroid Build Coastguard Worker result->SetC(string->CharAt(index));
1443*795d594fSAndroid Build Coastguard Worker }
1444*795d594fSAndroid Build Coastguard Worker
1445*795d594fSAndroid Build Coastguard Worker // This allows creating String objects with replaced characters during compilation.
1446*795d594fSAndroid Build Coastguard Worker // 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)1447*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedStringDoReplace(
1448*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1449*795d594fSAndroid Build Coastguard Worker jchar old_c = shadow_frame->GetVReg(arg_offset + 1);
1450*795d594fSAndroid Build Coastguard Worker jchar new_c = shadow_frame->GetVReg(arg_offset + 2);
1451*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
1452*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> string =
1453*795d594fSAndroid Build Coastguard Worker hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
1454*795d594fSAndroid Build Coastguard Worker if (string == nullptr) {
1455*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "String.replaceWithMatch with null object");
1456*795d594fSAndroid Build Coastguard Worker return;
1457*795d594fSAndroid Build Coastguard Worker }
1458*795d594fSAndroid Build Coastguard Worker result->SetL(mirror::String::DoReplace(self, string, old_c, new_c));
1459*795d594fSAndroid Build Coastguard Worker }
1460*795d594fSAndroid Build Coastguard Worker
1461*795d594fSAndroid Build Coastguard Worker // This allows creating the new style of String objects during compilation.
UnstartedStringFactoryNewStringFromBytes(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1462*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedStringFactoryNewStringFromBytes(
1463*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1464*795d594fSAndroid Build Coastguard Worker jint high = shadow_frame->GetVReg(arg_offset + 1);
1465*795d594fSAndroid Build Coastguard Worker jint offset = shadow_frame->GetVReg(arg_offset + 2);
1466*795d594fSAndroid Build Coastguard Worker jint byte_count = shadow_frame->GetVReg(arg_offset + 3);
1467*795d594fSAndroid Build Coastguard Worker DCHECK_GE(byte_count, 0);
1468*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
1469*795d594fSAndroid Build Coastguard Worker Handle<mirror::ByteArray> h_byte_array(
1470*795d594fSAndroid Build Coastguard Worker hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsByteArray()));
1471*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
1472*795d594fSAndroid Build Coastguard Worker gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1473*795d594fSAndroid Build Coastguard Worker result->SetL(
1474*795d594fSAndroid Build Coastguard Worker mirror::String::AllocFromByteArray(self, byte_count, h_byte_array, offset, high, allocator));
1475*795d594fSAndroid Build Coastguard Worker }
1476*795d594fSAndroid Build Coastguard Worker
1477*795d594fSAndroid Build Coastguard Worker // This allows creating the new style of String objects during compilation.
UnstartedStringFactoryNewStringFromChars(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1478*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedStringFactoryNewStringFromChars(
1479*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1480*795d594fSAndroid Build Coastguard Worker jint offset = shadow_frame->GetVReg(arg_offset);
1481*795d594fSAndroid Build Coastguard Worker jint char_count = shadow_frame->GetVReg(arg_offset + 1);
1482*795d594fSAndroid Build Coastguard Worker DCHECK_GE(char_count, 0);
1483*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
1484*795d594fSAndroid Build Coastguard Worker Handle<mirror::CharArray> h_char_array(
1485*795d594fSAndroid Build Coastguard Worker hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray()));
1486*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
1487*795d594fSAndroid Build Coastguard Worker gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1488*795d594fSAndroid Build Coastguard Worker result->SetL(
1489*795d594fSAndroid Build Coastguard Worker mirror::String::AllocFromCharArray(self, char_count, h_char_array, offset, allocator));
1490*795d594fSAndroid Build Coastguard Worker }
1491*795d594fSAndroid Build Coastguard Worker
1492*795d594fSAndroid Build Coastguard Worker // This allows creating the new style of String objects during compilation.
UnstartedStringFactoryNewStringFromString(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1493*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedStringFactoryNewStringFromString(
1494*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1495*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> to_copy = shadow_frame->GetVRegReference(arg_offset)->AsString();
1496*795d594fSAndroid Build Coastguard Worker if (to_copy == nullptr) {
1497*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "StringFactory.newStringFromString with null object");
1498*795d594fSAndroid Build Coastguard Worker return;
1499*795d594fSAndroid Build Coastguard Worker }
1500*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
1501*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> h_string(hs.NewHandle(to_copy));
1502*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
1503*795d594fSAndroid Build Coastguard Worker gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1504*795d594fSAndroid Build Coastguard Worker result->SetL(
1505*795d594fSAndroid Build Coastguard Worker mirror::String::AllocFromString(self, h_string->GetLength(), h_string, 0, allocator));
1506*795d594fSAndroid Build Coastguard Worker }
1507*795d594fSAndroid Build Coastguard Worker
UnstartedStringFastSubstring(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1508*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedStringFastSubstring(
1509*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1510*795d594fSAndroid Build Coastguard Worker jint start = shadow_frame->GetVReg(arg_offset + 1);
1511*795d594fSAndroid Build Coastguard Worker jint length = shadow_frame->GetVReg(arg_offset + 2);
1512*795d594fSAndroid Build Coastguard Worker DCHECK_GE(start, 0);
1513*795d594fSAndroid Build Coastguard Worker DCHECK_GE(length, 0);
1514*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
1515*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> h_string(
1516*795d594fSAndroid Build Coastguard Worker hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString()));
1517*795d594fSAndroid Build Coastguard Worker DCHECK_LE(start, h_string->GetLength());
1518*795d594fSAndroid Build Coastguard Worker DCHECK_LE(start + length, h_string->GetLength());
1519*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
1520*795d594fSAndroid Build Coastguard Worker gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1521*795d594fSAndroid Build Coastguard Worker result->SetL(mirror::String::AllocFromString(self, length, h_string, start, allocator));
1522*795d594fSAndroid Build Coastguard Worker }
1523*795d594fSAndroid Build Coastguard Worker
1524*795d594fSAndroid Build Coastguard Worker // 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)1525*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedStringToCharArray(
1526*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1527*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1528*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
1529*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> string =
1530*795d594fSAndroid Build Coastguard Worker hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString());
1531*795d594fSAndroid Build Coastguard Worker if (string == nullptr) {
1532*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "String.charAt with null object");
1533*795d594fSAndroid Build Coastguard Worker return;
1534*795d594fSAndroid Build Coastguard Worker }
1535*795d594fSAndroid Build Coastguard Worker result->SetL(mirror::String::ToCharArray(string, self));
1536*795d594fSAndroid Build Coastguard Worker }
1537*795d594fSAndroid Build Coastguard Worker
1538*795d594fSAndroid Build Coastguard Worker // This allows statically initializing ConcurrentHashMap and SynchronousQueue.
UnstartedReferenceGetReferent(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1539*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedReferenceGetReferent(
1540*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1541*795d594fSAndroid Build Coastguard Worker const ObjPtr<mirror::Reference> ref = ObjPtr<mirror::Reference>::DownCast(
1542*795d594fSAndroid Build Coastguard Worker shadow_frame->GetVRegReference(arg_offset));
1543*795d594fSAndroid Build Coastguard Worker if (ref == nullptr) {
1544*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Reference.getReferent() with null object");
1545*795d594fSAndroid Build Coastguard Worker return;
1546*795d594fSAndroid Build Coastguard Worker }
1547*795d594fSAndroid Build Coastguard Worker const ObjPtr<mirror::Object> referent =
1548*795d594fSAndroid Build Coastguard Worker Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1549*795d594fSAndroid Build Coastguard Worker result->SetL(referent);
1550*795d594fSAndroid Build Coastguard Worker }
1551*795d594fSAndroid Build Coastguard Worker
UnstartedReferenceRefersTo(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1552*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedReferenceRefersTo(
1553*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1554*795d594fSAndroid Build Coastguard Worker // Use the naive implementation that may block and needlessly extend the lifetime
1555*795d594fSAndroid Build Coastguard Worker // of the referenced object.
1556*795d594fSAndroid Build Coastguard Worker const ObjPtr<mirror::Reference> ref = ObjPtr<mirror::Reference>::DownCast(
1557*795d594fSAndroid Build Coastguard Worker shadow_frame->GetVRegReference(arg_offset));
1558*795d594fSAndroid Build Coastguard Worker if (ref == nullptr) {
1559*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Reference.refersTo() with null object");
1560*795d594fSAndroid Build Coastguard Worker return;
1561*795d594fSAndroid Build Coastguard Worker }
1562*795d594fSAndroid Build Coastguard Worker const ObjPtr<mirror::Object> referent =
1563*795d594fSAndroid Build Coastguard Worker Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(self, ref);
1564*795d594fSAndroid Build Coastguard Worker const ObjPtr<mirror::Object> o = shadow_frame->GetVRegReference(arg_offset + 1);
1565*795d594fSAndroid Build Coastguard Worker result->SetZ(o == referent);
1566*795d594fSAndroid Build Coastguard Worker }
1567*795d594fSAndroid Build Coastguard Worker
1568*795d594fSAndroid Build Coastguard Worker // This allows statically initializing ConcurrentHashMap and SynchronousQueue. We use a somewhat
1569*795d594fSAndroid Build Coastguard Worker // conservative upper bound. We restrict the callers to SynchronousQueue and ConcurrentHashMap,
1570*795d594fSAndroid Build Coastguard Worker // where we can predict the behavior (somewhat).
1571*795d594fSAndroid Build Coastguard Worker // Note: this is required (instead of lazy initialization) as these classes are used in the static
1572*795d594fSAndroid Build Coastguard Worker // initialization of other classes, so will *use* the value.
UnstartedRuntimeAvailableProcessors(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1573*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedRuntimeAvailableProcessors(Thread* self,
1574*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1575*795d594fSAndroid Build Coastguard Worker JValue* result,
1576*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] size_t arg_offset) {
1577*795d594fSAndroid Build Coastguard Worker if (CheckCallers(shadow_frame, { "void java.util.concurrent.SynchronousQueue.<clinit>()" })) {
1578*795d594fSAndroid Build Coastguard Worker // SynchronousQueue really only separates between single- and multiprocessor case. Return
1579*795d594fSAndroid Build Coastguard Worker // 8 as a conservative upper approximation.
1580*795d594fSAndroid Build Coastguard Worker result->SetI(8);
1581*795d594fSAndroid Build Coastguard Worker } else if (CheckCallers(shadow_frame,
1582*795d594fSAndroid Build Coastguard Worker { "void java.util.concurrent.ConcurrentHashMap.<clinit>()" })) {
1583*795d594fSAndroid Build Coastguard Worker // ConcurrentHashMap uses it for striding. 8 still seems an OK general value, as it's likely
1584*795d594fSAndroid Build Coastguard Worker // a good upper bound.
1585*795d594fSAndroid Build Coastguard Worker // TODO: Consider resetting in the zygote?
1586*795d594fSAndroid Build Coastguard Worker result->SetI(8);
1587*795d594fSAndroid Build Coastguard Worker } else {
1588*795d594fSAndroid Build Coastguard Worker // Not supported.
1589*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Accessing availableProcessors not allowed");
1590*795d594fSAndroid Build Coastguard Worker }
1591*795d594fSAndroid Build Coastguard Worker }
1592*795d594fSAndroid Build Coastguard Worker
1593*795d594fSAndroid Build Coastguard Worker // This allows accessing ConcurrentHashMap/SynchronousQueue.
1594*795d594fSAndroid Build Coastguard Worker
UnstartedUnsafeCompareAndSwapLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1595*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedUnsafeCompareAndSwapLong(
1596*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1597*795d594fSAndroid Build Coastguard Worker UnstartedJdkUnsafeCompareAndSwapLong(self, shadow_frame, result, arg_offset);
1598*795d594fSAndroid Build Coastguard Worker }
1599*795d594fSAndroid Build Coastguard Worker
UnstartedUnsafeCompareAndSwapObject(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1600*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
1601*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1602*795d594fSAndroid Build Coastguard Worker UnstartedJdkUnsafeCompareAndSwapObject(self, shadow_frame, result, arg_offset);
1603*795d594fSAndroid Build Coastguard Worker }
1604*795d594fSAndroid Build Coastguard Worker
UnstartedUnsafeGetObjectVolatile(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1605*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedUnsafeGetObjectVolatile(
1606*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1607*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1608*795d594fSAndroid Build Coastguard Worker UnstartedJdkUnsafeGetReferenceVolatile(self, shadow_frame, result, arg_offset);
1609*795d594fSAndroid Build Coastguard Worker }
1610*795d594fSAndroid Build Coastguard Worker
UnstartedUnsafePutObjectVolatile(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1611*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedUnsafePutObjectVolatile(
1612*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1613*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1614*795d594fSAndroid Build Coastguard Worker UnstartedJdkUnsafePutReferenceVolatile(self, shadow_frame, result, arg_offset);
1615*795d594fSAndroid Build Coastguard Worker }
1616*795d594fSAndroid Build Coastguard Worker
UnstartedUnsafePutOrderedObject(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1617*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedUnsafePutOrderedObject(
1618*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1619*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1620*795d594fSAndroid Build Coastguard Worker UnstartedJdkUnsafePutOrderedObject(self, shadow_frame, result, arg_offset);
1621*795d594fSAndroid Build Coastguard Worker }
1622*795d594fSAndroid Build Coastguard Worker
UnstartedJdkUnsafeCompareAndSetLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1623*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJdkUnsafeCompareAndSetLong(
1624*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1625*795d594fSAndroid Build Coastguard Worker UnstartedJdkUnsafeCompareAndSwapLong(self, shadow_frame, result, arg_offset);
1626*795d594fSAndroid Build Coastguard Worker }
1627*795d594fSAndroid Build Coastguard Worker
UnstartedJdkUnsafeCompareAndSetReference(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1628*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJdkUnsafeCompareAndSetReference(
1629*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1630*795d594fSAndroid Build Coastguard Worker UnstartedJdkUnsafeCompareAndSwapObject(self, shadow_frame, result, arg_offset);
1631*795d594fSAndroid Build Coastguard Worker }
1632*795d594fSAndroid Build Coastguard Worker
UnstartedJdkUnsafeCompareAndSwapLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1633*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJdkUnsafeCompareAndSwapLong(
1634*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1635*795d594fSAndroid Build Coastguard Worker // Argument 0 is the Unsafe instance, skip.
1636*795d594fSAndroid Build Coastguard Worker mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1637*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
1638*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1639*795d594fSAndroid Build Coastguard Worker return;
1640*795d594fSAndroid Build Coastguard Worker }
1641*795d594fSAndroid Build Coastguard Worker int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1642*795d594fSAndroid Build Coastguard Worker int64_t expectedValue = shadow_frame->GetVRegLong(arg_offset + 4);
1643*795d594fSAndroid Build Coastguard Worker int64_t newValue = shadow_frame->GetVRegLong(arg_offset + 6);
1644*795d594fSAndroid Build Coastguard Worker bool success;
1645*795d594fSAndroid Build Coastguard Worker // Check whether we're in a transaction, call accordingly.
1646*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
1647*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction()) {
1648*795d594fSAndroid Build Coastguard Worker if (runtime->GetClassLinker()->TransactionWriteConstraint(self, obj)) {
1649*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
1650*795d594fSAndroid Build Coastguard Worker return;
1651*795d594fSAndroid Build Coastguard Worker }
1652*795d594fSAndroid Build Coastguard Worker success = obj->CasFieldStrongSequentiallyConsistent64<true>(MemberOffset(offset),
1653*795d594fSAndroid Build Coastguard Worker expectedValue,
1654*795d594fSAndroid Build Coastguard Worker newValue);
1655*795d594fSAndroid Build Coastguard Worker } else {
1656*795d594fSAndroid Build Coastguard Worker success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
1657*795d594fSAndroid Build Coastguard Worker expectedValue,
1658*795d594fSAndroid Build Coastguard Worker newValue);
1659*795d594fSAndroid Build Coastguard Worker }
1660*795d594fSAndroid Build Coastguard Worker result->SetZ(success ? 1 : 0);
1661*795d594fSAndroid Build Coastguard Worker }
1662*795d594fSAndroid Build Coastguard Worker
UnstartedJdkUnsafeCompareAndSwapObject(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1663*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJdkUnsafeCompareAndSwapObject(
1664*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
1665*795d594fSAndroid Build Coastguard Worker // Argument 0 is the Unsafe instance, skip.
1666*795d594fSAndroid Build Coastguard Worker mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1667*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
1668*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1669*795d594fSAndroid Build Coastguard Worker return;
1670*795d594fSAndroid Build Coastguard Worker }
1671*795d594fSAndroid Build Coastguard Worker int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1672*795d594fSAndroid Build Coastguard Worker mirror::Object* expected_value = shadow_frame->GetVRegReference(arg_offset + 4);
1673*795d594fSAndroid Build Coastguard Worker mirror::Object* new_value = shadow_frame->GetVRegReference(arg_offset + 5);
1674*795d594fSAndroid Build Coastguard Worker
1675*795d594fSAndroid Build Coastguard Worker // Must use non transactional mode.
1676*795d594fSAndroid Build Coastguard Worker if (gUseReadBarrier) {
1677*795d594fSAndroid Build Coastguard Worker // Need to make sure the reference stored in the field is a to-space one before attempting the
1678*795d594fSAndroid Build Coastguard Worker // CAS or the CAS could fail incorrectly.
1679*795d594fSAndroid Build Coastguard Worker mirror::HeapReference<mirror::Object>* field_addr =
1680*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::HeapReference<mirror::Object>*>(
1681*795d594fSAndroid Build Coastguard Worker reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset));
1682*795d594fSAndroid Build Coastguard Worker ReadBarrier::Barrier<
1683*795d594fSAndroid Build Coastguard Worker mirror::Object,
1684*795d594fSAndroid Build Coastguard Worker /* kIsVolatile= */ false,
1685*795d594fSAndroid Build Coastguard Worker kWithReadBarrier,
1686*795d594fSAndroid Build Coastguard Worker /* kAlwaysUpdateField= */ true>(
1687*795d594fSAndroid Build Coastguard Worker obj,
1688*795d594fSAndroid Build Coastguard Worker MemberOffset(offset),
1689*795d594fSAndroid Build Coastguard Worker field_addr);
1690*795d594fSAndroid Build Coastguard Worker }
1691*795d594fSAndroid Build Coastguard Worker bool success;
1692*795d594fSAndroid Build Coastguard Worker // Check whether we're in a transaction, call accordingly.
1693*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
1694*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction()) {
1695*795d594fSAndroid Build Coastguard Worker if (runtime->GetClassLinker()->TransactionWriteConstraint(self, obj) ||
1696*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->TransactionWriteValueConstraint(self, new_value)) {
1697*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
1698*795d594fSAndroid Build Coastguard Worker return;
1699*795d594fSAndroid Build Coastguard Worker }
1700*795d594fSAndroid Build Coastguard Worker success = obj->CasFieldObject<true>(MemberOffset(offset),
1701*795d594fSAndroid Build Coastguard Worker expected_value,
1702*795d594fSAndroid Build Coastguard Worker new_value,
1703*795d594fSAndroid Build Coastguard Worker CASMode::kStrong,
1704*795d594fSAndroid Build Coastguard Worker std::memory_order_seq_cst);
1705*795d594fSAndroid Build Coastguard Worker } else {
1706*795d594fSAndroid Build Coastguard Worker success = obj->CasFieldObject<false>(MemberOffset(offset),
1707*795d594fSAndroid Build Coastguard Worker expected_value,
1708*795d594fSAndroid Build Coastguard Worker new_value,
1709*795d594fSAndroid Build Coastguard Worker CASMode::kStrong,
1710*795d594fSAndroid Build Coastguard Worker std::memory_order_seq_cst);
1711*795d594fSAndroid Build Coastguard Worker }
1712*795d594fSAndroid Build Coastguard Worker result->SetZ(success ? 1 : 0);
1713*795d594fSAndroid Build Coastguard Worker }
1714*795d594fSAndroid Build Coastguard Worker
UnstartedJdkUnsafeGetReferenceVolatile(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1715*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJdkUnsafeGetReferenceVolatile(
1716*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1717*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1718*795d594fSAndroid Build Coastguard Worker // Argument 0 is the Unsafe instance, skip.
1719*795d594fSAndroid Build Coastguard Worker mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1720*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
1721*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1722*795d594fSAndroid Build Coastguard Worker return;
1723*795d594fSAndroid Build Coastguard Worker }
1724*795d594fSAndroid Build Coastguard Worker int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1725*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
1726*795d594fSAndroid Build Coastguard Worker result->SetL(value);
1727*795d594fSAndroid Build Coastguard Worker }
1728*795d594fSAndroid Build Coastguard Worker
UnstartedJdkUnsafePutReferenceVolatile(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1729*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJdkUnsafePutReferenceVolatile(Thread* self,
1730*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1731*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] JValue* result,
1732*795d594fSAndroid Build Coastguard Worker size_t arg_offset)
1733*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1734*795d594fSAndroid Build Coastguard Worker // Argument 0 is the Unsafe instance, skip.
1735*795d594fSAndroid Build Coastguard Worker mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1736*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
1737*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1738*795d594fSAndroid Build Coastguard Worker return;
1739*795d594fSAndroid Build Coastguard Worker }
1740*795d594fSAndroid Build Coastguard Worker int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1741*795d594fSAndroid Build Coastguard Worker mirror::Object* value = shadow_frame->GetVRegReference(arg_offset + 4);
1742*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
1743*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction()) {
1744*795d594fSAndroid Build Coastguard Worker if (runtime->GetClassLinker()->TransactionWriteConstraint(self, obj) ||
1745*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->TransactionWriteValueConstraint(self, value)) {
1746*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
1747*795d594fSAndroid Build Coastguard Worker return;
1748*795d594fSAndroid Build Coastguard Worker }
1749*795d594fSAndroid Build Coastguard Worker obj->SetFieldObjectVolatile<true>(MemberOffset(offset), value);
1750*795d594fSAndroid Build Coastguard Worker } else {
1751*795d594fSAndroid Build Coastguard Worker obj->SetFieldObjectVolatile<false>(MemberOffset(offset), value);
1752*795d594fSAndroid Build Coastguard Worker }
1753*795d594fSAndroid Build Coastguard Worker }
1754*795d594fSAndroid Build Coastguard Worker
UnstartedJdkUnsafePutOrderedObject(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1755*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJdkUnsafePutOrderedObject(Thread* self,
1756*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1757*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] JValue* result,
1758*795d594fSAndroid Build Coastguard Worker size_t arg_offset)
1759*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1760*795d594fSAndroid Build Coastguard Worker // Argument 0 is the Unsafe instance, skip.
1761*795d594fSAndroid Build Coastguard Worker mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 1);
1762*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
1763*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
1764*795d594fSAndroid Build Coastguard Worker return;
1765*795d594fSAndroid Build Coastguard Worker }
1766*795d594fSAndroid Build Coastguard Worker int64_t offset = shadow_frame->GetVRegLong(arg_offset + 2);
1767*795d594fSAndroid Build Coastguard Worker mirror::Object* new_value = shadow_frame->GetVRegReference(arg_offset + 4);
1768*795d594fSAndroid Build Coastguard Worker std::atomic_thread_fence(std::memory_order_release);
1769*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
1770*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction()) {
1771*795d594fSAndroid Build Coastguard Worker if (runtime->GetClassLinker()->TransactionWriteConstraint(self, obj) ||
1772*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->TransactionWriteValueConstraint(self, new_value)) {
1773*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
1774*795d594fSAndroid Build Coastguard Worker return;
1775*795d594fSAndroid Build Coastguard Worker }
1776*795d594fSAndroid Build Coastguard Worker obj->SetFieldObject<true>(MemberOffset(offset), new_value);
1777*795d594fSAndroid Build Coastguard Worker } else {
1778*795d594fSAndroid Build Coastguard Worker obj->SetFieldObject<false>(MemberOffset(offset), new_value);
1779*795d594fSAndroid Build Coastguard Worker }
1780*795d594fSAndroid Build Coastguard Worker }
1781*795d594fSAndroid Build Coastguard Worker
1782*795d594fSAndroid Build Coastguard Worker // A cutout for Integer.parseInt(String). Note: this code is conservative and will bail instead
1783*795d594fSAndroid Build Coastguard Worker // of correctly handling the corner cases.
UnstartedIntegerParseInt(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1784*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedIntegerParseInt(
1785*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1786*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1787*795d594fSAndroid Build Coastguard Worker mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1788*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
1789*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1790*795d594fSAndroid Build Coastguard Worker return;
1791*795d594fSAndroid Build Coastguard Worker }
1792*795d594fSAndroid Build Coastguard Worker
1793*795d594fSAndroid Build Coastguard Worker std::string string_value = obj->AsString()->ToModifiedUtf8();
1794*795d594fSAndroid Build Coastguard Worker if (string_value.empty()) {
1795*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1796*795d594fSAndroid Build Coastguard Worker return;
1797*795d594fSAndroid Build Coastguard Worker }
1798*795d594fSAndroid Build Coastguard Worker
1799*795d594fSAndroid Build Coastguard Worker const char* c_str = string_value.c_str();
1800*795d594fSAndroid Build Coastguard Worker char *end;
1801*795d594fSAndroid Build Coastguard Worker // Can we set errno to 0? Is this always a variable, and not a macro?
1802*795d594fSAndroid Build Coastguard Worker // Worst case, we'll incorrectly fail a transaction. Seems OK.
1803*795d594fSAndroid Build Coastguard Worker int64_t l = strtol(c_str, &end, 10);
1804*795d594fSAndroid Build Coastguard Worker
1805*795d594fSAndroid Build Coastguard Worker if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1806*795d594fSAndroid Build Coastguard Worker (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1807*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1808*795d594fSAndroid Build Coastguard Worker return;
1809*795d594fSAndroid Build Coastguard Worker }
1810*795d594fSAndroid Build Coastguard Worker if (l == 0) {
1811*795d594fSAndroid Build Coastguard Worker // Check whether the string wasn't exactly zero.
1812*795d594fSAndroid Build Coastguard Worker if (string_value != "0") {
1813*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1814*795d594fSAndroid Build Coastguard Worker return;
1815*795d594fSAndroid Build Coastguard Worker }
1816*795d594fSAndroid Build Coastguard Worker } else if (*end != '\0') {
1817*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1818*795d594fSAndroid Build Coastguard Worker return;
1819*795d594fSAndroid Build Coastguard Worker }
1820*795d594fSAndroid Build Coastguard Worker
1821*795d594fSAndroid Build Coastguard Worker result->SetI(static_cast<int32_t>(l));
1822*795d594fSAndroid Build Coastguard Worker }
1823*795d594fSAndroid Build Coastguard Worker
1824*795d594fSAndroid Build Coastguard Worker // A cutout for Long.parseLong.
1825*795d594fSAndroid Build Coastguard Worker //
1826*795d594fSAndroid Build Coastguard Worker // Note: for now use code equivalent to Integer.parseInt, as the full range may not be supported
1827*795d594fSAndroid Build Coastguard Worker // well.
UnstartedLongParseLong(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1828*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedLongParseLong(
1829*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1830*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1831*795d594fSAndroid Build Coastguard Worker mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1832*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
1833*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot parse null string, retry at runtime.");
1834*795d594fSAndroid Build Coastguard Worker return;
1835*795d594fSAndroid Build Coastguard Worker }
1836*795d594fSAndroid Build Coastguard Worker
1837*795d594fSAndroid Build Coastguard Worker std::string string_value = obj->AsString()->ToModifiedUtf8();
1838*795d594fSAndroid Build Coastguard Worker if (string_value.empty()) {
1839*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot parse empty string, retry at runtime.");
1840*795d594fSAndroid Build Coastguard Worker return;
1841*795d594fSAndroid Build Coastguard Worker }
1842*795d594fSAndroid Build Coastguard Worker
1843*795d594fSAndroid Build Coastguard Worker const char* c_str = string_value.c_str();
1844*795d594fSAndroid Build Coastguard Worker char *end;
1845*795d594fSAndroid Build Coastguard Worker // Can we set errno to 0? Is this always a variable, and not a macro?
1846*795d594fSAndroid Build Coastguard Worker // Worst case, we'll incorrectly fail a transaction. Seems OK.
1847*795d594fSAndroid Build Coastguard Worker int64_t l = strtol(c_str, &end, 10);
1848*795d594fSAndroid Build Coastguard Worker
1849*795d594fSAndroid Build Coastguard Worker // Note: comparing against int32_t min/max is intentional here.
1850*795d594fSAndroid Build Coastguard Worker if ((errno == ERANGE && l == LONG_MAX) || l > std::numeric_limits<int32_t>::max() ||
1851*795d594fSAndroid Build Coastguard Worker (errno == ERANGE && l == LONG_MIN) || l < std::numeric_limits<int32_t>::min()) {
1852*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1853*795d594fSAndroid Build Coastguard Worker return;
1854*795d594fSAndroid Build Coastguard Worker }
1855*795d594fSAndroid Build Coastguard Worker if (l == 0) {
1856*795d594fSAndroid Build Coastguard Worker // Check whether the string wasn't exactly zero.
1857*795d594fSAndroid Build Coastguard Worker if (string_value != "0") {
1858*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1859*795d594fSAndroid Build Coastguard Worker return;
1860*795d594fSAndroid Build Coastguard Worker }
1861*795d594fSAndroid Build Coastguard Worker } else if (*end != '\0') {
1862*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot parse string %s, retry at runtime.", c_str);
1863*795d594fSAndroid Build Coastguard Worker return;
1864*795d594fSAndroid Build Coastguard Worker }
1865*795d594fSAndroid Build Coastguard Worker
1866*795d594fSAndroid Build Coastguard Worker result->SetJ(l);
1867*795d594fSAndroid Build Coastguard Worker }
1868*795d594fSAndroid Build Coastguard Worker
UnstartedMethodInvoke(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1869*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedMethodInvoke(
1870*795d594fSAndroid Build Coastguard Worker Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
1871*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1872*795d594fSAndroid Build Coastguard Worker JNIEnvExt* env = self->GetJniEnv();
1873*795d594fSAndroid Build Coastguard Worker ScopedObjectAccessUnchecked soa(self);
1874*795d594fSAndroid Build Coastguard Worker
1875*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> java_method_obj = shadow_frame->GetVRegReference(arg_offset);
1876*795d594fSAndroid Build Coastguard Worker ScopedLocalRef<jobject> java_method(env,
1877*795d594fSAndroid Build Coastguard Worker java_method_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_method_obj));
1878*795d594fSAndroid Build Coastguard Worker
1879*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> java_receiver_obj = shadow_frame->GetVRegReference(arg_offset + 1);
1880*795d594fSAndroid Build Coastguard Worker ScopedLocalRef<jobject> java_receiver(env,
1881*795d594fSAndroid Build Coastguard Worker java_receiver_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_receiver_obj));
1882*795d594fSAndroid Build Coastguard Worker
1883*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> java_args_obj = shadow_frame->GetVRegReference(arg_offset + 2);
1884*795d594fSAndroid Build Coastguard Worker ScopedLocalRef<jobject> java_args(env,
1885*795d594fSAndroid Build Coastguard Worker java_args_obj == nullptr ? nullptr : env->AddLocalReference<jobject>(java_args_obj));
1886*795d594fSAndroid Build Coastguard Worker
1887*795d594fSAndroid Build Coastguard Worker PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1888*795d594fSAndroid Build Coastguard Worker ScopedLocalRef<jobject> result_jobj(env,
1889*795d594fSAndroid Build Coastguard Worker (pointer_size == PointerSize::k64)
1890*795d594fSAndroid Build Coastguard Worker ? InvokeMethod<PointerSize::k64>(soa,
1891*795d594fSAndroid Build Coastguard Worker java_method.get(),
1892*795d594fSAndroid Build Coastguard Worker java_receiver.get(),
1893*795d594fSAndroid Build Coastguard Worker java_args.get())
1894*795d594fSAndroid Build Coastguard Worker : InvokeMethod<PointerSize::k32>(soa,
1895*795d594fSAndroid Build Coastguard Worker java_method.get(),
1896*795d594fSAndroid Build Coastguard Worker java_receiver.get(),
1897*795d594fSAndroid Build Coastguard Worker java_args.get()));
1898*795d594fSAndroid Build Coastguard Worker
1899*795d594fSAndroid Build Coastguard Worker result->SetL(self->DecodeJObject(result_jobj.get()));
1900*795d594fSAndroid Build Coastguard Worker
1901*795d594fSAndroid Build Coastguard Worker // Conservatively flag all exceptions as transaction aborts. This way we don't need to unwrap
1902*795d594fSAndroid Build Coastguard Worker // InvocationTargetExceptions.
1903*795d594fSAndroid Build Coastguard Worker if (self->IsExceptionPending()) {
1904*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Failed Method.invoke");
1905*795d594fSAndroid Build Coastguard Worker }
1906*795d594fSAndroid Build Coastguard Worker }
1907*795d594fSAndroid Build Coastguard Worker
UnstartedSystemIdentityHashCode(Thread * self,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)1908*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedSystemIdentityHashCode([[maybe_unused]] Thread* self,
1909*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
1910*795d594fSAndroid Build Coastguard Worker JValue* result,
1911*795d594fSAndroid Build Coastguard Worker size_t arg_offset)
1912*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1913*795d594fSAndroid Build Coastguard Worker mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset);
1914*795d594fSAndroid Build Coastguard Worker result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
1915*795d594fSAndroid Build Coastguard Worker }
1916*795d594fSAndroid Build Coastguard Worker
1917*795d594fSAndroid Build Coastguard Worker // Checks whether the runtime is s64-bit. This is needed for the clinit of
1918*795d594fSAndroid Build Coastguard Worker // java.lang.invoke.VarHandle clinit. The clinit determines sets of
1919*795d594fSAndroid Build Coastguard Worker // available VarHandle accessors and these differ based on machine
1920*795d594fSAndroid Build Coastguard Worker // word size.
UnstartedJNIVMRuntimeIs64Bit(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)1921*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIVMRuntimeIs64Bit([[maybe_unused]] Thread* self,
1922*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
1923*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
1924*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
1925*795d594fSAndroid Build Coastguard Worker JValue* result) {
1926*795d594fSAndroid Build Coastguard Worker PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1927*795d594fSAndroid Build Coastguard Worker jboolean is64bit = (pointer_size == PointerSize::k64) ? JNI_TRUE : JNI_FALSE;
1928*795d594fSAndroid Build Coastguard Worker result->SetZ(is64bit);
1929*795d594fSAndroid Build Coastguard Worker }
1930*795d594fSAndroid Build Coastguard Worker
UnstartedJNIVMRuntimeNewUnpaddedArray(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)1931*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
1932*795d594fSAndroid Build Coastguard Worker Thread* self,
1933*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
1934*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
1935*795d594fSAndroid Build Coastguard Worker uint32_t* args,
1936*795d594fSAndroid Build Coastguard Worker JValue* result) {
1937*795d594fSAndroid Build Coastguard Worker int32_t length = args[1];
1938*795d594fSAndroid Build Coastguard Worker DCHECK_GE(length, 0);
1939*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> element_class = reinterpret_cast32<mirror::Object*>(args[0])->AsClass();
1940*795d594fSAndroid Build Coastguard Worker if (element_class == nullptr) {
1941*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "VMRuntime.newUnpaddedArray with null element_class.");
1942*795d594fSAndroid Build Coastguard Worker return;
1943*795d594fSAndroid Build Coastguard Worker }
1944*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
1945*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> array_class =
1946*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->FindArrayClass(self, element_class->AsClass());
1947*795d594fSAndroid Build Coastguard Worker DCHECK(array_class != nullptr);
1948*795d594fSAndroid Build Coastguard Worker gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
1949*795d594fSAndroid Build Coastguard Worker result->SetL(mirror::Array::Alloc</*kIsInstrumented=*/ true, /*kFillUsable=*/ true>(
1950*795d594fSAndroid Build Coastguard Worker self, array_class, length, array_class->GetComponentSizeShift(), allocator));
1951*795d594fSAndroid Build Coastguard Worker }
1952*795d594fSAndroid Build Coastguard Worker
UnstartedJNIVMStackGetCallingClassLoader(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)1953*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIVMStackGetCallingClassLoader(
1954*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] Thread* self,
1955*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
1956*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
1957*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
1958*795d594fSAndroid Build Coastguard Worker JValue* result) {
1959*795d594fSAndroid Build Coastguard Worker result->SetL(nullptr);
1960*795d594fSAndroid Build Coastguard Worker }
1961*795d594fSAndroid Build Coastguard Worker
UnstartedJNIVMStackGetStackClass2(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)1962*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIVMStackGetStackClass2(Thread* self,
1963*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
1964*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
1965*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
1966*795d594fSAndroid Build Coastguard Worker JValue* result) {
1967*795d594fSAndroid Build Coastguard Worker NthCallerVisitor visitor(self, 3);
1968*795d594fSAndroid Build Coastguard Worker visitor.WalkStack();
1969*795d594fSAndroid Build Coastguard Worker if (visitor.caller != nullptr) {
1970*795d594fSAndroid Build Coastguard Worker result->SetL(visitor.caller->GetDeclaringClass());
1971*795d594fSAndroid Build Coastguard Worker }
1972*795d594fSAndroid Build Coastguard Worker }
1973*795d594fSAndroid Build Coastguard Worker
UnstartedJNIMathLog(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)1974*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIMathLog([[maybe_unused]] Thread* self,
1975*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
1976*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
1977*795d594fSAndroid Build Coastguard Worker uint32_t* args,
1978*795d594fSAndroid Build Coastguard Worker JValue* result) {
1979*795d594fSAndroid Build Coastguard Worker JValue value;
1980*795d594fSAndroid Build Coastguard Worker value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1981*795d594fSAndroid Build Coastguard Worker result->SetD(log(value.GetD()));
1982*795d594fSAndroid Build Coastguard Worker }
1983*795d594fSAndroid Build Coastguard Worker
UnstartedJNIMathExp(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)1984*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIMathExp([[maybe_unused]] Thread* self,
1985*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
1986*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
1987*795d594fSAndroid Build Coastguard Worker uint32_t* args,
1988*795d594fSAndroid Build Coastguard Worker JValue* result) {
1989*795d594fSAndroid Build Coastguard Worker JValue value;
1990*795d594fSAndroid Build Coastguard Worker value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
1991*795d594fSAndroid Build Coastguard Worker result->SetD(exp(value.GetD()));
1992*795d594fSAndroid Build Coastguard Worker }
1993*795d594fSAndroid Build Coastguard Worker
UnstartedJNIAtomicLongVMSupportsCS8(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)1994*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIAtomicLongVMSupportsCS8(
1995*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] Thread* self,
1996*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
1997*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
1998*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
1999*795d594fSAndroid Build Coastguard Worker JValue* result) {
2000*795d594fSAndroid Build Coastguard Worker result->SetZ(QuasiAtomic::LongAtomicsUseMutexes(Runtime::Current()->GetInstructionSet())
2001*795d594fSAndroid Build Coastguard Worker ? 0
2002*795d594fSAndroid Build Coastguard Worker : 1);
2003*795d594fSAndroid Build Coastguard Worker }
2004*795d594fSAndroid Build Coastguard Worker
UnstartedJNIClassGetNameNative(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2005*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIClassGetNameNative(Thread* self,
2006*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2007*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2008*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
2009*795d594fSAndroid Build Coastguard Worker JValue* result) {
2010*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
2011*795d594fSAndroid Build Coastguard Worker result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass())));
2012*795d594fSAndroid Build Coastguard Worker }
2013*795d594fSAndroid Build Coastguard Worker
UnstartedJNIDoubleLongBitsToDouble(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2014*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIDoubleLongBitsToDouble([[maybe_unused]] Thread* self,
2015*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2016*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2017*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2018*795d594fSAndroid Build Coastguard Worker JValue* result) {
2019*795d594fSAndroid Build Coastguard Worker uint64_t long_input = args[0] | (static_cast<uint64_t>(args[1]) << 32);
2020*795d594fSAndroid Build Coastguard Worker result->SetD(bit_cast<double>(long_input));
2021*795d594fSAndroid Build Coastguard Worker }
2022*795d594fSAndroid Build Coastguard Worker
UnstartedJNIFloatFloatToRawIntBits(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2023*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIFloatFloatToRawIntBits([[maybe_unused]] Thread* self,
2024*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2025*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2026*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2027*795d594fSAndroid Build Coastguard Worker JValue* result) {
2028*795d594fSAndroid Build Coastguard Worker result->SetI(args[0]);
2029*795d594fSAndroid Build Coastguard Worker }
2030*795d594fSAndroid Build Coastguard Worker
UnstartedJNIFloatIntBitsToFloat(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2031*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIFloatIntBitsToFloat([[maybe_unused]] Thread* self,
2032*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2033*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2034*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2035*795d594fSAndroid Build Coastguard Worker JValue* result) {
2036*795d594fSAndroid Build Coastguard Worker result->SetI(args[0]);
2037*795d594fSAndroid Build Coastguard Worker }
2038*795d594fSAndroid Build Coastguard Worker
UnstartedJNIObjectInternalClone(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2039*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIObjectInternalClone(Thread* self,
2040*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2041*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2042*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
2043*795d594fSAndroid Build Coastguard Worker JValue* result) {
2044*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
2045*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> h_receiver = hs.NewHandle(receiver);
2046*795d594fSAndroid Build Coastguard Worker result->SetL(mirror::Object::Clone(h_receiver, self));
2047*795d594fSAndroid Build Coastguard Worker }
2048*795d594fSAndroid Build Coastguard Worker
UnstartedJNIObjectNotifyAll(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2049*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIObjectNotifyAll(Thread* self,
2050*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2051*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2052*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
2053*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] JValue* result) {
2054*795d594fSAndroid Build Coastguard Worker receiver->NotifyAll(self);
2055*795d594fSAndroid Build Coastguard Worker }
2056*795d594fSAndroid Build Coastguard Worker
UnstartedJNIStringCompareTo(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2057*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIStringCompareTo(Thread* self,
2058*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2059*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2060*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2061*795d594fSAndroid Build Coastguard Worker JValue* result) {
2062*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> rhs = reinterpret_cast32<mirror::Object*>(args[0]);
2063*795d594fSAndroid Build Coastguard Worker if (rhs == nullptr) {
2064*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "String.compareTo with null object.");
2065*795d594fSAndroid Build Coastguard Worker return;
2066*795d594fSAndroid Build Coastguard Worker }
2067*795d594fSAndroid Build Coastguard Worker result->SetI(receiver->AsString()->CompareTo(rhs->AsString()));
2068*795d594fSAndroid Build Coastguard Worker }
2069*795d594fSAndroid Build Coastguard Worker
UnstartedJNIStringFillBytesLatin1(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue *)2070*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIStringFillBytesLatin1(Thread* self,
2071*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2072*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2073*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2074*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] JValue*) {
2075*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
2076*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> h_receiver(hs.NewHandle(
2077*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::String*>(receiver)->AsString()));
2078*795d594fSAndroid Build Coastguard Worker Handle<mirror::ByteArray> h_buffer(hs.NewHandle(
2079*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::ByteArray*>(args[0])->AsByteArray()));
2080*795d594fSAndroid Build Coastguard Worker int32_t index = static_cast<int32_t>(args[1]);
2081*795d594fSAndroid Build Coastguard Worker h_receiver->FillBytesLatin1(h_buffer, index);
2082*795d594fSAndroid Build Coastguard Worker }
2083*795d594fSAndroid Build Coastguard Worker
UnstartedJNIStringFillBytesUTF16(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue *)2084*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIStringFillBytesUTF16(Thread* self,
2085*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2086*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2087*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2088*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] JValue*) {
2089*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
2090*795d594fSAndroid Build Coastguard Worker Handle<mirror::String> h_receiver(hs.NewHandle(
2091*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::String*>(receiver)->AsString()));
2092*795d594fSAndroid Build Coastguard Worker Handle<mirror::ByteArray> h_buffer(hs.NewHandle(
2093*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::ByteArray*>(args[0])->AsByteArray()));
2094*795d594fSAndroid Build Coastguard Worker int32_t index = static_cast<int32_t>(args[1]);
2095*795d594fSAndroid Build Coastguard Worker h_receiver->FillBytesUTF16(h_buffer, index);
2096*795d594fSAndroid Build Coastguard Worker }
2097*795d594fSAndroid Build Coastguard Worker
UnstartedJNIStringIntern(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2098*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIStringIntern([[maybe_unused]] Thread* self,
2099*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2100*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2101*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
2102*795d594fSAndroid Build Coastguard Worker JValue* result) {
2103*795d594fSAndroid Build Coastguard Worker result->SetL(receiver->AsString()->Intern());
2104*795d594fSAndroid Build Coastguard Worker }
2105*795d594fSAndroid Build Coastguard Worker
UnstartedJNIArrayCreateMultiArray(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2106*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIArrayCreateMultiArray(Thread* self,
2107*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2108*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2109*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2110*795d594fSAndroid Build Coastguard Worker JValue* result) {
2111*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
2112*795d594fSAndroid Build Coastguard Worker auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass()));
2113*795d594fSAndroid Build Coastguard Worker auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray()));
2114*795d594fSAndroid Build Coastguard Worker result->SetL(mirror::Array::CreateMultiArray(self, h_class, h_dimensions));
2115*795d594fSAndroid Build Coastguard Worker }
2116*795d594fSAndroid Build Coastguard Worker
UnstartedJNIArrayCreateObjectArray(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2117*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIArrayCreateObjectArray(Thread* self,
2118*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2119*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2120*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2121*795d594fSAndroid Build Coastguard Worker JValue* result) {
2122*795d594fSAndroid Build Coastguard Worker int32_t length = static_cast<int32_t>(args[1]);
2123*795d594fSAndroid Build Coastguard Worker if (length < 0) {
2124*795d594fSAndroid Build Coastguard Worker ThrowNegativeArraySizeException(length);
2125*795d594fSAndroid Build Coastguard Worker return;
2126*795d594fSAndroid Build Coastguard Worker }
2127*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Class*>(args[0])->AsClass();
2128*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
2129*795d594fSAndroid Build Coastguard Worker ClassLinker* class_linker = runtime->GetClassLinker();
2130*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, element_class);
2131*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(array_class == nullptr)) {
2132*795d594fSAndroid Build Coastguard Worker CHECK(self->IsExceptionPending());
2133*795d594fSAndroid Build Coastguard Worker return;
2134*795d594fSAndroid Build Coastguard Worker }
2135*795d594fSAndroid Build Coastguard Worker DCHECK(array_class->IsObjectArrayClass());
2136*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Array> new_array = mirror::ObjectArray<mirror::Object>::Alloc(
2137*795d594fSAndroid Build Coastguard Worker self, array_class, length, runtime->GetHeap()->GetCurrentAllocator());
2138*795d594fSAndroid Build Coastguard Worker result->SetL(new_array);
2139*795d594fSAndroid Build Coastguard Worker }
2140*795d594fSAndroid Build Coastguard Worker
UnstartedJNIThrowableNativeFillInStackTrace(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2141*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace(
2142*795d594fSAndroid Build Coastguard Worker Thread* self,
2143*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2144*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2145*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
2146*795d594fSAndroid Build Coastguard Worker JValue* result) {
2147*795d594fSAndroid Build Coastguard Worker ScopedObjectAccessUnchecked soa(self);
2148*795d594fSAndroid Build Coastguard Worker result->SetL(self->CreateInternalStackTrace(soa));
2149*795d594fSAndroid Build Coastguard Worker }
2150*795d594fSAndroid Build Coastguard Worker
UnstartedJNIUnsafeCompareAndSwapInt(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2151*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
2152*795d594fSAndroid Build Coastguard Worker Thread* self,
2153*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
2154*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2155*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2156*795d594fSAndroid Build Coastguard Worker JValue* result) {
2157*795d594fSAndroid Build Coastguard Worker UnstartedJNIJdkUnsafeCompareAndSwapInt(self, method, receiver, args, result);
2158*795d594fSAndroid Build Coastguard Worker }
2159*795d594fSAndroid Build Coastguard Worker
UnstartedJNIUnsafeGetIntVolatile(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2160*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(Thread* self,
2161*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
2162*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2163*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2164*795d594fSAndroid Build Coastguard Worker JValue* result) {
2165*795d594fSAndroid Build Coastguard Worker UnstartedJNIJdkUnsafeGetIntVolatile(self, method, receiver, args, result);
2166*795d594fSAndroid Build Coastguard Worker }
2167*795d594fSAndroid Build Coastguard Worker
UnstartedJNIUnsafePutObject(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2168*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIUnsafePutObject(Thread* self,
2169*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
2170*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2171*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2172*795d594fSAndroid Build Coastguard Worker JValue* result) {
2173*795d594fSAndroid Build Coastguard Worker UnstartedJNIJdkUnsafePutReference(self, method, receiver, args, result);
2174*795d594fSAndroid Build Coastguard Worker }
2175*795d594fSAndroid Build Coastguard Worker
UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2176*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
2177*795d594fSAndroid Build Coastguard Worker Thread* self,
2178*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
2179*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2180*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2181*795d594fSAndroid Build Coastguard Worker JValue* result) {
2182*795d594fSAndroid Build Coastguard Worker UnstartedJNIJdkUnsafeGetArrayBaseOffsetForComponentType(self, method, receiver, args, result);
2183*795d594fSAndroid Build Coastguard Worker }
2184*795d594fSAndroid Build Coastguard Worker
UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2185*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
2186*795d594fSAndroid Build Coastguard Worker Thread* self,
2187*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
2188*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2189*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2190*795d594fSAndroid Build Coastguard Worker JValue* result) {
2191*795d594fSAndroid Build Coastguard Worker UnstartedJNIJdkUnsafeGetArrayIndexScaleForComponentType(self, method, receiver, args, result);
2192*795d594fSAndroid Build Coastguard Worker }
2193*795d594fSAndroid Build Coastguard Worker
UnstartedJNIJdkUnsafeAddressSize(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2194*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIJdkUnsafeAddressSize([[maybe_unused]] Thread* self,
2195*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2196*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2197*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
2198*795d594fSAndroid Build Coastguard Worker JValue* result) {
2199*795d594fSAndroid Build Coastguard Worker result->SetI(sizeof(void*));
2200*795d594fSAndroid Build Coastguard Worker }
2201*795d594fSAndroid Build Coastguard Worker
UnstartedJNIJdkUnsafeCompareAndSwapInt(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2202*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIJdkUnsafeCompareAndSwapInt(
2203*795d594fSAndroid Build Coastguard Worker Thread* self,
2204*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2205*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2206*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2207*795d594fSAndroid Build Coastguard Worker JValue* result) {
2208*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
2209*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
2210*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
2211*795d594fSAndroid Build Coastguard Worker return;
2212*795d594fSAndroid Build Coastguard Worker }
2213*795d594fSAndroid Build Coastguard Worker jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
2214*795d594fSAndroid Build Coastguard Worker jint expectedValue = args[3];
2215*795d594fSAndroid Build Coastguard Worker jint newValue = args[4];
2216*795d594fSAndroid Build Coastguard Worker bool success;
2217*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
2218*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction()) {
2219*795d594fSAndroid Build Coastguard Worker if (runtime->GetClassLinker()->TransactionWriteConstraint(self, obj)) {
2220*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
2221*795d594fSAndroid Build Coastguard Worker return;
2222*795d594fSAndroid Build Coastguard Worker }
2223*795d594fSAndroid Build Coastguard Worker success = obj->CasField32<true>(MemberOffset(offset),
2224*795d594fSAndroid Build Coastguard Worker expectedValue,
2225*795d594fSAndroid Build Coastguard Worker newValue,
2226*795d594fSAndroid Build Coastguard Worker CASMode::kStrong,
2227*795d594fSAndroid Build Coastguard Worker std::memory_order_seq_cst);
2228*795d594fSAndroid Build Coastguard Worker } else {
2229*795d594fSAndroid Build Coastguard Worker success = obj->CasField32<false>(MemberOffset(offset),
2230*795d594fSAndroid Build Coastguard Worker expectedValue,
2231*795d594fSAndroid Build Coastguard Worker newValue,
2232*795d594fSAndroid Build Coastguard Worker CASMode::kStrong,
2233*795d594fSAndroid Build Coastguard Worker std::memory_order_seq_cst);
2234*795d594fSAndroid Build Coastguard Worker }
2235*795d594fSAndroid Build Coastguard Worker result->SetZ(success ? JNI_TRUE : JNI_FALSE);
2236*795d594fSAndroid Build Coastguard Worker }
2237*795d594fSAndroid Build Coastguard Worker
UnstartedJNIJdkUnsafeCompareAndSetInt(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2238*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIJdkUnsafeCompareAndSetInt(
2239*795d594fSAndroid Build Coastguard Worker Thread* self,
2240*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
2241*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2242*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2243*795d594fSAndroid Build Coastguard Worker JValue* result) {
2244*795d594fSAndroid Build Coastguard Worker UnstartedJNIJdkUnsafeCompareAndSwapInt(self, method, receiver, args, result);
2245*795d594fSAndroid Build Coastguard Worker }
2246*795d594fSAndroid Build Coastguard Worker
UnstartedJNIJdkUnsafeGetIntVolatile(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2247*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIJdkUnsafeGetIntVolatile(
2248*795d594fSAndroid Build Coastguard Worker Thread* self,
2249*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2250*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2251*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2252*795d594fSAndroid Build Coastguard Worker JValue* result) {
2253*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
2254*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
2255*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Unsafe.compareAndSwapIntVolatile with null object.");
2256*795d594fSAndroid Build Coastguard Worker return;
2257*795d594fSAndroid Build Coastguard Worker }
2258*795d594fSAndroid Build Coastguard Worker
2259*795d594fSAndroid Build Coastguard Worker jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
2260*795d594fSAndroid Build Coastguard Worker result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
2261*795d594fSAndroid Build Coastguard Worker }
2262*795d594fSAndroid Build Coastguard Worker
UnstartedJNIJdkUnsafePutReference(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2263*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIJdkUnsafePutReference(Thread* self,
2264*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2265*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2266*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2267*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] JValue* result) {
2268*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
2269*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
2270*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Unsafe.putObject with null object.");
2271*795d594fSAndroid Build Coastguard Worker return;
2272*795d594fSAndroid Build Coastguard Worker }
2273*795d594fSAndroid Build Coastguard Worker jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
2274*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> new_value = reinterpret_cast32<mirror::Object*>(args[3]);
2275*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
2276*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction()) {
2277*795d594fSAndroid Build Coastguard Worker if (runtime->GetClassLinker()->TransactionWriteConstraint(self, obj) ||
2278*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->TransactionWriteValueConstraint(self, new_value)) {
2279*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
2280*795d594fSAndroid Build Coastguard Worker return;
2281*795d594fSAndroid Build Coastguard Worker }
2282*795d594fSAndroid Build Coastguard Worker obj->SetFieldObject<true>(MemberOffset(offset), new_value);
2283*795d594fSAndroid Build Coastguard Worker } else {
2284*795d594fSAndroid Build Coastguard Worker obj->SetFieldObject<false>(MemberOffset(offset), new_value);
2285*795d594fSAndroid Build Coastguard Worker }
2286*795d594fSAndroid Build Coastguard Worker }
2287*795d594fSAndroid Build Coastguard Worker
UnstartedJNIJdkUnsafeStoreFence(Thread * self ATTRIBUTE_UNUSED,ArtMethod * method ATTRIBUTE_UNUSED,mirror::Object * receiver ATTRIBUTE_UNUSED,uint32_t * args ATTRIBUTE_UNUSED,JValue * result ATTRIBUTE_UNUSED)2288*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIJdkUnsafeStoreFence(Thread* self ATTRIBUTE_UNUSED,
2289*795d594fSAndroid Build Coastguard Worker ArtMethod* method ATTRIBUTE_UNUSED,
2290*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver ATTRIBUTE_UNUSED,
2291*795d594fSAndroid Build Coastguard Worker uint32_t* args ATTRIBUTE_UNUSED,
2292*795d594fSAndroid Build Coastguard Worker JValue* result ATTRIBUTE_UNUSED) {
2293*795d594fSAndroid Build Coastguard Worker std::atomic_thread_fence(std::memory_order_release);
2294*795d594fSAndroid Build Coastguard Worker }
2295*795d594fSAndroid Build Coastguard Worker
UnstartedJNIJdkUnsafeGetArrayBaseOffsetForComponentType(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2296*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIJdkUnsafeGetArrayBaseOffsetForComponentType(
2297*795d594fSAndroid Build Coastguard Worker Thread* self,
2298*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2299*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2300*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2301*795d594fSAndroid Build Coastguard Worker JValue* result) {
2302*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
2303*795d594fSAndroid Build Coastguard Worker if (component == nullptr) {
2304*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Unsafe.getArrayBaseOffsetForComponentType with null component.");
2305*795d594fSAndroid Build Coastguard Worker return;
2306*795d594fSAndroid Build Coastguard Worker }
2307*795d594fSAndroid Build Coastguard Worker Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
2308*795d594fSAndroid Build Coastguard Worker result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
2309*795d594fSAndroid Build Coastguard Worker }
2310*795d594fSAndroid Build Coastguard Worker
UnstartedJNIJdkUnsafeGetArrayIndexScaleForComponentType(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2311*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIJdkUnsafeGetArrayIndexScaleForComponentType(
2312*795d594fSAndroid Build Coastguard Worker Thread* self,
2313*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2314*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] mirror::Object* receiver,
2315*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2316*795d594fSAndroid Build Coastguard Worker JValue* result) {
2317*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
2318*795d594fSAndroid Build Coastguard Worker if (component == nullptr) {
2319*795d594fSAndroid Build Coastguard Worker AbortTransactionOrFail(self, "Unsafe.getArrayIndexScaleForComponentType with null component.");
2320*795d594fSAndroid Build Coastguard Worker return;
2321*795d594fSAndroid Build Coastguard Worker }
2322*795d594fSAndroid Build Coastguard Worker Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
2323*795d594fSAndroid Build Coastguard Worker result->SetI(Primitive::ComponentSize(primitive_type));
2324*795d594fSAndroid Build Coastguard Worker }
2325*795d594fSAndroid Build Coastguard Worker
UnstartedJNIFieldGetArtField(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2326*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIFieldGetArtField([[maybe_unused]] Thread* self,
2327*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2328*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2329*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
2330*795d594fSAndroid Build Coastguard Worker JValue* result) {
2331*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Field> field = ObjPtr<mirror::Field>::DownCast(receiver);
2332*795d594fSAndroid Build Coastguard Worker ArtField* art_field = field->GetArtField();
2333*795d594fSAndroid Build Coastguard Worker result->SetJ(reinterpret_cast<int64_t>(art_field));
2334*795d594fSAndroid Build Coastguard Worker }
2335*795d594fSAndroid Build Coastguard Worker
UnstartedJNIFieldGetNameInternal(Thread * self,ArtMethod * method,mirror::Object * receiver,uint32_t * args,JValue * result)2336*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::UnstartedJNIFieldGetNameInternal([[maybe_unused]] Thread* self,
2337*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] ArtMethod* method,
2338*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2339*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t* args,
2340*795d594fSAndroid Build Coastguard Worker JValue* result) {
2341*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Field> field = ObjPtr<mirror::Field>::DownCast(receiver);
2342*795d594fSAndroid Build Coastguard Worker ArtField* art_field = field->GetArtField();
2343*795d594fSAndroid Build Coastguard Worker result->SetL(art_field->ResolveNameString());
2344*795d594fSAndroid Build Coastguard Worker }
2345*795d594fSAndroid Build Coastguard Worker
2346*795d594fSAndroid Build Coastguard Worker using InvokeHandler = void(*)(Thread* self,
2347*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
2348*795d594fSAndroid Build Coastguard Worker JValue* result,
2349*795d594fSAndroid Build Coastguard Worker size_t arg_size);
2350*795d594fSAndroid Build Coastguard Worker
2351*795d594fSAndroid Build Coastguard Worker using JNIHandler = void(*)(Thread* self,
2352*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
2353*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver,
2354*795d594fSAndroid Build Coastguard Worker uint32_t* args,
2355*795d594fSAndroid Build Coastguard Worker JValue* result);
2356*795d594fSAndroid Build Coastguard Worker
2357*795d594fSAndroid Build Coastguard Worker // NOLINTNEXTLINE
2358*795d594fSAndroid Build Coastguard Worker #define ONE_PLUS(ShortNameIgnored, DescriptorIgnored, NameIgnored, SignatureIgnored) 1 +
2359*795d594fSAndroid Build Coastguard Worker static constexpr size_t kInvokeHandlersSize = UNSTARTED_RUNTIME_DIRECT_LIST(ONE_PLUS) 0;
2360*795d594fSAndroid Build Coastguard Worker static constexpr size_t kJniHandlersSize = UNSTARTED_RUNTIME_JNI_LIST(ONE_PLUS) 0;
2361*795d594fSAndroid Build Coastguard Worker #undef ONE_PLUS
2362*795d594fSAndroid Build Coastguard Worker
2363*795d594fSAndroid Build Coastguard Worker // The actual value of `kMinLoadFactor` is irrelevant because the HashMap<>s below
2364*795d594fSAndroid Build Coastguard Worker // are never resized, but we still need to pass a reasonable value to the constructor.
2365*795d594fSAndroid Build Coastguard Worker static constexpr double kMinLoadFactor = 0.5;
2366*795d594fSAndroid Build Coastguard Worker static constexpr double kMaxLoadFactor = 0.7;
2367*795d594fSAndroid Build Coastguard Worker
BufferSize(size_t size)2368*795d594fSAndroid Build Coastguard Worker constexpr size_t BufferSize(size_t size) {
2369*795d594fSAndroid Build Coastguard Worker // Note: ceil() is not suitable for constexpr, so cast to size_t and adjust by 1 if needed.
2370*795d594fSAndroid Build Coastguard Worker const size_t estimate = static_cast<size_t>(size / kMaxLoadFactor);
2371*795d594fSAndroid Build Coastguard Worker return static_cast<size_t>(estimate * kMaxLoadFactor) == size ? estimate : estimate + 1u;
2372*795d594fSAndroid Build Coastguard Worker }
2373*795d594fSAndroid Build Coastguard Worker
2374*795d594fSAndroid Build Coastguard Worker static constexpr size_t kInvokeHandlersBufferSize = BufferSize(kInvokeHandlersSize);
2375*795d594fSAndroid Build Coastguard Worker static_assert(
2376*795d594fSAndroid Build Coastguard Worker static_cast<size_t>(kInvokeHandlersBufferSize * kMaxLoadFactor) == kInvokeHandlersSize);
2377*795d594fSAndroid Build Coastguard Worker static constexpr size_t kJniHandlersBufferSize = BufferSize(kJniHandlersSize);
2378*795d594fSAndroid Build Coastguard Worker static_assert(static_cast<size_t>(kJniHandlersBufferSize * kMaxLoadFactor) == kJniHandlersSize);
2379*795d594fSAndroid Build Coastguard Worker
2380*795d594fSAndroid Build Coastguard Worker static bool tables_initialized_ = false;
2381*795d594fSAndroid Build Coastguard Worker static std::pair<ArtMethod*, InvokeHandler> kInvokeHandlersBuffer[kInvokeHandlersBufferSize];
2382*795d594fSAndroid Build Coastguard Worker static HashMap<ArtMethod*, InvokeHandler> invoke_handlers_(
2383*795d594fSAndroid Build Coastguard Worker kMinLoadFactor, kMaxLoadFactor, kInvokeHandlersBuffer, kInvokeHandlersBufferSize);
2384*795d594fSAndroid Build Coastguard Worker static std::pair<ArtMethod*, JNIHandler> kJniHandlersBuffer[kJniHandlersBufferSize];
2385*795d594fSAndroid Build Coastguard Worker static HashMap<ArtMethod*, JNIHandler> jni_handlers_(
2386*795d594fSAndroid Build Coastguard Worker kMinLoadFactor, kMaxLoadFactor, kJniHandlersBuffer, kJniHandlersBufferSize);
2387*795d594fSAndroid Build Coastguard Worker
FindMethod(Thread * self,ClassLinker * class_linker,const char * descriptor,std::string_view name,std::string_view signature)2388*795d594fSAndroid Build Coastguard Worker static ArtMethod* FindMethod(Thread* self,
2389*795d594fSAndroid Build Coastguard Worker ClassLinker* class_linker,
2390*795d594fSAndroid Build Coastguard Worker const char* descriptor,
2391*795d594fSAndroid Build Coastguard Worker std::string_view name,
2392*795d594fSAndroid Build Coastguard Worker std::string_view signature) REQUIRES_SHARED(Locks::mutator_lock_) {
2393*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> klass = class_linker->FindSystemClass(self, descriptor);
2394*795d594fSAndroid Build Coastguard Worker DCHECK(klass != nullptr) << descriptor;
2395*795d594fSAndroid Build Coastguard Worker ArtMethod* method = klass->FindClassMethod(name, signature, class_linker->GetImagePointerSize());
2396*795d594fSAndroid Build Coastguard Worker DCHECK(method != nullptr) << descriptor << "." << name << signature;
2397*795d594fSAndroid Build Coastguard Worker return method;
2398*795d594fSAndroid Build Coastguard Worker }
2399*795d594fSAndroid Build Coastguard Worker
InitializeInvokeHandlers(Thread * self)2400*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::InitializeInvokeHandlers(Thread* self) {
2401*795d594fSAndroid Build Coastguard Worker ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2402*795d594fSAndroid Build Coastguard Worker #define UNSTARTED_DIRECT(ShortName, Descriptor, Name, Signature) \
2403*795d594fSAndroid Build Coastguard Worker { \
2404*795d594fSAndroid Build Coastguard Worker ArtMethod* method = FindMethod(self, class_linker, Descriptor, Name, Signature); \
2405*795d594fSAndroid Build Coastguard Worker invoke_handlers_.insert(std::make_pair(method, & UnstartedRuntime::Unstarted ## ShortName)); \
2406*795d594fSAndroid Build Coastguard Worker }
2407*795d594fSAndroid Build Coastguard Worker UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
2408*795d594fSAndroid Build Coastguard Worker #undef UNSTARTED_DIRECT
2409*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(invoke_handlers_.NumBuckets(), kInvokeHandlersBufferSize);
2410*795d594fSAndroid Build Coastguard Worker }
2411*795d594fSAndroid Build Coastguard Worker
InitializeJNIHandlers(Thread * self)2412*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::InitializeJNIHandlers(Thread* self) {
2413*795d594fSAndroid Build Coastguard Worker ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2414*795d594fSAndroid Build Coastguard Worker #define UNSTARTED_JNI(ShortName, Descriptor, Name, Signature) \
2415*795d594fSAndroid Build Coastguard Worker { \
2416*795d594fSAndroid Build Coastguard Worker ArtMethod* method = FindMethod(self, class_linker, Descriptor, Name, Signature); \
2417*795d594fSAndroid Build Coastguard Worker jni_handlers_.insert(std::make_pair(method, & UnstartedRuntime::UnstartedJNI ## ShortName)); \
2418*795d594fSAndroid Build Coastguard Worker }
2419*795d594fSAndroid Build Coastguard Worker UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
2420*795d594fSAndroid Build Coastguard Worker #undef UNSTARTED_JNI
2421*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(jni_handlers_.NumBuckets(), kJniHandlersBufferSize);
2422*795d594fSAndroid Build Coastguard Worker }
2423*795d594fSAndroid Build Coastguard Worker
Initialize()2424*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::Initialize() {
2425*795d594fSAndroid Build Coastguard Worker CHECK(!tables_initialized_);
2426*795d594fSAndroid Build Coastguard Worker
2427*795d594fSAndroid Build Coastguard Worker ScopedObjectAccess soa(Thread::Current());
2428*795d594fSAndroid Build Coastguard Worker InitializeInvokeHandlers(soa.Self());
2429*795d594fSAndroid Build Coastguard Worker InitializeJNIHandlers(soa.Self());
2430*795d594fSAndroid Build Coastguard Worker
2431*795d594fSAndroid Build Coastguard Worker tables_initialized_ = true;
2432*795d594fSAndroid Build Coastguard Worker }
2433*795d594fSAndroid Build Coastguard Worker
Reinitialize()2434*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::Reinitialize() {
2435*795d594fSAndroid Build Coastguard Worker CHECK(tables_initialized_);
2436*795d594fSAndroid Build Coastguard Worker
2437*795d594fSAndroid Build Coastguard Worker // Note: HashSet::clear() abandons the pre-allocated storage which we need to keep.
2438*795d594fSAndroid Build Coastguard Worker while (!invoke_handlers_.empty()) {
2439*795d594fSAndroid Build Coastguard Worker invoke_handlers_.erase(invoke_handlers_.begin());
2440*795d594fSAndroid Build Coastguard Worker }
2441*795d594fSAndroid Build Coastguard Worker while (!jni_handlers_.empty()) {
2442*795d594fSAndroid Build Coastguard Worker jni_handlers_.erase(jni_handlers_.begin());
2443*795d594fSAndroid Build Coastguard Worker }
2444*795d594fSAndroid Build Coastguard Worker
2445*795d594fSAndroid Build Coastguard Worker tables_initialized_ = false;
2446*795d594fSAndroid Build Coastguard Worker Initialize();
2447*795d594fSAndroid Build Coastguard Worker }
2448*795d594fSAndroid Build Coastguard Worker
Invoke(Thread * self,const CodeItemDataAccessor & accessor,ShadowFrame * shadow_frame,JValue * result,size_t arg_offset)2449*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::Invoke(Thread* self, const CodeItemDataAccessor& accessor,
2450*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
2451*795d594fSAndroid Build Coastguard Worker // In a runtime that's not started we intercept certain methods to avoid complicated dependency
2452*795d594fSAndroid Build Coastguard Worker // problems in core libraries.
2453*795d594fSAndroid Build Coastguard Worker CHECK(tables_initialized_);
2454*795d594fSAndroid Build Coastguard Worker
2455*795d594fSAndroid Build Coastguard Worker const auto& iter = invoke_handlers_.find(shadow_frame->GetMethod());
2456*795d594fSAndroid Build Coastguard Worker if (iter != invoke_handlers_.end()) {
2457*795d594fSAndroid Build Coastguard Worker // Note: When we special case the method, we do not ensure initialization.
2458*795d594fSAndroid Build Coastguard Worker // This has been the behavior since implementation of this feature.
2459*795d594fSAndroid Build Coastguard Worker
2460*795d594fSAndroid Build Coastguard Worker // Clear out the result in case it's not zeroed out.
2461*795d594fSAndroid Build Coastguard Worker result->SetL(nullptr);
2462*795d594fSAndroid Build Coastguard Worker
2463*795d594fSAndroid Build Coastguard Worker // Push the shadow frame. This is so the failing method can be seen in abort dumps.
2464*795d594fSAndroid Build Coastguard Worker self->PushShadowFrame(shadow_frame);
2465*795d594fSAndroid Build Coastguard Worker
2466*795d594fSAndroid Build Coastguard Worker (*iter->second)(self, shadow_frame, result, arg_offset);
2467*795d594fSAndroid Build Coastguard Worker
2468*795d594fSAndroid Build Coastguard Worker self->PopShadowFrame();
2469*795d594fSAndroid Build Coastguard Worker } else {
2470*795d594fSAndroid Build Coastguard Worker if (!EnsureInitialized(self, shadow_frame)) {
2471*795d594fSAndroid Build Coastguard Worker return;
2472*795d594fSAndroid Build Coastguard Worker }
2473*795d594fSAndroid Build Coastguard Worker // Not special, continue with regular interpreter execution.
2474*795d594fSAndroid Build Coastguard Worker ArtInterpreterToInterpreterBridge(self, accessor, shadow_frame, result);
2475*795d594fSAndroid Build Coastguard Worker }
2476*795d594fSAndroid Build Coastguard Worker }
2477*795d594fSAndroid Build Coastguard Worker
2478*795d594fSAndroid Build Coastguard Worker // 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)2479*795d594fSAndroid Build Coastguard Worker void UnstartedRuntime::Jni(Thread* self, ArtMethod* method, mirror::Object* receiver,
2480*795d594fSAndroid Build Coastguard Worker uint32_t* args, JValue* result) {
2481*795d594fSAndroid Build Coastguard Worker const auto& iter = jni_handlers_.find(method);
2482*795d594fSAndroid Build Coastguard Worker if (iter != jni_handlers_.end()) {
2483*795d594fSAndroid Build Coastguard Worker // Clear out the result in case it's not zeroed out.
2484*795d594fSAndroid Build Coastguard Worker result->SetL(nullptr);
2485*795d594fSAndroid Build Coastguard Worker (*iter->second)(self, method, receiver, args, result);
2486*795d594fSAndroid Build Coastguard Worker } else {
2487*795d594fSAndroid Build Coastguard Worker Runtime* runtime = Runtime::Current();
2488*795d594fSAndroid Build Coastguard Worker if (runtime->IsActiveTransaction()) {
2489*795d594fSAndroid Build Coastguard Worker runtime->GetClassLinker()->AbortTransactionF(
2490*795d594fSAndroid Build Coastguard Worker self,
2491*795d594fSAndroid Build Coastguard Worker "Attempt to invoke native method in non-started runtime: %s",
2492*795d594fSAndroid Build Coastguard Worker ArtMethod::PrettyMethod(method).c_str());
2493*795d594fSAndroid Build Coastguard Worker } else {
2494*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Calling native method " << ArtMethod::PrettyMethod(method)
2495*795d594fSAndroid Build Coastguard Worker << " in an unstarted non-transactional runtime";
2496*795d594fSAndroid Build Coastguard Worker }
2497*795d594fSAndroid Build Coastguard Worker }
2498*795d594fSAndroid Build Coastguard Worker }
2499*795d594fSAndroid Build Coastguard Worker
2500*795d594fSAndroid Build Coastguard Worker } // namespace interpreter
2501*795d594fSAndroid Build Coastguard Worker } // namespace art
2502