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> 200bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe#include <locale> 2189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 2289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe#include "base/casts.h" 23656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe#include "base/memory_tool.h" 24799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "class_linker.h" 25799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "common_runtime_test.h" 26400ce0087ed0a41f385b55d555afc4616166965aJeff Hao#include "dex_instruction.h" 27799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle.h" 28799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle_scope-inl.h" 29400ce0087ed0a41f385b55d555afc4616166965aJeff Hao#include "interpreter/interpreter_common.h" 30799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/class_loader.h" 31799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/string-inl.h" 32799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "runtime.h" 33799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "scoped_thread_state_change.h" 34799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "thread.h" 350bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe#include "transaction.h" 36799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 37799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace art { 38799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace interpreter { 39799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 40799681b176ad25437ce2849639f54f610dcbf684Andreas Gampeclass UnstartedRuntimeTest : public CommonRuntimeTest { 41799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe protected: 42799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Re-expose all UnstartedRuntime implementations so we don't need to declare a million 43799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // test friends. 44799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 45799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Methods that intercept available libcore implementations. 46799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#define UNSTARTED_DIRECT(Name, SigIgnored) \ 47799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe static void Unstarted ## Name(Thread* self, \ 48799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* shadow_frame, \ 49799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue* result, \ 50799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe size_t arg_offset) \ 5190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 52799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \ 53799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 54799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h" 55799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT) 56799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST 57799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST 58799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_DIRECT 59799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 60799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Methods that are native. 61e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#define UNSTARTED_JNI(Name, SigIgnored) \ 62799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe static void UnstartedJNI ## Name(Thread* self, \ 63e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method, \ 64799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::Object* receiver, \ 65799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe uint32_t* args, \ 66799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue* result) \ 6790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { \ 68799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \ 69799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 70799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h" 71799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI) 72799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST 73799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST 74799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_JNI 7585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 7685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Helpers for ArrayCopy. 7785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // 7885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size 7985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // of three everywhere. That is enough to test all cases. 8085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 8185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe static mirror::ObjectArray<mirror::Object>* CreateObjectArray( 8285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Thread* self, 8385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::Class* component_type, 8485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& data) 8585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe SHARED_REQUIRES(Locks::mutator_lock_) { 8685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Runtime* runtime = Runtime::Current(); 8785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::Class* array_type = runtime->GetClassLinker()->FindArrayClass(self, &component_type); 8885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK(array_type != nullptr); 8985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>* result = 9085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3); 9185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK(result != nullptr); 9285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe for (size_t i = 0; i < 3; ++i) { 9385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe result->Set(static_cast<int32_t>(i), data.GetReference(i)); 9485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK(!self->IsExceptionPending()); 9585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 9685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe return result; 9785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 9885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 9985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array, 10085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& data) 10185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe SHARED_REQUIRES(Locks::mutator_lock_) { 10285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK_EQ(array->GetLength(), 3); 10385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CHECK_EQ(data.NumberOfReferences(), 3U); 10485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe for (size_t i = 0; i < 3; ++i) { 10585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i; 10685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 10785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 10885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 10985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe void RunArrayCopy(Thread* self, 11085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp, 11185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe bool expect_exception, 11285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>* src, 11385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t src_pos, 11485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>* dst, 11585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t dst_pos, 11685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t length) 11785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe SHARED_REQUIRES(Locks::mutator_lock_) { 11885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe JValue result; 11985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVRegReference(0, src); 12085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVReg(1, src_pos); 12185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVRegReference(2, dst); 12285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVReg(3, dst_pos); 12385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp->SetVReg(4, length); 12485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe UnstartedSystemArraycopy(self, tmp, &result, 0); 12585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe bool exception_pending = self->IsExceptionPending(); 12685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe EXPECT_EQ(exception_pending, expect_exception); 12785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe if (exception_pending) { 12885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe self->ClearException(); 12985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 13085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 13185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 13285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe void RunArrayCopy(Thread* self, 13385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp, 13485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe bool expect_exception, 13585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::Class* src_component_class, 13685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::Class* dst_component_class, 13785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& src_data, 13885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t src_pos, 13985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& dst_data, 14085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t dst_pos, 14185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe int32_t length, 14285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe const StackHandleScope<3>& expected_result) 14385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe SHARED_REQUIRES(Locks::mutator_lock_) { 14485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_misc(self); 14585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class)); 14685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 14785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::ObjectArray<mirror::Object>> src_handle( 14885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data))); 14985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 15085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::ObjectArray<mirror::Object>> dst_handle( 15185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data))); 15285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 15385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 15485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 15585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe expect_exception, 15685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe src_handle.Get(), 15785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe src_pos, 15885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe dst_handle.Get(), 15985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe dst_pos, 16085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe length); 16185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe CheckObjectArray(dst_handle.Get(), expected_result); 16285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 16389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 16489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe void TestCeilFloor(bool ceil, 16589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe Thread* self, 16689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ShadowFrame* tmp, 16789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe double const test_pairs[][2], 16889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe size_t num_pairs) 16989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe SHARED_REQUIRES(Locks::mutator_lock_) { 17089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe for (size_t i = 0; i < num_pairs; ++i) { 17189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe tmp->SetVRegDouble(0, test_pairs[i][0]); 17289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 17389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe JValue result; 17489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe if (ceil) { 17589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe UnstartedMathCeil(self, tmp, &result, 0); 17689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe } else { 17789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe UnstartedMathFloor(self, tmp, &result, 0); 17889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe } 17989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 18089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 18189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 18289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe // We want precise results. 18389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe int64_t result_int64t = bit_cast<int64_t, double>(result.GetD()); 18489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]); 18589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1]; 18689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe } 18789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe } 1880bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe 1890bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe // Prepare for aborts. Aborts assume that the exception class is already resolved, as the 1900bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe // loading code doesn't work under transactions. 1910bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe void PrepareForAborts() SHARED_REQUIRES(Locks::mutator_lock_) { 1920bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe mirror::Object* result = Runtime::Current()->GetClassLinker()->FindClass( 1930bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Thread::Current(), 1940bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Transaction::kAbortExceptionSignature, 1950bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ScopedNullHandle<mirror::ClassLoader>()); 1960bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe CHECK(result != nullptr); 1970bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 198799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}; 199799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 200799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekByte) { 201799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 202799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 203799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 204799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 205799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 206799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 207799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 208799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 209799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 210799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 211799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < kBaseLen; ++i) { 212799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 213799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 214799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekByte(self, tmp, &result, 0); 215799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 216799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i])); 217799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 218799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 219799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 220799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 221799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 222799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekShort) { 223799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 224799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 225799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 226799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 227799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 228799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 229799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 230799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 231799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 232799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 233799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t adjusted_length = kBaseLen - sizeof(int16_t); 234799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < adjusted_length; ++i) { 235799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 236799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 237799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekShort(self, tmp, &result, 0); 238799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 239799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe typedef int16_t unaligned_short __attribute__ ((aligned (1))); 240799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i); 241799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetS(), *short_ptr); 242799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 243799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 244799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 245799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 246799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 247799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekInt) { 248799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 249799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 250799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 251799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 252799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 253799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 254799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 255799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 256799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 257799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 258799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t adjusted_length = kBaseLen - sizeof(int32_t); 259799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < adjusted_length; ++i) { 260799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 261799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 262799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekInt(self, tmp, &result, 0); 263799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 264799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe typedef int32_t unaligned_int __attribute__ ((aligned (1))); 265799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i); 266799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetI(), *int_ptr); 267799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 268799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 269799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 270799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 271799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 272799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekLong) { 273799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 274799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 275799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 276799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 277799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 278799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const uint8_t* base_ptr = base_array; 279799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 280799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 281799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 282799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 283799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t adjusted_length = kBaseLen - sizeof(int64_t); 284799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < adjusted_length; ++i) { 285799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 286799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 287799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedMemoryPeekLong(self, tmp, &result, 0); 288799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 289799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe typedef int64_t unaligned_long __attribute__ ((aligned (1))); 290799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i); 291799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetJ(), *long_ptr); 292799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 293799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 294799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 295799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 296799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 297799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) { 298799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 299799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 300799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 301799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe StackHandleScope<2> hs(self); 302799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // TODO: Actual UTF. 303799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const char base_string[] = "abcdefghijklmnop"; 304799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Handle<mirror::String> h_test_string(hs.NewHandle( 305799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::String::AllocFromModifiedUtf8(self, base_string))); 306799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1; 307799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Handle<mirror::CharArray> h_char_array(hs.NewHandle( 308799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::CharArray::Alloc(self, kBaseLen))); 309799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // A buffer so we can make sure we only modify the elements targetted. 310799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe uint16_t buf[kBaseLen]; 311799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 312799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 313799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 314799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 315799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) { 316799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t count = 0; count <= kBaseLen; ++count) { 317799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) { 318799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Only do it when in bounds. 319799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) { 320799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegReference(0, h_test_string.Get()); 321799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(1, start_index); 322799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(2, count); 323799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegReference(3, h_char_array.Get()); 324799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(3, trg_offset); 325799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 326799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Copy the char_array into buf. 327799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t)); 328799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 329799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedStringCharAt(self, tmp, &result, 0); 330799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 331799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe uint16_t* data = h_char_array->GetData(); 332799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 333799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe bool success = true; 334799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 335799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // First segment should be unchanged. 336799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < trg_offset; ++i) { 337799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe success = success && (data[i] == buf[i]); 338799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 339799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Second segment should be a copy. 340799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = trg_offset; i < trg_offset + count; ++i) { 341799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe success = success && (data[i] == buf[i - trg_offset + start_index]); 342799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 343799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // Third segment should be unchanged. 344799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = trg_offset + count; i < kBaseLen; ++i) { 345799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe success = success && (data[i] == buf[i]); 346799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 347799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 348799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_TRUE(success); 349799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 350799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 351799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 352799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 353799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 354799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 355799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 356799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 357799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringCharAt) { 358799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe Thread* self = Thread::Current(); 359799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 360799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ScopedObjectAccess soa(self); 361799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe // TODO: Actual UTF. 362799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe constexpr const char* base_string = "abcdefghijklmnop"; 363799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe int32_t base_len = static_cast<int32_t>(strlen(base_string)); 364799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe mirror::String* test_string = mirror::String::AllocFromModifiedUtf8(self, base_string); 365799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 366799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe JValue result; 367799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 368799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 369799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe for (int32_t i = 0; i < base_len; ++i) { 370799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVRegReference(0, test_string); 371799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe tmp->SetVReg(1, i); 372799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 373799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedStringCharAt(self, tmp, &result, 0); 374799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 375799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe EXPECT_EQ(result.GetI(), base_string[i]); 376799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe } 377799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 378799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 379799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} 380799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe 381400ce0087ed0a41f385b55d555afc4616166965aJeff HaoTEST_F(UnstartedRuntimeTest, StringInit) { 382400ce0087ed0a41f385b55d555afc4616166965aJeff Hao Thread* self = Thread::Current(); 383400ce0087ed0a41f385b55d555afc4616166965aJeff Hao ScopedObjectAccess soa(self); 384400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::Class* klass = mirror::String::GetJavaLangString(); 385e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method = klass->FindDeclaredDirectMethod("<init>", "(Ljava/lang/String;)V", 386e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier sizeof(void*)); 387400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 388400ce0087ed0a41f385b55d555afc4616166965aJeff Hao // create instruction data for invoke-direct {v0, v1} of method with fake index 389400ce0087ed0a41f385b55d555afc4616166965aJeff Hao uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 }; 390400ce0087ed0a41f385b55d555afc4616166965aJeff Hao const Instruction* inst = Instruction::At(inst_data); 391400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 392400ce0087ed0a41f385b55d555afc4616166965aJeff Hao JValue result; 393400ce0087ed0a41f385b55d555afc4616166965aJeff Hao ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0); 394400ce0087ed0a41f385b55d555afc4616166965aJeff Hao const char* base_string = "hello_world"; 395400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string); 396400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, ""); 397400ce0087ed0a41f385b55d555afc4616166965aJeff Hao shadow_frame->SetVRegReference(0, reference_empty_string); 398400ce0087ed0a41f385b55d555afc4616166965aJeff Hao shadow_frame->SetVRegReference(1, string_arg); 399400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 400400ce0087ed0a41f385b55d555afc4616166965aJeff Hao interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result); 401400ce0087ed0a41f385b55d555afc4616166965aJeff Hao mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL()); 402400ce0087ed0a41f385b55d555afc4616166965aJeff Hao EXPECT_EQ(string_arg->GetLength(), string_result->GetLength()); 403400ce0087ed0a41f385b55d555afc4616166965aJeff Hao EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(), 404400ce0087ed0a41f385b55d555afc4616166965aJeff Hao string_arg->GetLength() * sizeof(uint16_t)), 0); 405400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 406400ce0087ed0a41f385b55d555afc4616166965aJeff Hao ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 407400ce0087ed0a41f385b55d555afc4616166965aJeff Hao} 408400ce0087ed0a41f385b55d555afc4616166965aJeff Hao 40985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// Tests the exceptions that should be checked before modifying the destination. 41085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// (Doesn't check the object vs primitive case ATM.) 41185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) { 41285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Thread* self = Thread::Current(); 41385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ScopedObjectAccess soa(self); 41485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe JValue result; 41585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 41685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 41785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we 41885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // allocate. 41985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<2> hs_misc(self); 42085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::Class> object_class( 42185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 42285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 42385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_data(self); 42485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 42585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 42685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 42785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 42885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::ObjectArray<mirror::Object>> array( 42985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data))); 43085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 43185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0); 43285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0); 43385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1); 43485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4); 43585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3); 43685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3); 43785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 43885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::ObjectArray<mirror::Object>* class_as_array = 43985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()); 44085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0); 44185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0); 44285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 44385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 44485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe} 44585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 44685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) { 44785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Thread* self = Thread::Current(); 44885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ScopedObjectAccess soa(self); 44985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe JValue result; 45085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 45185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 45285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<1> hs_object(self); 45385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe Handle<mirror::Class> object_class( 45485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 45585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 45685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Simple test: 45785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6] 45885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe { 45985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_src(self); 46085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 46185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 46285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 46385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 46485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_dst(self); 46585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 46685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 46785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 46885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 46985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_expected(self); 47085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(0)); 47185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(1)); 47285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_src.GetReference(1)); 47385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 47485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 47585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 47685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe false, 47785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 47885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 47985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src, 48085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 48185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst, 48285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 2, 48385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 48485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected); 48585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 48685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 48785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Simple test: 48885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[]) 48985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe { 49085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_src(self); 49185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 49285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 49385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 49485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 49585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_dst(self); 49685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 49785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 49885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 49985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 50085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_expected(self); 50185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(0)); 50285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_src.GetReference(1)); 50385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(2)); 50485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 50585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 50685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 50785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe false, 50885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 50985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::String::GetJavaLangString(), 51085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src, 51185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 51285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst, 51385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 51485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 1, 51585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected); 51685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 51785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 51885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // Simple test: 51985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe // [1,*,3] into [4,5,6] = [1,5,6] + exc 52085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe { 52185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_src(self); 52285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 52385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::GetJavaLangString()); 52485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 52585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 52685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_dst(self); 52785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 52885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 52985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 53085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 53185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe StackHandleScope<3> hs_expected(self); 53285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_src.GetReference(0)); 53385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(1)); 53485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected.NewHandle(hs_dst.GetReference(2)); 53585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 53685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe RunArrayCopy(self, 53785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe tmp, 53885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe true, 53985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe object_class.Get(), 54085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe mirror::String::GetJavaLangString(), 54185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_src, 54285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 0, 54385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_dst, 54485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 0, 54585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 3, 54685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe hs_expected); 54785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe } 54885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 54985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 55085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe} 55185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe 55213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas GampeTEST_F(UnstartedRuntimeTest, IntegerParseIntTest) { 55313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe Thread* self = Thread::Current(); 55413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ScopedObjectAccess soa(self); 55513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 55613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 55713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 55813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all 55913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe // suffixes). 56013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe constexpr const char* test_string = "-2147483646"; 56113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe constexpr int32_t test_values[] = { 56213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 6, 56313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 46, 56413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 646, 56513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 3646, 56613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 83646, 56713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 483646, 56813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 7483646, 56913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 47483646, 57013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 147483646, 57113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 2147483646, 57213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe -2147483646 57313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe }; 57413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 57513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe static_assert(arraysize(test_values) == 11U, "test_values"); 57613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe CHECK_EQ(strlen(test_string), 11U); 57713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 57813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe for (size_t i = 0; i <= 10; ++i) { 57913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe const char* test_value = &test_string[10 - i]; 58013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 58113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe StackHandleScope<1> hs_str(self); 58213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe Handle<mirror::String> h_str( 58313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value))); 58413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_NE(h_str.Get(), nullptr); 58513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 58613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 58713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe tmp->SetVRegReference(0, h_str.Get()); 58813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 58913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe JValue result; 59013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe UnstartedIntegerParseInt(self, tmp, &result, 0); 59113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 59213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 59313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe EXPECT_EQ(result.GetI(), test_values[i]); 59413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe } 59513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 59613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 59713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe} 59813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 59913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe// Right now the same as Integer.Parse 60013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas GampeTEST_F(UnstartedRuntimeTest, LongParseLongTest) { 60113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe Thread* self = Thread::Current(); 60213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ScopedObjectAccess soa(self); 60313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 60413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 60513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 60613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all 60713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe // suffixes). 60813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe constexpr const char* test_string = "-2147483646"; 60913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe constexpr int64_t test_values[] = { 61013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 6, 61113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 46, 61213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 646, 61313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 3646, 61413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 83646, 61513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 483646, 61613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 7483646, 61713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 47483646, 61813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 147483646, 61913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 2147483646, 62013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe -2147483646 62113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe }; 62213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 62313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe static_assert(arraysize(test_values) == 11U, "test_values"); 62413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe CHECK_EQ(strlen(test_string), 11U); 62513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 62613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe for (size_t i = 0; i <= 10; ++i) { 62713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe const char* test_value = &test_string[10 - i]; 62813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 62913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe StackHandleScope<1> hs_str(self); 63013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe Handle<mirror::String> h_str( 63113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value))); 63213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_NE(h_str.Get(), nullptr); 63313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 63413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 63513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe tmp->SetVRegReference(0, h_str.Get()); 63613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 63713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe JValue result; 63813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe UnstartedLongParseLong(self, tmp, &result, 0); 63913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 64013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 64113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe EXPECT_EQ(result.GetJ(), test_values[i]); 64213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe } 64313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 64413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 64513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe} 64613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe 64789e3b486167c58a3268cf963c56183cd7f478b3cAndreas GampeTEST_F(UnstartedRuntimeTest, Ceil) { 64889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe Thread* self = Thread::Current(); 64989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ScopedObjectAccess soa(self); 65089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 65189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 65289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 65389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double nan = std::numeric_limits<double>::quiet_NaN(); 65489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double inf = std::numeric_limits<double>::infinity(); 65589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1); 65689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55); 65789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double test_pairs[][2] = { 65889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -0.0, -0.0 }, 65989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 0.0, 0.0 }, 66089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -0.5, -0.0 }, 66189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -1.0, -1.0 }, 66289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 0.5, 1.0 }, 66389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 1.0, 1.0 }, 66489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { nan, nan }, 66589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { inf, inf }, 66689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -inf, -inf }, 66789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { ld1, ld1 }, 66889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { ld2, ld2 } 66989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe }; 67089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 67189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs)); 67289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 67389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 67489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe} 67589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 67689e3b486167c58a3268cf963c56183cd7f478b3cAndreas GampeTEST_F(UnstartedRuntimeTest, Floor) { 67789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe Thread* self = Thread::Current(); 67889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ScopedObjectAccess soa(self); 67989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 68089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 68189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 68289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double nan = std::numeric_limits<double>::quiet_NaN(); 68389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double inf = std::numeric_limits<double>::infinity(); 68489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1); 68589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55); 68689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe constexpr double test_pairs[][2] = { 68789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -0.0, -0.0 }, 68889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 0.0, 0.0 }, 68989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -0.5, -1.0 }, 69089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -1.0, -1.0 }, 69189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 0.5, 0.0 }, 69289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { 1.0, 1.0 }, 69389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { nan, nan }, 69489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { inf, inf }, 69589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { -inf, -inf }, 69689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { ld1, ld1 }, 69789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe { ld2, ld2 } 69889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe }; 69989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 70089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe TestCeilFloor(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs)); 70189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 70289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 70389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe} 70489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe 7050bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas GampeTEST_F(UnstartedRuntimeTest, ToLowerUpper) { 7060bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Thread* self = Thread::Current(); 7070bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ScopedObjectAccess soa(self); 7080bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe 7090bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 7100bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe 7110bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe std::locale c_locale("C"); 7120bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe 7130bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe // Check ASCII. 7140bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe for (uint32_t i = 0; i < 128; ++i) { 7150bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe bool c_upper = std::isupper(static_cast<char>(i), c_locale); 7160bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe bool c_lower = std::islower(static_cast<char>(i), c_locale); 7170bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe EXPECT_FALSE(c_upper && c_lower) << i; 7180bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe 7190bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe // Check toLowerCase. 7200bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe { 7210bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe JValue result; 7220bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 7230bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe UnstartedCharacterToLowerCase(self, tmp, &result, 0); 7240bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 7250bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe uint32_t lower_result = static_cast<uint32_t>(result.GetI()); 7260bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe if (c_lower) { 7270bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe EXPECT_EQ(i, lower_result); 7280bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } else if (c_upper) { 7290bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)), 7300bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe lower_result); 7310bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } else { 7320bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe EXPECT_EQ(i, lower_result); 7330bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 7340bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 7350bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe 7360bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe // Check toUpperCase. 7370bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe { 7380bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe JValue result2; 7390bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 7400bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe UnstartedCharacterToUpperCase(self, tmp, &result2, 0); 7410bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ASSERT_FALSE(self->IsExceptionPending()); 7420bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe uint32_t upper_result = static_cast<uint32_t>(result2.GetI()); 7430bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe if (c_upper) { 7440bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe EXPECT_EQ(i, upper_result); 7450bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } else if (c_lower) { 7460bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)), 7470bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe upper_result); 7480bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } else { 7490bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe EXPECT_EQ(i, upper_result); 7500bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 7510bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 7520bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 7530bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe 7540bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe // Check abort for other things. Can't test all. 7550bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe 7560bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe PrepareForAborts(); 7570bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe 7580bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe for (uint32_t i = 128; i < 256; ++i) { 7590bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe { 7600bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe JValue result; 7610bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 7620bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Transaction transaction; 7630bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Runtime::Current()->EnterTransactionMode(&transaction); 7640bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe UnstartedCharacterToLowerCase(self, tmp, &result, 0); 7650bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Runtime::Current()->ExitTransactionMode(); 7660bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ASSERT_TRUE(self->IsExceptionPending()); 7670bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ASSERT_TRUE(transaction.IsAborted()); 7680bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 7690bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe { 7700bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe JValue result; 7710bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 7720bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Transaction transaction; 7730bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Runtime::Current()->EnterTransactionMode(&transaction); 7740bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe UnstartedCharacterToUpperCase(self, tmp, &result, 0); 7750bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Runtime::Current()->ExitTransactionMode(); 7760bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ASSERT_TRUE(self->IsExceptionPending()); 7770bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ASSERT_TRUE(transaction.IsAborted()); 7780bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 7790bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 7800bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) { 7810bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe { 7820bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe JValue result; 7830bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 7840bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Transaction transaction; 7850bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Runtime::Current()->EnterTransactionMode(&transaction); 7860bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe UnstartedCharacterToLowerCase(self, tmp, &result, 0); 7870bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Runtime::Current()->ExitTransactionMode(); 7880bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ASSERT_TRUE(self->IsExceptionPending()); 7890bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ASSERT_TRUE(transaction.IsAborted()); 7900bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 7910bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe { 7920bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe JValue result; 7930bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe tmp->SetVReg(0, static_cast<int32_t>(i)); 7940bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Transaction transaction; 7950bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Runtime::Current()->EnterTransactionMode(&transaction); 7960bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe UnstartedCharacterToUpperCase(self, tmp, &result, 0); 7970bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe Runtime::Current()->ExitTransactionMode(); 7980bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ASSERT_TRUE(self->IsExceptionPending()); 7990bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ASSERT_TRUE(transaction.IsAborted()); 8000bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 8010bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe } 8020bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe 8030bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 8040bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe} 8050bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe 8068c5889a3bdefd7dc84494ec824d495913f2362a9Andreas GampeTEST_F(UnstartedRuntimeTest, Sin) { 8078c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe Thread* self = Thread::Current(); 8088c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe ScopedObjectAccess soa(self); 8098c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8108c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 8118c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8128c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe // Test an important value, PI/6. That's the one we see in practice. 8138c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365); 8148c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(lvalue)); 8158c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8168c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe JValue result; 8178c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe UnstartedMathSin(self, tmp, &result, 0); 8188c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8198c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 8208c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult); 8218c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8228c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 8238c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe} 8248c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8258c5889a3bdefd7dc84494ec824d495913f2362a9Andreas GampeTEST_F(UnstartedRuntimeTest, Cos) { 8268c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe Thread* self = Thread::Current(); 8278c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe ScopedObjectAccess soa(self); 8288c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8298c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 8308c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8318c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe // Test an important value, PI/6. That's the one we see in practice. 8328c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365); 8338c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(lvalue)); 8348c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8358c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe JValue result; 8368c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe UnstartedMathCos(self, tmp, &result, 0); 8378c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8388c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 8398c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult); 8408c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8418c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 8428c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe} 8438c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8448c5889a3bdefd7dc84494ec824d495913f2362a9Andreas GampeTEST_F(UnstartedRuntimeTest, Pow) { 845656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe // Valgrind seems to get this wrong, actually. Disable for valgrind. 846656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) { 847656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe return; 848656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe } 849656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe 8508c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe Thread* self = Thread::Current(); 8518c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe ScopedObjectAccess soa(self); 8528c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8538c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 8548c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8558c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe // Test an important pair. 8568c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000); 8578c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000); 8588c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8598c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1)); 8608c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2)); 8618c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8628c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe JValue result; 8638c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe UnstartedMathPow(self, tmp, &result, 0); 8648c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8658c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 8668c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult); 8678c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 8688c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe ShadowFrame::DeleteDeoptimizedFrame(tmp); 8698c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe} 8708c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe 871799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} // namespace interpreter 872799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe} // namespace art 873