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 1989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe#include <limits> 208ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe#include <locale> 2189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 2289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe#include "base/casts.h" 23542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe#include "base/enums.h" 24b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe#include "base/memory_tool.h" 25799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "class_linker.h" 26799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "common_runtime_test.h" 27b2ec9f5c128673c43f776cbe12c8eeb0a6884ebbDavid Sehr#include "dex/descriptors_names.h" 289e734c7ab4599d7747a05db0dc73c7b668cb6683David Sehr#include "dex/dex_instruction.h" 29799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle.h" 30799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle_scope-inl.h" 31400ce0087ed0a41f385b55d555afc4616166965aJeff Hao#include "interpreter/interpreter_common.h" 32799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/class_loader.h" 339486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe#include "mirror/object-inl.h" 348cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe#include "mirror/object_array-inl.h" 35799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/string-inl.h" 36799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "runtime.h" 370795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_thread_state_change-inl.h" 38799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "thread.h" 398ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe#include "transaction.h" 40799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 41799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace art { 42799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace interpreter { 43799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 44799681b176ad25437ce2849639f54f610dcbf684Andreas Gampeclass UnstartedRuntimeTest : public CommonRuntimeTest { 45799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe protected: 46799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Re-expose all UnstartedRuntime implementations so we don't need to declare a million 47799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // test friends. 48799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 49799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Methods that intercept available libcore implementations. 50799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#define UNSTARTED_DIRECT(Name, SigIgnored) \ 51799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe static void Unstarted ## Name(Thread* self, \ 52799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* shadow_frame, \ 53799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue* result, \ 54799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe size_t arg_offset) \ 55bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { \ 56799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \ 57799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 58799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h" 59799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT) 60799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST 61799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST 62799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_DIRECT 63799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 64799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Methods that are native. 65e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#define UNSTARTED_JNI(Name, SigIgnored) \ 66799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe static void UnstartedJNI ## Name(Thread* self, \ 67e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method, \ 68799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::Object* receiver, \ 69799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe uint32_t* args, \ 70799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue* result) \ 71bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { \ 72799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \ 73799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 74799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h" 75799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI) 76799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST 77799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST 78799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_JNI 7985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 8085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Helpers for ArrayCopy. 8185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // 8285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size 8385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // of three everywhere. That is enough to test all cases. 8485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 8585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe static mirror::ObjectArray<mirror::Object>* CreateObjectArray( 8685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Thread* self, 87bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier ObjPtr<mirror::Class> component_type, 8885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& data) 89bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 9085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Runtime* runtime = Runtime::Current(); 91bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier ObjPtr<mirror::Class> array_type = 92bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier runtime->GetClassLinker()->FindArrayClass(self, &component_type); 9385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK(array_type != nullptr); 94bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier ObjPtr<mirror::ObjectArray<mirror::Object>> result = 9585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3); 9685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK(result != nullptr); 9785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe for (size_t i = 0; i < 3; ++i) { 9885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe result->Set(static_cast<int32_t>(i), data.GetReference(i)); 9985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK(!self->IsExceptionPending()); 10085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 101bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier return result.Ptr(); 10285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 10385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 10485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array, 10585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& data) 106bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 10785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK_EQ(array->GetLength(), 3); 10885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK_EQ(data.NumberOfReferences(), 3U); 10985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe for (size_t i = 0; i < 3; ++i) { 11085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i; 11185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 11285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 11385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 11485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe void RunArrayCopy(Thread* self, 11585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp, 11685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe bool expect_exception, 11785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>* src, 11885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t src_pos, 11985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>* dst, 12085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t dst_pos, 12185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t length) 122bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 12385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe JValue result; 12485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVRegReference(0, src); 12585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVReg(1, src_pos); 12685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVRegReference(2, dst); 12785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVReg(3, dst_pos); 12885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVReg(4, length); 12985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe UnstartedSystemArraycopy(self, tmp, &result, 0); 13085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe bool exception_pending = self->IsExceptionPending(); 13185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe EXPECT_EQ(exception_pending, expect_exception); 13285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe if (exception_pending) { 13385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe self->ClearException(); 13485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 13585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 13685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 13785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe void RunArrayCopy(Thread* self, 13885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp, 13985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe bool expect_exception, 14085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::Class* src_component_class, 14185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::Class* dst_component_class, 14285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& src_data, 14385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t src_pos, 14485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& dst_data, 14585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t dst_pos, 14685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t length, 14785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& expected_result) 148bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 14985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_misc(self); 15085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class)); 15185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 15285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::ObjectArray<mirror::Object>> src_handle( 15385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data))); 15485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 15585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::ObjectArray<mirror::Object>> dst_handle( 15685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data))); 15785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 15885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 15985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 16085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe expect_exception, 16185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe src_handle.Get(), 16285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe src_pos, 16385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe dst_handle.Get(), 16485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe dst_pos, 16585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe length); 16685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CheckObjectArray(dst_handle.Get(), expected_result); 16785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 16889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 16989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe void TestCeilFloor(bool ceil, 17089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe Thread* self, 17189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ShadowFrame* tmp, 17289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe double const test_pairs[][2], 17389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe size_t num_pairs) 174bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 17589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe for (size_t i = 0; i < num_pairs; ++i) { 17689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe tmp->SetVRegDouble(0, test_pairs[i][0]); 17789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 17889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe JValue result; 17989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe if (ceil) { 18089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe UnstartedMathCeil(self, tmp, &result, 0); 18189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe } else { 18289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe UnstartedMathFloor(self, tmp, &result, 0); 18389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe } 18489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 18589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 18689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 18789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe // We want precise results. 18889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe int64_t result_int64t = bit_cast<int64_t, double>(result.GetD()); 18989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]); 19089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1]; 19189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe } 19289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe } 1938ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe 1948ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe // Prepare for aborts. Aborts assume that the exception class is already resolved, as the 1958ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe // loading code doesn't work under transactions. 196bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) { 1978ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe mirror::Object* result = Runtime::Current()->GetClassLinker()->FindClass( 1988ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe Thread::Current(), 1998ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe Transaction::kAbortExceptionSignature, 2008ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe ScopedNullHandle<mirror::ClassLoader>()); 2018ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe CHECK(result != nullptr); 2028ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 203799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}; 204799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 205799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekByte) { 206799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 207799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 208799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 209799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 210799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 211799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 212799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 213799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 214799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 215799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 216799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < kBaseLen; ++i) { 217799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 218799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 219799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekByte(self, tmp, &result, 0); 220799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 221799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i])); 222799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 223799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 224799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 225799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 226799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 227799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekShort) { 228799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 229799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 230799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 231799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 232799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 233799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 234799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 235799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 236799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 237799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 238799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t adjusted_length = kBaseLen - sizeof(int16_t); 239799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < adjusted_length; ++i) { 240799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 241799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 242799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekShort(self, tmp, &result, 0); 243799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 244799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe typedef int16_t unaligned_short __attribute__ ((aligned (1))); 245799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i); 246799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetS(), *short_ptr); 247799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 248799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 249799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 250799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 251799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 252799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekInt) { 253799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 254799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 255799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 256799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 257799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 258799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 259799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 260799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 261799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 262799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 263799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t adjusted_length = kBaseLen - sizeof(int32_t); 264799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < adjusted_length; ++i) { 265799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 266799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 267799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekInt(self, tmp, &result, 0); 268799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 269799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe typedef int32_t unaligned_int __attribute__ ((aligned (1))); 270799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i); 271799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetI(), *int_ptr); 272799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 273799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 274799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 275799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 276799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 277799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekLong) { 278799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 279799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 280799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 281799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 282799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 283799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 284799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 285799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 286799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 287799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 288799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t adjusted_length = kBaseLen - sizeof(int64_t); 289799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < adjusted_length; ++i) { 290799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 291799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 292799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekLong(self, tmp, &result, 0); 293799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 294799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe typedef int64_t unaligned_long __attribute__ ((aligned (1))); 295799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i); 296799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetJ(), *long_ptr); 297799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 298799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 299799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 300799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 301799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 302799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) { 303799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 304799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 305799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 306799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe StackHandleScope<2> hs(self); 307799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // TODO: Actual UTF. 308799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const char base_string[] = "abcdefghijklmnop"; 309799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Handle<mirror::String> h_test_string(hs.NewHandle( 310799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::String::AllocFromModifiedUtf8(self, base_string))); 311799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1; 312799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Handle<mirror::CharArray> h_char_array(hs.NewHandle( 313799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::CharArray::Alloc(self, kBaseLen))); 314799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // A buffer so we can make sure we only modify the elements targetted. 315799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe uint16_t buf[kBaseLen]; 316799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 317799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 318799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 319799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 320799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) { 321799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t count = 0; count <= kBaseLen; ++count) { 322799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) { 323799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Only do it when in bounds. 324799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) { 325799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegReference(0, h_test_string.Get()); 326799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(1, start_index); 327799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(2, count); 328799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegReference(3, h_char_array.Get()); 329799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(3, trg_offset); 330799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 331799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Copy the char_array into buf. 332799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t)); 333799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 334799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedStringCharAt(self, tmp, &result, 0); 335799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 336799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe uint16_t* data = h_char_array->GetData(); 337799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 338799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe bool success = true; 339799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 340799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // First segment should be unchanged. 341799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < trg_offset; ++i) { 342799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe success = success && (data[i] == buf[i]); 343799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 344799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Second segment should be a copy. 345799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = trg_offset; i < trg_offset + count; ++i) { 346799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe success = success && (data[i] == buf[i - trg_offset + start_index]); 347799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 348799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Third segment should be unchanged. 349799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = trg_offset + count; i < kBaseLen; ++i) { 350799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe success = success && (data[i] == buf[i]); 351799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 352799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 353799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_TRUE(success); 354799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 355799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 356799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 357799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 358799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 359799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 360799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 361799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 362799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringCharAt) { 363799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 364799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 365799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 366799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // TODO: Actual UTF. 367799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const char* base_string = "abcdefghijklmnop"; 368799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t base_len = static_cast<int32_t>(strlen(base_string)); 369799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::String* test_string = mirror::String::AllocFromModifiedUtf8(self, base_string); 370799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 371799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 372799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 373799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 374799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < base_len; ++i) { 375799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegReference(0, test_string); 376799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(1, i); 377799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 378799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedStringCharAt(self, tmp, &result, 0); 379799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 380799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetI(), base_string[i]); 381799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 382799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 383799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 384799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 385799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 386400ce0087ed0a41f385b55d555afc4616166965aJeff HaoTEST_F(UnstartedRuntimeTest, StringInit) { 387400ce0087ed0a41f385b55d555afc4616166965aJeff Hao Thread* self = Thread::Current(); 388400ce0087ed0a41f385b55d555afc4616166965aJeff Hao ScopedObjectAccess soa(self); 389400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::Class* klass = mirror::String::GetJavaLangString(); 390fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing ArtMethod* method = 391ba118827465d12177f3996e50133960087b1c916Vladimir Marko klass->FindConstructor("(Ljava/lang/String;)V", 392ba118827465d12177f3996e50133960087b1c916Vladimir Marko Runtime::Current()->GetClassLinker()->GetImagePointerSize()); 393ba118827465d12177f3996e50133960087b1c916Vladimir Marko ASSERT_TRUE(method != nullptr); 394400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 395400ce0087ed0a41f385b55d555afc4616166965aJeff Hao // create instruction data for invoke-direct {v0, v1} of method with fake index 396400ce0087ed0a41f385b55d555afc4616166965aJeff Hao uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 }; 397400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 398400ce0087ed0a41f385b55d555afc4616166965aJeff Hao JValue result; 399400ce0087ed0a41f385b55d555afc4616166965aJeff Hao ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0); 400400ce0087ed0a41f385b55d555afc4616166965aJeff Hao const char* base_string = "hello_world"; 401400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string); 402400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, ""); 403400ce0087ed0a41f385b55d555afc4616166965aJeff Hao shadow_frame->SetVRegReference(0, reference_empty_string); 404400ce0087ed0a41f385b55d555afc4616166965aJeff Hao shadow_frame->SetVRegReference(1, string_arg); 405400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 4062b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier interpreter::DoCall<false, false>(method, 4072b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier self, 4082b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier *shadow_frame, 4092b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier Instruction::At(inst_data), 4102b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier inst_data[0], 4112b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier &result); 412400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL()); 413400ce0087ed0a41f385b55d555afc4616166965aJeff Hao EXPECT_EQ(string_arg->GetLength(), string_result->GetLength()); 4143aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo 4153aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo if (string_arg->IsCompressed() && string_result->IsCompressed()) { 4163aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(), 4173aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo string_arg->GetLength() * sizeof(uint8_t)), 0); 4183aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) { 4193aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(), 4203aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo string_arg->GetLength() * sizeof(uint16_t)), 0); 4213aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo } else { 4223aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo bool equal = true; 4233aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo for (int i = 0; i < string_arg->GetLength(); ++i) { 4243aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo if (string_arg->CharAt(i) != string_result->CharAt(i)) { 4253aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo equal = false; 4263aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo break; 4273aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo } 4283aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo } 4293aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo EXPECT_EQ(equal, true); 4303aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo } 431400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 432400ce0087ed0a41f385b55d555afc4616166965aJeff Hao ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 433400ce0087ed0a41f385b55d555afc4616166965aJeff Hao} 434400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 43585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// Tests the exceptions that should be checked before modifying the destination. 43685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// (Doesn't check the object vs primitive case ATM.) 43785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) { 43885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Thread* self = Thread::Current(); 43985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ScopedObjectAccess soa(self); 44085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe JValue result; 44185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 44285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 44385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we 44485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // allocate. 44585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<2> hs_misc(self); 44685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::Class> object_class( 44785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 44885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 44985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_data(self); 45085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 45185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 45285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 45385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 45485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::ObjectArray<mirror::Object>> array( 45585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data))); 45685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 45785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0); 45885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0); 45985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1); 46085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4); 46185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3); 46285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3); 46385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 46485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>* class_as_array = 46585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()); 46685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0); 46785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0); 46885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 46985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 47085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe} 47185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 47285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) { 47385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Thread* self = Thread::Current(); 47485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ScopedObjectAccess soa(self); 47585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe JValue result; 47685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 47785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 47885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<1> hs_object(self); 47985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::Class> object_class( 48085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 48185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 48285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Simple test: 48385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6] 48485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe { 48585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_src(self); 48685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 48785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 48885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 48985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 49085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_dst(self); 49185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 49285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 49385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 49485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 49585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_expected(self); 49685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(0)); 49785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(1)); 49885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_src.GetReference(1)); 49985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 50085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 50185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 50285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe false, 50385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 50485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 50585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src, 50685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 50785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst, 50885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 2, 50985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 51085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected); 51185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 51285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 51385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Simple test: 51485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[]) 51585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe { 51685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_src(self); 51785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 51885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 51985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 52085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 52185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_dst(self); 52285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 52385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 52485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 52585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 52685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_expected(self); 52785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(0)); 52885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_src.GetReference(1)); 52985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(2)); 53085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 53185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 53285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 53385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe false, 53485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 53585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::String::GetJavaLangString(), 53685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src, 53785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 53885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst, 53985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 54085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 54185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected); 54285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 54385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 54485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Simple test: 54585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // [1,*,3] into [4,5,6] = [1,5,6] + exc 54685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe { 54785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_src(self); 54885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 54985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::GetJavaLangString()); 55085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 55185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 55285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_dst(self); 55385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 55485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 55585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 55685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 55785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_expected(self); 55885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_src.GetReference(0)); 55985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(1)); 56085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(2)); 56185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 56285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 56385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 56485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe true, 56585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 56685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::String::GetJavaLangString(), 56785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src, 56885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 0, 56985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst, 57085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 0, 57185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 3, 57285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected); 57385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 57485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 57585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 57685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe} 57785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 57813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas GampeTEST_F(UnstartedRuntimeTest, IntegerParseIntTest) { 57913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe Thread* self = Thread::Current(); 58013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ScopedObjectAccess soa(self); 58113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 58213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 58313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 58413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all 58513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe // suffixes). 58613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe constexpr const char* test_string = "-2147483646"; 58713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe constexpr int32_t test_values[] = { 58813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 6, 58913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 46, 59013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 646, 59113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 3646, 59213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 83646, 59313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 483646, 59413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 7483646, 59513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 47483646, 59613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 147483646, 59713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 2147483646, 59813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe -2147483646 59913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe }; 60013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 60113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe static_assert(arraysize(test_values) == 11U, "test_values"); 60213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe CHECK_EQ(strlen(test_string), 11U); 60313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 60413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe for (size_t i = 0; i <= 10; ++i) { 60513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe const char* test_value = &test_string[10 - i]; 60613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 60713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe StackHandleScope<1> hs_str(self); 60813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe Handle<mirror::String> h_str( 60913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value))); 61013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_NE(h_str.Get(), nullptr); 61113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 61213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 61313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe tmp->SetVRegReference(0, h_str.Get()); 61413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 61513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe JValue result; 61613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe UnstartedIntegerParseInt(self, tmp, &result, 0); 61713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 61813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 61913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe EXPECT_EQ(result.GetI(), test_values[i]); 62013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe } 62113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 62213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 62313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe} 62413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 62513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe// Right now the same as Integer.Parse 62613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas GampeTEST_F(UnstartedRuntimeTest, LongParseLongTest) { 62713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe Thread* self = Thread::Current(); 62813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ScopedObjectAccess soa(self); 62913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 63013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 63113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 63213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all 63313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe // suffixes). 63413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe constexpr const char* test_string = "-2147483646"; 63513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe constexpr int64_t test_values[] = { 63613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 6, 63713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 46, 63813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 646, 63913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 3646, 64013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 83646, 64113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 483646, 64213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 7483646, 64313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 47483646, 64413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 147483646, 64513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 2147483646, 64613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe -2147483646 64713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe }; 64813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 64913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe static_assert(arraysize(test_values) == 11U, "test_values"); 65013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe CHECK_EQ(strlen(test_string), 11U); 65113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 65213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe for (size_t i = 0; i <= 10; ++i) { 65313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe const char* test_value = &test_string[10 - i]; 65413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 65513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe StackHandleScope<1> hs_str(self); 65613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe Handle<mirror::String> h_str( 65713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value))); 65813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_NE(h_str.Get(), nullptr); 65913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 66013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 66113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe tmp->SetVRegReference(0, h_str.Get()); 66213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 66313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe JValue result; 66413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe UnstartedLongParseLong(self, tmp, &result, 0); 66513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 66613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 66713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe EXPECT_EQ(result.GetJ(), test_values[i]); 66813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe } 66913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 67013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 67113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe} 67213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 67389e3b486167c58a3268cf963c56183cd7f478b3cAndreas GampeTEST_F(UnstartedRuntimeTest, Ceil) { 67489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe Thread* self = Thread::Current(); 67589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ScopedObjectAccess soa(self); 67689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 67789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 67889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 67989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double nan = std::numeric_limits<double>::quiet_NaN(); 68089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double inf = std::numeric_limits<double>::infinity(); 68189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1); 68289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55); 68389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double test_pairs[][2] = { 68489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -0.0, -0.0 }, 68589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 0.0, 0.0 }, 68689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -0.5, -0.0 }, 68789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -1.0, -1.0 }, 68889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 0.5, 1.0 }, 68989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 1.0, 1.0 }, 69089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { nan, nan }, 69189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { inf, inf }, 69289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -inf, -inf }, 69389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { ld1, ld1 }, 69489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { ld2, ld2 } 69589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe }; 69689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 69789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs)); 69889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 69989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 70089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe} 70189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 70289e3b486167c58a3268cf963c56183cd7f478b3cAndreas GampeTEST_F(UnstartedRuntimeTest, Floor) { 70389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe Thread* self = Thread::Current(); 70489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ScopedObjectAccess soa(self); 70589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 70689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 70789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 70889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double nan = std::numeric_limits<double>::quiet_NaN(); 70989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double inf = std::numeric_limits<double>::infinity(); 71089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1); 71189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55); 71289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double test_pairs[][2] = { 71389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -0.0, -0.0 }, 71489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 0.0, 0.0 }, 71589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -0.5, -1.0 }, 71689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -1.0, -1.0 }, 71789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 0.5, 0.0 }, 71889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 1.0, 1.0 }, 71989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { nan, nan }, 72089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { inf, inf }, 72189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -inf, -inf }, 72289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { ld1, ld1 }, 72389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { ld2, ld2 } 72489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe }; 72589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 72689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe TestCeilFloor(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs)); 72789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 72889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 72989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe} 73089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 7318ce9c30f5d7328579619eb7e26c5f041837984afAndreas GampeTEST_F(UnstartedRuntimeTest, ToLowerUpper) { 7328ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe Thread* self = Thread::Current(); 7338ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe ScopedObjectAccess soa(self); 7348ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe 7358ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 7368ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe 7378ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe std::locale c_locale("C"); 7388ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe 7398ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe // Check ASCII. 7408ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe for (uint32_t i = 0; i < 128; ++i) { 7418ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe bool c_upper = std::isupper(static_cast<char>(i), c_locale); 7428ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe bool c_lower = std::islower(static_cast<char>(i), c_locale); 7438ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe EXPECT_FALSE(c_upper && c_lower) << i; 7448ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe 7458ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe // Check toLowerCase. 7468ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe { 7478ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe JValue result; 7488ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 7498ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe UnstartedCharacterToLowerCase(self, tmp, &result, 0); 7508ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 7518ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe uint32_t lower_result = static_cast<uint32_t>(result.GetI()); 7528ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe if (c_lower) { 7538ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe EXPECT_EQ(i, lower_result); 7548ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } else if (c_upper) { 7558ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)), 7568ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe lower_result); 7578ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } else { 7588ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe EXPECT_EQ(i, lower_result); 7598ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 7608ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 7618ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe 7628ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe // Check toUpperCase. 7638ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe { 7648ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe JValue result2; 7658ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 7668ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe UnstartedCharacterToUpperCase(self, tmp, &result2, 0); 7678ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 7688ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe uint32_t upper_result = static_cast<uint32_t>(result2.GetI()); 7698ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe if (c_upper) { 7708ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe EXPECT_EQ(i, upper_result); 7718ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } else if (c_lower) { 7728ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)), 7738ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe upper_result); 7748ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } else { 7758ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe EXPECT_EQ(i, upper_result); 7768ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 7778ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 7788ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 7798ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe 7808ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe // Check abort for other things. Can't test all. 7818ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe 7828ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe PrepareForAborts(); 7838ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe 7848ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe for (uint32_t i = 128; i < 256; ++i) { 7858ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe { 7868ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe JValue result; 7878ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 78816d1dd86dca33520b44d9802695e19d3b658af3eChang Xing Runtime::Current()->EnterTransactionMode(); 7898ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe UnstartedCharacterToLowerCase(self, tmp, &result, 0); 79016d1dd86dca33520b44d9802695e19d3b658af3eChang Xing ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 7918ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe Runtime::Current()->ExitTransactionMode(); 7928ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe ASSERT_TRUE(self->IsExceptionPending()); 7938ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 7948ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe { 7958ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe JValue result; 7968ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 79716d1dd86dca33520b44d9802695e19d3b658af3eChang Xing Runtime::Current()->EnterTransactionMode(); 7988ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe UnstartedCharacterToUpperCase(self, tmp, &result, 0); 79916d1dd86dca33520b44d9802695e19d3b658af3eChang Xing ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 8008ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe Runtime::Current()->ExitTransactionMode(); 8018ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe ASSERT_TRUE(self->IsExceptionPending()); 8028ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 8038ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 8048ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) { 8058ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe { 8068ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe JValue result; 8078ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 80816d1dd86dca33520b44d9802695e19d3b658af3eChang Xing Runtime::Current()->EnterTransactionMode(); 8098ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe UnstartedCharacterToLowerCase(self, tmp, &result, 0); 81016d1dd86dca33520b44d9802695e19d3b658af3eChang Xing ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 8118ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe Runtime::Current()->ExitTransactionMode(); 8128ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe ASSERT_TRUE(self->IsExceptionPending()); 8138ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 8148ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe { 8158ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe JValue result; 8168ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 81716d1dd86dca33520b44d9802695e19d3b658af3eChang Xing Runtime::Current()->EnterTransactionMode(); 8188ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe UnstartedCharacterToUpperCase(self, tmp, &result, 0); 81916d1dd86dca33520b44d9802695e19d3b658af3eChang Xing ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 8208ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe Runtime::Current()->ExitTransactionMode(); 8218ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe ASSERT_TRUE(self->IsExceptionPending()); 8228ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 8238ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe } 8248ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe 8258ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 8268ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe} 8278ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe 828b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas GampeTEST_F(UnstartedRuntimeTest, Sin) { 829b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe Thread* self = Thread::Current(); 830b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe ScopedObjectAccess soa(self); 831b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 832b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 833b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 834b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe // Test an important value, PI/6. That's the one we see in practice. 835b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365); 836b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(lvalue)); 837b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 838b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe JValue result; 839b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe UnstartedMathSin(self, tmp, &result, 0); 840b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 841b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 842b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult); 843b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 844b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 845b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe} 846b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 847b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas GampeTEST_F(UnstartedRuntimeTest, Cos) { 848b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe Thread* self = Thread::Current(); 849b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe ScopedObjectAccess soa(self); 850b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 851b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 852b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 853b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe // Test an important value, PI/6. That's the one we see in practice. 854b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365); 855b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(lvalue)); 856b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 857b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe JValue result; 858b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe UnstartedMathCos(self, tmp, &result, 0); 859b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 860b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 861b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult); 862b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 863b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 864b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe} 865b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 866b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas GampeTEST_F(UnstartedRuntimeTest, Pow) { 867b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe // Valgrind seems to get this wrong, actually. Disable for valgrind. 868b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) { 869b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe return; 870b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe } 871b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe 872b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe Thread* self = Thread::Current(); 873b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe ScopedObjectAccess soa(self); 874b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 875b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 876b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 877b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe // Test an important pair. 878b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000); 879b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000); 880b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 881b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1)); 882b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2)); 883b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 884b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe JValue result; 885b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe UnstartedMathPow(self, tmp, &result, 0); 886b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 887b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 888b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult); 889b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 890b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 891b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe} 892b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe 893ae78c2643375c7536affcec318a60d13d430f181Andreas GampeTEST_F(UnstartedRuntimeTest, IsAnonymousClass) { 894ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe Thread* self = Thread::Current(); 895ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe ScopedObjectAccess soa(self); 896ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 897ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe JValue result; 898ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 899ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 900ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe mirror::Class* class_klass = mirror::Class::GetJavaLangClass(); 901ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe shadow_frame->SetVRegReference(0, class_klass); 902ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0); 903ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe EXPECT_EQ(result.GetZ(), 0); 904ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 905ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe jobject class_loader = LoadDex("Nested"); 906ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe StackHandleScope<1> hs(soa.Self()); 907ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe Handle<mirror::ClassLoader> loader( 908ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); 909ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe mirror::Class* c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader); 910ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe ASSERT_TRUE(c != nullptr); 911ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe shadow_frame->SetVRegReference(0, c); 912ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0); 913ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe EXPECT_EQ(result.GetZ(), 1); 914ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 915ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 916ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe} 917ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 918ae78c2643375c7536affcec318a60d13d430f181Andreas GampeTEST_F(UnstartedRuntimeTest, GetDeclaringClass) { 919ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe Thread* self = Thread::Current(); 920ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe ScopedObjectAccess soa(self); 921ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 922ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe JValue result; 923ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 924ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 925ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe jobject class_loader = LoadDex("Nested"); 926ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe StackHandleScope<4> hs(self); 927ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe Handle<mirror::ClassLoader> loader( 928ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); 929ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 930ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe Handle<mirror::Class> nested_klass(hs.NewHandle( 931ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe class_linker_->FindClass(soa.Self(), "LNested;", loader))); 932ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe Handle<mirror::Class> inner_klass(hs.NewHandle( 933ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader))); 934ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe Handle<mirror::Class> anon_klass(hs.NewHandle( 935ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe class_linker_->FindClass(soa.Self(), "LNested$1;", loader))); 936ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 937ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe shadow_frame->SetVRegReference(0, nested_klass.Get()); 938ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0); 939ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe EXPECT_EQ(result.GetL(), nullptr); 940ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 941ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe shadow_frame->SetVRegReference(0, inner_klass.Get()); 942ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0); 943ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe EXPECT_EQ(result.GetL(), nested_klass.Get()); 944ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 945ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe shadow_frame->SetVRegReference(0, anon_klass.Get()); 946ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0); 947ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe EXPECT_EQ(result.GetL(), nullptr); 948ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 949ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 950ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe} 951ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe 9523d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas GampeTEST_F(UnstartedRuntimeTest, ThreadLocalGet) { 9533d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe Thread* self = Thread::Current(); 9543d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ScopedObjectAccess soa(self); 9553d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 9563d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe JValue result; 9573d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 9583d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 9593d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe StackHandleScope<1> hs(self); 9603d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 9613d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 9623d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe // Positive test. See that We get something for float conversion. 9633d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe { 9643d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe Handle<mirror::Class> floating_decimal = hs.NewHandle( 9653d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe class_linker->FindClass(self, 9663d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe "Lsun/misc/FloatingDecimal;", 9673d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ScopedNullHandle<mirror::ClassLoader>())); 968fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(floating_decimal != nullptr); 9693d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true)); 9703d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 971ba118827465d12177f3996e50133960087b1c916Vladimir Marko ArtMethod* caller_method = floating_decimal->FindClassMethod( 9723d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe "getBinaryToASCIIBuffer", 9733d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;", 9743d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe class_linker->GetImagePointerSize()); 9753d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail); 9763d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ASSERT_TRUE(caller_method != nullptr); 977ba118827465d12177f3996e50133960087b1c916Vladimir Marko ASSERT_TRUE(caller_method->IsDirect()); 978ba118827465d12177f3996e50133960087b1c916Vladimir Marko ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get()); 9793d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0); 9803d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe shadow_frame->SetLink(caller_frame); 9813d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 9823d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe UnstartedThreadLocalGet(self, shadow_frame, &result, 0); 9833d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe EXPECT_TRUE(result.GetL() != nullptr); 9843d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe EXPECT_FALSE(self->IsExceptionPending()); 9853d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 9863d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(caller_frame); 9873d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe } 9883d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 9893d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe // Negative test. 9903d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe PrepareForAborts(); 9913d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 9923d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe { 9933d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe // Just use a method in Class. 9943d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass(); 9953d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ArtMethod* caller_method = 9963d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin(); 9973d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0); 9983d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe shadow_frame->SetLink(caller_frame); 9993d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 100016d1dd86dca33520b44d9802695e19d3b658af3eChang Xing Runtime::Current()->EnterTransactionMode(); 10013d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe UnstartedThreadLocalGet(self, shadow_frame, &result, 0); 100216d1dd86dca33520b44d9802695e19d3b658af3eChang Xing ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 10033d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe Runtime::Current()->ExitTransactionMode(); 10043d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ASSERT_TRUE(self->IsExceptionPending()); 10053d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe self->ClearException(); 10063d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 10073d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(caller_frame); 10083d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe } 10093d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 10103d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 10113d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe} 10123d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 10133d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas GampeTEST_F(UnstartedRuntimeTest, FloatConversion) { 10143d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe Thread* self = Thread::Current(); 10153d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ScopedObjectAccess soa(self); 10163d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 10173d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe StackHandleScope<1> hs(self); 10183d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 10193d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe Handle<mirror::Class> double_class = hs.NewHandle( 10203d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe class_linker->FindClass(self, 10213d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe "Ljava/lang/Double;", 10223d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ScopedNullHandle<mirror::ClassLoader>())); 1023fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(double_class != nullptr); 10243d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true)); 10253d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 1026ba118827465d12177f3996e50133960087b1c916Vladimir Marko ArtMethod* method = double_class->FindClassMethod("toString", 1027ba118827465d12177f3996e50133960087b1c916Vladimir Marko "(D)Ljava/lang/String;", 1028ba118827465d12177f3996e50133960087b1c916Vladimir Marko class_linker->GetImagePointerSize()); 10293d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ASSERT_TRUE(method != nullptr); 1030ba118827465d12177f3996e50133960087b1c916Vladimir Marko ASSERT_TRUE(method->IsDirect()); 1031ba118827465d12177f3996e50133960087b1c916Vladimir Marko ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get()); 10323d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 10333d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe // create instruction data for invoke-direct {v0, v1} of method with fake index 10343d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 }; 10353d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 10363d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe JValue result; 10373d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0); 10383d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe shadow_frame->SetVRegDouble(0, 1.23); 10392b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier interpreter::DoCall<false, false>(method, 10402b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier self, 10412b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier *shadow_frame, 10422b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier Instruction::At(inst_data), 10432b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier inst_data[0], 10442b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier &result); 10453d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ObjPtr<mirror::String> string_result = reinterpret_cast<mirror::String*>(result.GetL()); 10463d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ASSERT_TRUE(string_result != nullptr); 10473d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 10483d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe std::string mod_utf = string_result->ToModifiedUtf8(); 10493d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe EXPECT_EQ("1.23", mod_utf); 10503d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 10513d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 10523d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe} 10533d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe 1054bad529da18122c7044fbfd7d56153535d34367b1Andreas GampeTEST_F(UnstartedRuntimeTest, ThreadCurrentThread) { 1055bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe Thread* self = Thread::Current(); 1056bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe ScopedObjectAccess soa(self); 1057bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe 1058bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe JValue result; 1059bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1060bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe 1061bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe StackHandleScope<1> hs(self); 1062bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1063bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe Handle<mirror::Class> thread_class = hs.NewHandle( 1064bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>())); 1065bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe ASSERT_TRUE(thread_class.Get() != nullptr); 1066bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true)); 1067bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe 1068bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe // Negative test. In general, currentThread should fail (as we should not leak a peer that will 1069bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe // be recreated at runtime). 1070bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe PrepareForAborts(); 1071bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe 1072bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe { 107316d1dd86dca33520b44d9802695e19d3b658af3eChang Xing Runtime::Current()->EnterTransactionMode(); 1074bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe UnstartedThreadCurrentThread(self, shadow_frame, &result, 0); 107516d1dd86dca33520b44d9802695e19d3b658af3eChang Xing ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 1076bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe Runtime::Current()->ExitTransactionMode(); 1077bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe ASSERT_TRUE(self->IsExceptionPending()); 1078bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe self->ClearException(); 1079bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe } 1080bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe 1081bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1082bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe} 1083bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe 1084bad529da18122c7044fbfd7d56153535d34367b1Andreas GampeTEST_F(UnstartedRuntimeTest, LogManager) { 1085bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe Thread* self = Thread::Current(); 1086bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe ScopedObjectAccess soa(self); 1087bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe 1088bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe StackHandleScope<1> hs(self); 1089bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1090bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe Handle<mirror::Class> log_manager_class = hs.NewHandle( 10919486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe class_linker->FindClass(self, 10929486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe "Ljava/util/logging/LogManager;", 10939486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ScopedNullHandle<mirror::ClassLoader>())); 1094bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe ASSERT_TRUE(log_manager_class.Get() != nullptr); 1095bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true)); 1096bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe} 1097bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe 109847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampeclass UnstartedClassForNameTest : public UnstartedRuntimeTest { 109947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe public: 110047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe template <typename T> 110147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe void RunTest(T& runner, bool in_transaction, bool should_succeed) { 110247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe Thread* self = Thread::Current(); 110347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ScopedObjectAccess soa(self); 110447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 110547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe // Ensure that Class is initialized. 110647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe { 110747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 110847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe StackHandleScope<1> hs(self); 110947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe Handle<mirror::Class> h_class = hs.NewHandle(mirror::Class::GetJavaLangClass()); 111047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(class_linker->EnsureInitialized(self, h_class, true, true)); 111147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } 111247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 111347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe // A selection of classes from different core classpath components. 111447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe constexpr const char* kTestCases[] = { 111547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe "java.net.CookieManager", // From libcore. 111647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe "dalvik.system.ClassExt", // From libart. 111747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe }; 111847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 111947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe if (in_transaction) { 112047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe // For transaction mode, we cannot load any classes, as the pre-fence initialization of 112147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe // classes isn't transactional. Load them ahead of time. 112247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 112347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe for (const char* name : kTestCases) { 112447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe class_linker->FindClass(self, 112547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe DotToDescriptor(name).c_str(), 112647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ScopedNullHandle<mirror::ClassLoader>()); 112747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(!self->IsExceptionPending()) << self->GetException()->Dump(); 112847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } 112947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } 113047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 113147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe if (!should_succeed) { 113247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe // Negative test. In general, currentThread should fail (as we should not leak a peer that will 113347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe // be recreated at runtime). 113447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe PrepareForAborts(); 113547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } 113647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 113747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe JValue result; 113847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 113947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 114047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe for (const char* name : kTestCases) { 114147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe mirror::String* name_string = mirror::String::AllocFromModifiedUtf8(self, name); 114247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(name_string != nullptr); 114347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 114447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe if (in_transaction) { 114516d1dd86dca33520b44d9802695e19d3b658af3eChang Xing Runtime::Current()->EnterTransactionMode(); 114647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } 114747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(!self->IsExceptionPending()); 114847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 114947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe runner(self, shadow_frame, name_string, &result); 115047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 115147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe if (should_succeed) { 115247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump(); 115347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(result.GetL() != nullptr) << name; 115447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } else { 115547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(self->IsExceptionPending()) << name; 115647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe if (in_transaction) { 115716d1dd86dca33520b44d9802695e19d3b658af3eChang Xing ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 115847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } 115947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe self->ClearException(); 116047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } 116116d1dd86dca33520b44d9802695e19d3b658af3eChang Xing 116216d1dd86dca33520b44d9802695e19d3b658af3eChang Xing if (in_transaction) { 116316d1dd86dca33520b44d9802695e19d3b658af3eChang Xing Runtime::Current()->ExitTransactionMode(); 116416d1dd86dca33520b44d9802695e19d3b658af3eChang Xing } 116547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } 116647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 116747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 116847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } 116947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 117047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) { 117147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe Thread* self = Thread::Current(); 117247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe StackHandleScope<2> hs(self); 117347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr); 117447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 117547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe { 117647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 117747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 117847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe // Create the fake boot classloader. Any instance is fine, they are technically interchangeable. 117947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe Handle<mirror::Class> boot_cp_class = hs.NewHandle( 118047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe class_linker->FindClass(self, 118147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe "Ljava/lang/BootClassLoader;", 118247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ScopedNullHandle<mirror::ClassLoader>())); 118347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(boot_cp_class != nullptr); 118447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true)); 118547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 118647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader()); 118747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(boot_cp != nullptr); 118847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 1189ba118827465d12177f3996e50133960087b1c916Vladimir Marko ArtMethod* boot_cp_init = boot_cp_class->FindConstructor( 1190ba118827465d12177f3996e50133960087b1c916Vladimir Marko "()V", class_linker->GetImagePointerSize()); 119147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(boot_cp_init != nullptr); 119247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 119347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe JValue result; 119447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, boot_cp_init, 0); 119547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVRegReference(0, boot_cp.Get()); 119647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 119747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe // create instruction data for invoke-direct {v0} of method with fake index 119847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 }; 119947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 120047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe interpreter::DoCall<false, false>(boot_cp_init, 120147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe self, 120247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe *shadow_frame, 12032b2bef245d5b2c6faa2d6f36da14866b2d8f5e4fMathieu Chartier Instruction::At(inst_data), 120447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe inst_data[0], 120547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe &result); 120647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe CHECK(!self->IsExceptionPending()); 120747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 120847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 120947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } 121047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 121147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe return boot_cp.Get(); 121247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe } 121347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe}; 121447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 121547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas GampeTEST_F(UnstartedClassForNameTest, ClassForName) { 121647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 121747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 121847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVRegReference(0, name); 121947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe UnstartedClassForName(self, shadow_frame, result, 0); 122047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe }; 122147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe RunTest(runner, false, true); 122247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe} 122347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 122447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas GampeTEST_F(UnstartedClassForNameTest, ClassForNameLong) { 122547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 122647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 122747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVRegReference(0, name); 122847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVReg(1, 0); 122947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVRegReference(2, nullptr); 123047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe UnstartedClassForNameLong(self, shadow_frame, result, 0); 123147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe }; 123247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe RunTest(runner, false, true); 123347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe} 123447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 123547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas GampeTEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) { 123647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe Thread* self = Thread::Current(); 123747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ScopedObjectAccess soa(self); 123847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 123947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe StackHandleScope<1> hs(self); 124047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader()); 124147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 124247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 124347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 124447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVRegReference(0, name); 124547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVReg(1, 0); 124647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVRegReference(2, boot_cp.Get()); 124747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe UnstartedClassForNameLong(th, shadow_frame, result, 0); 124847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe }; 124947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe RunTest(runner, false, true); 125047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe} 125147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 125247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas GampeTEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) { 125347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe Thread* self = Thread::Current(); 125447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ScopedObjectAccess soa(self); 125547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 125647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe StackHandleScope<1> hs(self); 125747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader()); 125847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 125947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 126047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 126147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVRegReference(0, name); 126247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVReg(1, 0); 126347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVRegReference(2, boot_cp.Get()); 126447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe UnstartedClassForNameLong(th, shadow_frame, result, 0); 126547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe }; 126647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe RunTest(runner, true, true); 126747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe} 126847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 126947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas GampeTEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) { 127047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe Thread* self = Thread::Current(); 127147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ScopedObjectAccess soa(self); 127247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 127347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe StackHandleScope<2> hs(self); 127447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 127547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe jobject path_jobj = class_linker->CreatePathClassLoader(self, {}); 127647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe ASSERT_TRUE(path_jobj != nullptr); 127747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>( 127847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe self->DecodeJObject(path_jobj)->AsClassLoader()); 127947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 128047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 128147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 128247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVRegReference(0, name); 128347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVReg(1, 0); 128447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe shadow_frame->SetVRegReference(2, path_cp.Get()); 128547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe UnstartedClassForNameLong(th, shadow_frame, result, 0); 128647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe }; 128747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe RunTest(runner, true, false); 128847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe} 128947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe 12909486a16180466e32aa8a98927030aff9fbdce189Andreas GampeTEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) { 12919486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe Thread* self = Thread::Current(); 12929486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ScopedObjectAccess soa(self); 12939486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe 12949486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe StackHandleScope<1> hs(self); 12959486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 12969486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe Handle<mirror::Class> list_class = hs.NewHandle( 12979486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe class_linker->FindClass(self, 12989486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe "Ljava/util/List;", 12999486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ScopedNullHandle<mirror::ClassLoader>())); 13009486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ASSERT_TRUE(list_class.Get() != nullptr); 13019486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true)); 13029486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe 13039486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe JValue result; 13049486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 13059486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe 13069486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe shadow_frame->SetVRegReference(0, list_class.Get()); 13079486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe UnstartedClassGetSignatureAnnotation(self, shadow_frame, &result, 0); 13089486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ASSERT_TRUE(result.GetL() != nullptr); 13099486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 13109486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe 13119486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 13129486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe 13139486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ASSERT_TRUE(result.GetL()->IsObjectArray()); 13149486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ObjPtr<mirror::ObjectArray<mirror::Object>> array = 13159486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe result.GetL()->AsObjectArray<mirror::Object>(); 13169486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe std::ostringstream oss; 13179486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe for (int32_t i = 0; i != array->GetLength(); ++i) { 13189486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ObjPtr<mirror::Object> elem = array->Get(i); 13199486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ASSERT_TRUE(elem != nullptr); 13209486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ASSERT_TRUE(elem->IsString()); 13219486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe oss << elem->AsString()->ToModifiedUtf8(); 13229486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe } 13239486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe std::string output_string = oss.str(); 13249486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;"); 13259486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe} 13269486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe 132785bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas GampeTEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) { 132885bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe Thread* self = Thread::Current(); 132985bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ScopedObjectAccess soa(self); 133085bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe 133185bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe StackHandleScope<4> hs(self); 133285bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 133385bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe 133485bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe // Get Throwable. 133585bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe Handle<mirror::Class> throw_class = hs.NewHandle(mirror::Throwable::GetJavaLangThrowable()); 133685bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true)); 133785bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe 133885bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe // Get an input object. 133985bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd")); 134085bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe 134185bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe // Find the constructor. 1342ba118827465d12177f3996e50133960087b1c916Vladimir Marko ArtMethod* throw_cons = throw_class->FindConstructor( 1343ba118827465d12177f3996e50133960087b1c916Vladimir Marko "(Ljava/lang/String;)V", class_linker->GetImagePointerSize()); 134485bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ASSERT_TRUE(throw_cons != nullptr); 1345fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing Handle<mirror::Constructor> cons; 1346fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing if (class_linker->GetImagePointerSize() == PointerSize::k64) { 1347fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing cons = hs.NewHandle( 1348fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons)); 1349fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing ASSERT_TRUE(cons != nullptr); 1350fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing } else { 1351fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing cons = hs.NewHandle( 1352fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons)); 1353fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing ASSERT_TRUE(cons != nullptr); 1354fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing } 135585bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe 135685bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle( 1357c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe mirror::ObjectArray<mirror::Object>::Alloc( 1358c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe self, class_linker_->GetClassRoot(ClassLinker::ClassRoot::kObjectArrayClass), 1)); 135985bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ASSERT_TRUE(args != nullptr); 136085bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe args->Set(0, input.Get()); 136185bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe 136285bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe // OK, we're ready now. 136385bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe JValue result; 136485bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 136585bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe shadow_frame->SetVRegReference(0, cons.Get()); 136685bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe shadow_frame->SetVRegReference(1, args.Get()); 136785bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe UnstartedConstructorNewInstance0(self, shadow_frame, &result, 0); 136885bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe 136985bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ASSERT_TRUE(result.GetL() != nullptr); 137085bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 137185bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe 137285bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe // Should be a new object. 137385bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ASSERT_NE(result.GetL(), input.Get()); 137485bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe // Should be a String. 137585bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ASSERT_EQ(mirror::Throwable::GetJavaLangThrowable(), result.GetL()->GetClass()); 137685bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe // Should have the right string. 137785bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ObjPtr<mirror::String> result_msg = 137885bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage(); 137985bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe EXPECT_EQ(input.Get(), result_msg.Ptr()); 138085bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe 138185bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 138285bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe} 138385bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe 1384ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas GeoffrayTEST_F(UnstartedRuntimeTest, IdentityHashCode) { 1385ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray Thread* self = Thread::Current(); 1386ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray ScopedObjectAccess soa(self); 1387ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1388ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray 1389ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray JValue result; 1390ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray UnstartedSystemIdentityHashCode(self, tmp, &result, 0); 1391ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray 1392ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray EXPECT_EQ(0, result.GetI()); 1393ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray ASSERT_FALSE(self->IsExceptionPending()); 1394ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray 1395ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd"); 1396ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray tmp->SetVRegReference(0, str.Ptr()); 1397ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray UnstartedSystemIdentityHashCode(self, tmp, &result, 0); 1398ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray EXPECT_NE(0, result.GetI()); 1399ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray EXPECT_EQ(str->IdentityHashCode(), result.GetI()); 1400ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray ASSERT_FALSE(self->IsExceptionPending()); 1401ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray 1402ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray ShadowFrame::DeleteDeoptimizedFrame(tmp); 1403ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray} 1404ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray 1405799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} // namespace interpreter 1406799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} // namespace art 1407