1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2024 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 #ifndef ART_RUNTIME_INTERPRETER_UNSTARTED_RUNTIME_TEST_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_INTERPRETER_UNSTARTED_RUNTIME_TEST_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "unstarted_runtime.h" 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include <memory> 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker #include "class_linker-inl.h" 25*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h" 26*795d594fSAndroid Build Coastguard Worker #include "handle.h" 27*795d594fSAndroid Build Coastguard Worker #include "handle_scope-inl.h" 28*795d594fSAndroid Build Coastguard Worker #include "interpreter_common.h" 29*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-alloc-inl.h" 30*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-inl.h" 31*795d594fSAndroid Build Coastguard Worker #include "shadow_frame-inl.h" 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 34*795d594fSAndroid Build Coastguard Worker namespace interpreter { 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker // Deleter to be used with ShadowFrame::CreateDeoptimizedFrame objects. 37*795d594fSAndroid Build Coastguard Worker struct DeoptShadowFrameDelete { 38*795d594fSAndroid Build Coastguard Worker // NOTE: Deleting a const object is valid but free() takes a non-const pointer. operatorDeoptShadowFrameDelete39*795d594fSAndroid Build Coastguard Worker void operator()(ShadowFrame* ptr) const { 40*795d594fSAndroid Build Coastguard Worker ShadowFrame::DeleteDeoptimizedFrame(ptr); 41*795d594fSAndroid Build Coastguard Worker } 42*795d594fSAndroid Build Coastguard Worker }; 43*795d594fSAndroid Build Coastguard Worker // Alias for std::unique_ptr<> that uses the above deleter. 44*795d594fSAndroid Build Coastguard Worker using UniqueDeoptShadowFramePtr = std::unique_ptr<ShadowFrame, DeoptShadowFrameDelete>; 45*795d594fSAndroid Build Coastguard Worker 46*795d594fSAndroid Build Coastguard Worker class UnstartedRuntimeTestBase : public CommonRuntimeTest { 47*795d594fSAndroid Build Coastguard Worker protected: 48*795d594fSAndroid Build Coastguard Worker // Re-expose all UnstartedRuntime implementations so we don't need to declare a million 49*795d594fSAndroid Build Coastguard Worker // test friends. 50*795d594fSAndroid Build Coastguard Worker 51*795d594fSAndroid Build Coastguard Worker // Methods that intercept available libcore implementations. 52*795d594fSAndroid Build Coastguard Worker #define UNSTARTED_DIRECT(Name, DescriptorIgnored, NameIgnored, SignatureIgnored) \ 53*795d594fSAndroid Build Coastguard Worker static void Unstarted ## Name(Thread* self, \ 54*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame, \ 55*795d594fSAndroid Build Coastguard Worker JValue* result, \ 56*795d594fSAndroid Build Coastguard Worker size_t arg_offset) \ 57*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { \ 58*795d594fSAndroid Build Coastguard Worker interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \ 59*795d594fSAndroid Build Coastguard Worker } UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)60*795d594fSAndroid Build Coastguard Worker UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT) 61*795d594fSAndroid Build Coastguard Worker #undef UNSTARTED_DIRECT 62*795d594fSAndroid Build Coastguard Worker 63*795d594fSAndroid Build Coastguard Worker // Methods that are native. 64*795d594fSAndroid Build Coastguard Worker #define UNSTARTED_JNI(Name, DescriptorIgnored, NameIgnored, SignatureIgnored) \ 65*795d594fSAndroid Build Coastguard Worker static void UnstartedJNI ## Name(Thread* self, \ 66*795d594fSAndroid Build Coastguard Worker ArtMethod* method, \ 67*795d594fSAndroid Build Coastguard Worker mirror::Object* receiver, \ 68*795d594fSAndroid Build Coastguard Worker uint32_t* args, \ 69*795d594fSAndroid Build Coastguard Worker JValue* result) \ 70*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { \ 71*795d594fSAndroid Build Coastguard Worker interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \ 72*795d594fSAndroid Build Coastguard Worker } 73*795d594fSAndroid Build Coastguard Worker UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI) 74*795d594fSAndroid Build Coastguard Worker #undef UNSTARTED_JNI 75*795d594fSAndroid Build Coastguard Worker 76*795d594fSAndroid Build Coastguard Worker UniqueDeoptShadowFramePtr CreateShadowFrame(uint32_t num_vregs, 77*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 78*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc) { 79*795d594fSAndroid Build Coastguard Worker return UniqueDeoptShadowFramePtr( 80*795d594fSAndroid Build Coastguard Worker ShadowFrame::CreateDeoptimizedFrame(num_vregs, method, dex_pc)); 81*795d594fSAndroid Build Coastguard Worker } 82*795d594fSAndroid Build Coastguard Worker GetBootClassLoader()83*795d594fSAndroid Build Coastguard Worker mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) { 84*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current(); 85*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self); 86*795d594fSAndroid Build Coastguard Worker 87*795d594fSAndroid Build Coastguard Worker // Create the fake boot classloader. Any instance is fine, they are technically interchangeable. 88*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> boot_cp_class = hs.NewHandle( 89*795d594fSAndroid Build Coastguard Worker FindClass("Ljava/lang/BootClassLoader;", ScopedNullHandle<mirror::ClassLoader>())); 90*795d594fSAndroid Build Coastguard Worker CHECK(boot_cp_class != nullptr); 91*795d594fSAndroid Build Coastguard Worker CHECK(class_linker_->EnsureInitialized( 92*795d594fSAndroid Build Coastguard Worker self, boot_cp_class, /*can_init_fields=*/ true, /*can_init_parents=*/ true)); 93*795d594fSAndroid Build Coastguard Worker 94*795d594fSAndroid Build Coastguard Worker Handle<mirror::ClassLoader> boot_cp = 95*795d594fSAndroid Build Coastguard Worker hs.NewHandle(boot_cp_class->AllocObject(self)->AsClassLoader()); 96*795d594fSAndroid Build Coastguard Worker CHECK(boot_cp != nullptr); 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Worker ArtMethod* boot_cp_init = 99*795d594fSAndroid Build Coastguard Worker boot_cp_class->FindConstructor("()V", class_linker_->GetImagePointerSize()); 100*795d594fSAndroid Build Coastguard Worker CHECK(boot_cp_init != nullptr); 101*795d594fSAndroid Build Coastguard Worker 102*795d594fSAndroid Build Coastguard Worker JValue result; 103*795d594fSAndroid Build Coastguard Worker UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, boot_cp_init, 0); 104*795d594fSAndroid Build Coastguard Worker shadow_frame->SetVRegReference(0, boot_cp.Get()); 105*795d594fSAndroid Build Coastguard Worker 106*795d594fSAndroid Build Coastguard Worker // create instruction data for invoke-direct {v0} of method with fake index 107*795d594fSAndroid Build Coastguard Worker uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 }; 108*795d594fSAndroid Build Coastguard Worker 109*795d594fSAndroid Build Coastguard Worker interpreter::DoCall<false>(boot_cp_init, 110*795d594fSAndroid Build Coastguard Worker self, 111*795d594fSAndroid Build Coastguard Worker *shadow_frame, 112*795d594fSAndroid Build Coastguard Worker Instruction::At(inst_data), 113*795d594fSAndroid Build Coastguard Worker inst_data[0], 114*795d594fSAndroid Build Coastguard Worker /* string_init= */ false, 115*795d594fSAndroid Build Coastguard Worker &result); 116*795d594fSAndroid Build Coastguard Worker CHECK(!self->IsExceptionPending()); 117*795d594fSAndroid Build Coastguard Worker 118*795d594fSAndroid Build Coastguard Worker return boot_cp.Get(); 119*795d594fSAndroid Build Coastguard Worker } 120*795d594fSAndroid Build Coastguard Worker }; 121*795d594fSAndroid Build Coastguard Worker 122*795d594fSAndroid Build Coastguard Worker } // namespace interpreter 123*795d594fSAndroid Build Coastguard Worker } // namespace art 124*795d594fSAndroid Build Coastguard Worker 125*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_INTERPRETER_UNSTARTED_RUNTIME_TEST_H_ 126