1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecmascript/ecma_vm.h" 17#include "ecmascript/ic/invoke_cache.h" 18#include "ecmascript/object_factory.h" 19#include "ecmascript/tests/test_helper.h" 20 21using namespace panda::ecmascript; 22namespace panda::test { 23class ICInvokeTest : public testing::Test { 24public: 25 static void SetUpTestCase() 26 { 27 GTEST_LOG_(INFO) << "SetUpTestCase"; 28 } 29 30 static void TearDownTestCase() 31 { 32 GTEST_LOG_(INFO) << "TearDownCase"; 33 } 34 35 void SetUp() override 36 { 37 TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope); 38 } 39 40 void TearDown() override 41 { 42 TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope); 43 } 44 45 EcmaVM *ecmaVm = nullptr; 46 EcmaHandleScope *scope {nullptr}; 47 JSThread *thread {nullptr}; 48}; 49 50HWTEST_F_L0(ICInvokeTest, SetMonoConstuctCacheSlot) 51{ 52 auto globalEnv = ecmaVm->GetGlobalEnv(); 53 auto factory = ecmaVm->GetFactory(); 54 JSHandle<JSFunction> func = factory->NewJSFunction(globalEnv); 55 func.GetTaggedValue().GetTaggedObject()->GetClass()->SetClassConstructor(true); 56 57 JSHandle<TaggedArray> array = factory->NewTaggedArray(10); 58 uint32_t slotId = 5; 59 bool setResult = InvokeCache::SetMonoConstuctCacheSlot( 60 thread, static_cast<ProfileTypeInfo *>(*array), slotId, func.GetTaggedValue(), JSTaggedValue(123)); 61 ASSERT_TRUE(setResult); 62 ASSERT_EQ(array->Get(thread, slotId), func.GetTaggedValue()); 63 ASSERT_EQ(array->Get(thread, slotId + 1), JSTaggedValue(123)); 64} 65 66HWTEST_F_L0(ICInvokeTest, SetPolyConstuctCacheSlot) 67{ 68 auto globalEnv = ecmaVm->GetGlobalEnv(); 69 auto factory = ecmaVm->GetFactory(); 70 JSHandle<TaggedArray> array1 = factory->NewTaggedArray(3); 71 JSHandle<TaggedArray> array2 = factory->NewTaggedArray(3); 72 73 JSHandle<JSFunction> func0 = factory->NewJSFunction(globalEnv); 74 func0.GetTaggedValue().GetTaggedObject()->GetClass()->SetClassConstructor(true); 75 array1->Set(thread, 0, func0.GetTaggedValue()); 76 array2->Set(thread, 0, JSTaggedValue(123)); 77 JSHandle<JSFunction> func1 = factory->NewJSFunction(globalEnv); 78 func1.GetTaggedValue().GetTaggedObject()->GetClass()->SetClassConstructor(true); 79 array1->Set(thread, 1, func1.GetTaggedValue()); 80 array2->Set(thread, 1, JSTaggedValue(456)); 81 JSHandle<JSFunction> func2 = factory->NewJSFunction(globalEnv); 82 func2.GetTaggedValue().GetTaggedObject()->GetClass()->SetClassConstructor(true); 83 array1->Set(thread, 2, func2.GetTaggedValue()); 84 array2->Set(thread, 2, JSTaggedValue(789)); 85 86 JSHandle<TaggedArray> array = factory->NewTaggedArray(10); 87 uint32_t slotId = 5; 88 bool setResult = InvokeCache::SetPolyConstuctCacheSlot( 89 thread, static_cast<ProfileTypeInfo *>(*array), slotId, 3, array1.GetTaggedValue(), array2.GetTaggedValue()); 90 ASSERT_TRUE(setResult); 91 JSTaggedValue slot = array->Get(thread, slotId); 92 ASSERT_TRUE(slot.IsTaggedArray()); 93 JSHandle<TaggedArray> slotArray(thread, slot); 94 ASSERT_EQ(slotArray->Get(thread, 0), func0.GetTaggedValue()); 95 ASSERT_EQ(slotArray->Get(thread, 1), JSTaggedValue(123)); 96 ASSERT_EQ(slotArray->Get(thread, 2), func1.GetTaggedValue()); 97 ASSERT_EQ(slotArray->Get(thread, 3), JSTaggedValue(456)); 98 ASSERT_EQ(slotArray->Get(thread, 4), func2.GetTaggedValue()); 99 ASSERT_EQ(slotArray->Get(thread, 5), JSTaggedValue(789)); 100 ASSERT_EQ(array->Get(thread, slotId + 1), JSTaggedValue::Hole()); 101} 102 103HWTEST_F_L0(ICInvokeTest, CheckPolyInvokeCache) 104{ 105 auto globalEnv = ecmaVm->GetGlobalEnv(); 106 auto factory = ecmaVm->GetFactory(); 107 JSHandle<TaggedArray> array = factory->NewTaggedArray(6); 108 109 JSHandle<JSFunction> func0 = factory->NewJSFunction(globalEnv); 110 JSHandle<JSFunction> func1 = factory->NewJSFunction(globalEnv); 111 JSHandle<JSFunction> func2 = factory->NewJSFunction(globalEnv); 112 JSHandle<JSFunction> func3 = factory->NewJSFunction(globalEnv); 113 array->Set(thread, 0, func0.GetTaggedValue()); 114 array->Set(thread, 1, JSTaggedValue(123)); 115 array->Set(thread, 2, func1.GetTaggedValue()); 116 array->Set(thread, 3, JSTaggedValue(456)); 117 array->Set(thread, 4, func2.GetTaggedValue()); 118 array->Set(thread, 5, JSTaggedValue(789)); 119 120 JSTaggedValue testValue0 = InvokeCache::CheckPolyInvokeCache(array.GetTaggedValue(), func0.GetTaggedValue()); 121 ASSERT_EQ(testValue0, JSTaggedValue(123)); 122 JSTaggedValue testValue1 = InvokeCache::CheckPolyInvokeCache(array.GetTaggedValue(), func1.GetTaggedValue()); 123 ASSERT_EQ(testValue1, JSTaggedValue(456)); 124 JSTaggedValue testValue2 = InvokeCache::CheckPolyInvokeCache(array.GetTaggedValue(), func2.GetTaggedValue()); 125 ASSERT_EQ(testValue2, JSTaggedValue(789)); 126 JSTaggedValue testValue3 = InvokeCache::CheckPolyInvokeCache(array.GetTaggedValue(), func3.GetTaggedValue()); 127 ASSERT_EQ(testValue3, JSTaggedValue::Hole()); 128} 129} // namespace panda::test