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