178 lines · cpp
1//===- AllocActionTest.cpp ------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Tests for orc-rt's AllocAction.h APIs.10//11//===----------------------------------------------------------------------===//12 13#include "orc-rt/AllocAction.h"14#include "orc-rt/ExecutorAddress.h"15#include "orc-rt/SPSAllocAction.h"16 17#include "AllocActionTestUtils.h"18#include "gtest/gtest.h"19 20using namespace orc_rt;21 22TEST(AllocActionTest, DefaultConstruct) {23 AllocAction AA;24 EXPECT_FALSE(AA);25}26 27static orc_rt_WrapperFunctionBuffer noopAction(const char *ArgData,28 size_t ArgSize) {29 return WrapperFunctionBuffer().release();30}31 32TEST(AllocActionTest, ConstructWithAction) {33 AllocAction AA(noopAction, WrapperFunctionBuffer());34 EXPECT_TRUE(AA);35}36 37// Increments int via pointer.38static orc_rt_WrapperFunctionBuffer39increment_sps_allocaction(const char *ArgData, size_t ArgSize) {40 return SPSAllocActionFunction<SPSExecutorAddr>::handle(41 ArgData, ArgSize,42 [](ExecutorAddr IntPtr) {43 *IntPtr.toPtr<int *>() += 1;44 return WrapperFunctionBuffer();45 })46 .release();47}48 49// Increments int via pointer.50static orc_rt_WrapperFunctionBuffer51decrement_sps_allocaction(const char *ArgData, size_t ArgSize) {52 return SPSAllocActionFunction<SPSExecutorAddr>::handle(53 ArgData, ArgSize,54 [](ExecutorAddr IntPtr) {55 *IntPtr.toPtr<int *>() -= 1;56 return WrapperFunctionBuffer();57 })58 .release();59}60 61template <typename T>62static WrapperFunctionBuffer makeExecutorAddrBuffer(T *P) {63 return *spsSerialize<SPSArgList<SPSExecutorAddr>>(ExecutorAddr::fromPtr(P));64}65 66TEST(AllocActionTest, RunBasicAction) {67 int Val = 0;68 AllocAction IncVal(increment_sps_allocaction, makeExecutorAddrBuffer(&Val));69 EXPECT_TRUE(IncVal);70 auto B = IncVal();71 EXPECT_TRUE(B.empty());72 EXPECT_EQ(Val, 1);73}74 75TEST(AllocActionTest, RunFinalizationActionsComplete) {76 int Val = 0;77 78 std::vector<AllocActionPair> InitialActions;79 80 auto MakeAAOnVal = [&](AllocActionFn Fn) {81 return *MakeAllocAction<SPSExecutorAddr>::from(Fn,82 ExecutorAddr::fromPtr(&Val));83 };84 InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),85 MakeAAOnVal(decrement_sps_allocaction)});86 InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),87 MakeAAOnVal(decrement_sps_allocaction)});88 89 auto DeallocActions = cantFail(runFinalizeActions(std::move(InitialActions)));90 91 EXPECT_EQ(Val, 2);92 93 runDeallocActions(std::move(DeallocActions));94 95 EXPECT_EQ(Val, 0);96}97 98static orc_rt_WrapperFunctionBuffer fail_sps_allocaction(const char *ArgData,99 size_t ArgSize) {100 return WrapperFunctionBuffer::createOutOfBandError("failed").release();101}102 103TEST(AllocActionTest, RunFinalizeActionsFail) {104 int Val = 0;105 106 std::vector<AllocActionPair> InitialActions;107 108 auto MakeAAOnVal = [&](AllocActionFn Fn) {109 return *MakeAllocAction<SPSExecutorAddr>::from(Fn,110 ExecutorAddr::fromPtr(&Val));111 };112 InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),113 MakeAAOnVal(decrement_sps_allocaction)});114 InitialActions.push_back({*MakeAllocAction<>::from(fail_sps_allocaction),115 MakeAAOnVal(decrement_sps_allocaction)});116 117 auto DeallocActions = runFinalizeActions(std::move(InitialActions));118 119 if (DeallocActions) {120 ADD_FAILURE() << "Failed to report error from runFinalizeActions";121 return;122 }123 124 EXPECT_EQ(toString(DeallocActions.takeError()), std::string("failed"));125 126 // Check that we ran the decrement corresponding to the first increment.127 EXPECT_EQ(Val, 0);128}129 130TEST(AllocActionTest, RunFinalizeActionsNullFinalize) {131 int Val = 0;132 133 std::vector<AllocActionPair> InitialActions;134 135 auto MakeAAOnVal = [&](AllocActionFn Fn) {136 return *MakeAllocAction<SPSExecutorAddr>::from(Fn,137 ExecutorAddr::fromPtr(&Val));138 };139 InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),140 MakeAAOnVal(decrement_sps_allocaction)});141 InitialActions.push_back({*MakeAllocAction<>::from(nullptr),142 MakeAAOnVal(decrement_sps_allocaction)});143 144 auto DeallocActions = cantFail(runFinalizeActions(std::move(InitialActions)));145 146 // Both dealloc actions should be included in the returned list, despite one147 // of them having a null finalize action.148 EXPECT_EQ(DeallocActions.size(), 2U);149 150 runDeallocActions(std::move(DeallocActions));151 152 EXPECT_EQ(Val, -1);153}154 155TEST(AllocActionTest, RunFinalizeActionsNullDealloc) {156 int Val = 0;157 158 std::vector<AllocActionPair> InitialActions;159 160 auto MakeAAOnVal = [&](AllocActionFn Fn) {161 return *MakeAllocAction<SPSExecutorAddr>::from(Fn,162 ExecutorAddr::fromPtr(&Val));163 };164 InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),165 MakeAAOnVal(decrement_sps_allocaction)});166 InitialActions.push_back({MakeAAOnVal(increment_sps_allocaction),167 *MakeAllocAction<>::from(nullptr)});168 169 auto DeallocActions = cantFail(runFinalizeActions(std::move(InitialActions)));170 171 // Null dealloc actions should be filtered out of the returned list.172 EXPECT_EQ(DeallocActions.size(), 1U);173 174 runDeallocActions(std::move(DeallocActions));175 176 EXPECT_EQ(Val, 1);177}178