unstarted_runtime_test.cc revision 85a098af5fc8d2dd0e39d61c9f93fc6257d631c5
1799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe/* 2799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * Copyright (C) 2015 The Android Open Source Project 3799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * 4799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * Licensed under the Apache License, Version 2.0 (the "License"); 5799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * you may not use this file except in compliance with the License. 6799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * You may obtain a copy of the License at 7799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * 8799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * http://www.apache.org/licenses/LICENSE-2.0 9799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * 10799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * Unless required by applicable law or agreed to in writing, software 11799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * distributed under the License is distributed on an "AS IS" BASIS, 12799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * See the License for the specific language governing permissions and 14799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * limitations under the License. 15799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe */ 16799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 17799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime.h" 18799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 19799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "class_linker.h" 20799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "common_runtime_test.h" 21400ce0087ed0a41f385b55d555afc4616166965aJeff Hao#include "dex_instruction.h" 22799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle.h" 23799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle_scope-inl.h" 24400ce0087ed0a41f385b55d555afc4616166965aJeff Hao#include "interpreter/interpreter_common.h" 25799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/class_loader.h" 26799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/string-inl.h" 27799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "runtime.h" 28799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "scoped_thread_state_change.h" 29799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "thread.h" 30799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 31799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace art { 32799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace interpreter { 33799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 34799681b176ad25437ce2849639f54f610dcbf684Andreas Gampeclass UnstartedRuntimeTest : public CommonRuntimeTest { 35799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe protected: 36799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Re-expose all UnstartedRuntime implementations so we don't need to declare a million 37799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // test friends. 38799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 39799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Methods that intercept available libcore implementations. 40799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#define UNSTARTED_DIRECT(Name, SigIgnored) \ 41799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe static void Unstarted ## Name(Thread* self, \ 42799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* shadow_frame, \ 43799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue* result, \ 44799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe size_t arg_offset) \ 4590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 46799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \ 47799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 48799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h" 49799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT) 50799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST 51799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST 52799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_DIRECT 53799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 54799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Methods that are native. 55e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#define UNSTARTED_JNI(Name, SigIgnored) \ 56799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe static void UnstartedJNI ## Name(Thread* self, \ 57e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method, \ 58799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::Object* receiver, \ 59799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe uint32_t* args, \ 60799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue* result) \ 6190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 62799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \ 63799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 64799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h" 65799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI) 66799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST 67799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST 68799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_JNI 6985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 7085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Helpers for ArrayCopy. 7185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // 7285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size 7385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // of three everywhere. That is enough to test all cases. 7485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 7585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe static mirror::ObjectArray<mirror::Object>* CreateObjectArray( 7685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Thread* self, 7785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::Class* component_type, 7885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& data) 7985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe SHARED_REQUIRES(Locks::mutator_lock_) { 8085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Runtime* runtime = Runtime::Current(); 8185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::Class* array_type = runtime->GetClassLinker()->FindArrayClass(self, &component_type); 8285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK(array_type != nullptr); 8385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>* result = 8485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3); 8585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK(result != nullptr); 8685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe for (size_t i = 0; i < 3; ++i) { 8785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe result->Set(static_cast<int32_t>(i), data.GetReference(i)); 8885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK(!self->IsExceptionPending()); 8985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 9085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe return result; 9185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 9285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 9385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array, 9485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& data) 9585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe SHARED_REQUIRES(Locks::mutator_lock_) { 9685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK_EQ(array->GetLength(), 3); 9785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK_EQ(data.NumberOfReferences(), 3U); 9885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe for (size_t i = 0; i < 3; ++i) { 9985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i; 10085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 10185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 10285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 10385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe void RunArrayCopy(Thread* self, 10485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp, 10585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe bool expect_exception, 10685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>* src, 10785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t src_pos, 10885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>* dst, 10985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t dst_pos, 11085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t length) 11185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe SHARED_REQUIRES(Locks::mutator_lock_) { 11285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe JValue result; 11385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVRegReference(0, src); 11485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVReg(1, src_pos); 11585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVRegReference(2, dst); 11685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVReg(3, dst_pos); 11785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVReg(4, length); 11885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe UnstartedSystemArraycopy(self, tmp, &result, 0); 11985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe bool exception_pending = self->IsExceptionPending(); 12085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe EXPECT_EQ(exception_pending, expect_exception); 12185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe if (exception_pending) { 12285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe self->ClearException(); 12385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 12485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 12585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 12685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe void RunArrayCopy(Thread* self, 12785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp, 12885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe bool expect_exception, 12985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::Class* src_component_class, 13085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::Class* dst_component_class, 13185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& src_data, 13285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t src_pos, 13385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& dst_data, 13485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t dst_pos, 13585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t length, 13685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& expected_result) 13785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe SHARED_REQUIRES(Locks::mutator_lock_) { 13885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_misc(self); 13985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class)); 14085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 14185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::ObjectArray<mirror::Object>> src_handle( 14285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data))); 14385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 14485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::ObjectArray<mirror::Object>> dst_handle( 14585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data))); 14685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 14785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 14885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 14985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe expect_exception, 15085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe src_handle.Get(), 15185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe src_pos, 15285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe dst_handle.Get(), 15385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe dst_pos, 15485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe length); 15585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CheckObjectArray(dst_handle.Get(), expected_result); 15685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 157799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}; 158799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 159799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekByte) { 160799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 161799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 162799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 163799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 164799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 165799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 166799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 167799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 168799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 169799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 170799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < kBaseLen; ++i) { 171799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 172799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 173799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekByte(self, tmp, &result, 0); 174799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 175799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i])); 176799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 177799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 178799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 179799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 180799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 181799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekShort) { 182799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 183799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 184799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 185799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 186799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 187799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 188799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 189799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 190799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 191799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 192799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t adjusted_length = kBaseLen - sizeof(int16_t); 193799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < adjusted_length; ++i) { 194799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 195799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 196799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekShort(self, tmp, &result, 0); 197799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 198799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe typedef int16_t unaligned_short __attribute__ ((aligned (1))); 199799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i); 200799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetS(), *short_ptr); 201799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 202799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 203799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 204799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 205799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 206799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekInt) { 207799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 208799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 209799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 210799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 211799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 212799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 213799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 214799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 215799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 216799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 217799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t adjusted_length = kBaseLen - sizeof(int32_t); 218799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < adjusted_length; ++i) { 219799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 220799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 221799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekInt(self, tmp, &result, 0); 222799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 223799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe typedef int32_t unaligned_int __attribute__ ((aligned (1))); 224799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i); 225799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetI(), *int_ptr); 226799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 227799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 228799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 229799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 230799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 231799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekLong) { 232799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 233799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 234799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 235799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 236799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 237799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 238799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 239799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 240799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 241799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 242799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t adjusted_length = kBaseLen - sizeof(int64_t); 243799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < adjusted_length; ++i) { 244799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 245799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 246799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekLong(self, tmp, &result, 0); 247799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 248799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe typedef int64_t unaligned_long __attribute__ ((aligned (1))); 249799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i); 250799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetJ(), *long_ptr); 251799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 252799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 253799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 254799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 255799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 256799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) { 257799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 258799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 259799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 260799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe StackHandleScope<2> hs(self); 261799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // TODO: Actual UTF. 262799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const char base_string[] = "abcdefghijklmnop"; 263799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Handle<mirror::String> h_test_string(hs.NewHandle( 264799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::String::AllocFromModifiedUtf8(self, base_string))); 265799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1; 266799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Handle<mirror::CharArray> h_char_array(hs.NewHandle( 267799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::CharArray::Alloc(self, kBaseLen))); 268799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // A buffer so we can make sure we only modify the elements targetted. 269799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe uint16_t buf[kBaseLen]; 270799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 271799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 272799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 273799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 274799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) { 275799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t count = 0; count <= kBaseLen; ++count) { 276799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) { 277799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Only do it when in bounds. 278799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) { 279799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegReference(0, h_test_string.Get()); 280799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(1, start_index); 281799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(2, count); 282799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegReference(3, h_char_array.Get()); 283799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(3, trg_offset); 284799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 285799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Copy the char_array into buf. 286799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t)); 287799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 288799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedStringCharAt(self, tmp, &result, 0); 289799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 290799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe uint16_t* data = h_char_array->GetData(); 291799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 292799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe bool success = true; 293799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 294799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // First segment should be unchanged. 295799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < trg_offset; ++i) { 296799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe success = success && (data[i] == buf[i]); 297799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 298799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Second segment should be a copy. 299799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = trg_offset; i < trg_offset + count; ++i) { 300799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe success = success && (data[i] == buf[i - trg_offset + start_index]); 301799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 302799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Third segment should be unchanged. 303799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = trg_offset + count; i < kBaseLen; ++i) { 304799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe success = success && (data[i] == buf[i]); 305799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 306799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 307799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_TRUE(success); 308799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 309799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 310799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 311799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 312799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 313799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 314799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 315799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 316799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringCharAt) { 317799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 318799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 319799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 320799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // TODO: Actual UTF. 321799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const char* base_string = "abcdefghijklmnop"; 322799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t base_len = static_cast<int32_t>(strlen(base_string)); 323799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::String* test_string = mirror::String::AllocFromModifiedUtf8(self, base_string); 324799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 325799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 326799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 327799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 328799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < base_len; ++i) { 329799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegReference(0, test_string); 330799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(1, i); 331799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 332799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedStringCharAt(self, tmp, &result, 0); 333799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 334799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetI(), base_string[i]); 335799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 336799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 337799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 338799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 339799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 340400ce0087ed0a41f385b55d555afc4616166965aJeff HaoTEST_F(UnstartedRuntimeTest, StringInit) { 341400ce0087ed0a41f385b55d555afc4616166965aJeff Hao Thread* self = Thread::Current(); 342400ce0087ed0a41f385b55d555afc4616166965aJeff Hao ScopedObjectAccess soa(self); 343400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::Class* klass = mirror::String::GetJavaLangString(); 344e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method = klass->FindDeclaredDirectMethod("<init>", "(Ljava/lang/String;)V", 345e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier sizeof(void*)); 346400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 347400ce0087ed0a41f385b55d555afc4616166965aJeff Hao // create instruction data for invoke-direct {v0, v1} of method with fake index 348400ce0087ed0a41f385b55d555afc4616166965aJeff Hao uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 }; 349400ce0087ed0a41f385b55d555afc4616166965aJeff Hao const Instruction* inst = Instruction::At(inst_data); 350400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 351400ce0087ed0a41f385b55d555afc4616166965aJeff Hao JValue result; 352400ce0087ed0a41f385b55d555afc4616166965aJeff Hao ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0); 353400ce0087ed0a41f385b55d555afc4616166965aJeff Hao const char* base_string = "hello_world"; 354400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string); 355400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, ""); 356400ce0087ed0a41f385b55d555afc4616166965aJeff Hao shadow_frame->SetVRegReference(0, reference_empty_string); 357400ce0087ed0a41f385b55d555afc4616166965aJeff Hao shadow_frame->SetVRegReference(1, string_arg); 358400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 359400ce0087ed0a41f385b55d555afc4616166965aJeff Hao interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result); 360400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL()); 361400ce0087ed0a41f385b55d555afc4616166965aJeff Hao EXPECT_EQ(string_arg->GetLength(), string_result->GetLength()); 362400ce0087ed0a41f385b55d555afc4616166965aJeff Hao EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(), 363400ce0087ed0a41f385b55d555afc4616166965aJeff Hao string_arg->GetLength() * sizeof(uint16_t)), 0); 364400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 365400ce0087ed0a41f385b55d555afc4616166965aJeff Hao ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 366400ce0087ed0a41f385b55d555afc4616166965aJeff Hao} 367400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 36885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// Tests the exceptions that should be checked before modifying the destination. 36985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// (Doesn't check the object vs primitive case ATM.) 37085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) { 37185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Thread* self = Thread::Current(); 37285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ScopedObjectAccess soa(self); 37385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe JValue result; 37485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 37585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 37685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we 37785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // allocate. 37885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<2> hs_misc(self); 37985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::Class> object_class( 38085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 38185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 38285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_data(self); 38385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 38485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 38585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 38685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 38785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::ObjectArray<mirror::Object>> array( 38885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data))); 38985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 39085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0); 39185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0); 39285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1); 39385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4); 39485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3); 39585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3); 39685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 39785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>* class_as_array = 39885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()); 39985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0); 40085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0); 40185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 40285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 40385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe} 40485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 40585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) { 40685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Thread* self = Thread::Current(); 40785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ScopedObjectAccess soa(self); 40885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe JValue result; 40985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 41085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 41185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<1> hs_object(self); 41285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::Class> object_class( 41385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 41485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 41585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Simple test: 41685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6] 41785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe { 41885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_src(self); 41985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 42085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 42185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 42285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 42385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_dst(self); 42485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 42585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 42685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 42785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 42885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_expected(self); 42985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(0)); 43085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(1)); 43185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_src.GetReference(1)); 43285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 43385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 43485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 43585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe false, 43685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 43785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 43885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src, 43985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 44085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst, 44185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 2, 44285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 44385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected); 44485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 44585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 44685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Simple test: 44785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[]) 44885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe { 44985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_src(self); 45085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 45185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 45285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 45385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 45485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_dst(self); 45585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 45685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 45785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 45885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 45985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_expected(self); 46085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(0)); 46185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_src.GetReference(1)); 46285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(2)); 46385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 46485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 46585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 46685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe false, 46785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 46885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::String::GetJavaLangString(), 46985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src, 47085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 47185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst, 47285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 47385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 47485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected); 47585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 47685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 47785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Simple test: 47885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // [1,*,3] into [4,5,6] = [1,5,6] + exc 47985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe { 48085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_src(self); 48185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 48285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::GetJavaLangString()); 48385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 48485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 48585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_dst(self); 48685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 48785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 48885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 48985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 49085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_expected(self); 49185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_src.GetReference(0)); 49285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(1)); 49385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(2)); 49485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 49585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 49685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 49785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe true, 49885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 49985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::String::GetJavaLangString(), 50085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src, 50185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 0, 50285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst, 50385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 0, 50485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 3, 50585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected); 50685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 50785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 50885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 50985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe} 51085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 511799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} // namespace interpreter 512799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} // namespace art 513