From 897eb579c615260d68fee7ecc11a5d1773fa3781 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sat, 25 Sep 2021 11:56:30 -0700 Subject: [PATCH] [ORC-RT] ExecutorAddrDiff ergonomic improvements; contains and overlaps methods Renames StartAddress and EndAddress members to Start and End. Adds contains and overlap methods. Adds a constructor from an address and size. These changes are counterparts to LLVM commits ef391df2b6332, c0d889995e708, and 37f1b7a3f35fd. --- compiler-rt/lib/orc/elfnix_platform.cpp | 12 ++-- compiler-rt/lib/orc/executor_address.h | 37 +++++++---- compiler-rt/lib/orc/macho_platform.cpp | 18 ++--- compiler-rt/lib/orc/unittests/CMakeLists.txt | 1 + .../lib/orc/unittests/executor_address_test.cpp | 77 ++++++++++++++++++++++ 5 files changed, 119 insertions(+), 26 deletions(-) create mode 100644 compiler-rt/lib/orc/unittests/executor_address_test.cpp diff --git a/compiler-rt/lib/orc/elfnix_platform.cpp b/compiler-rt/lib/orc/elfnix_platform.cpp index 73183b3..fae93b4 100644 --- a/compiler-rt/lib/orc/elfnix_platform.cpp +++ b/compiler-rt/lib/orc/elfnix_platform.cpp @@ -41,7 +41,7 @@ Error validatePointerSectionExtent(const char *SectionName, if (SE.size().getValue() % sizeof(uintptr_t)) { std::ostringstream ErrMsg; ErrMsg << std::hex << "Size of " << SectionName << " 0x" - << SE.StartAddress.getValue() << " -- 0x" << SE.EndAddress.getValue() + << SE.Start.getValue() << " -- 0x" << SE.End.getValue() << " is not a pointer multiple"; return make_error(ErrMsg.str()); } @@ -166,10 +166,10 @@ void ELFNixPlatformRuntimeState::destroy() { Error ELFNixPlatformRuntimeState::registerObjectSections( ELFNixPerObjectSectionsToRegister POSR) { - if (POSR.EHFrameSection.StartAddress) - __register_frame(POSR.EHFrameSection.StartAddress.toPtr()); + if (POSR.EHFrameSection.Start) + __register_frame(POSR.EHFrameSection.Start.toPtr()); - if (POSR.ThreadDataSection.StartAddress) { + if (POSR.ThreadDataSection.Start) { if (auto Err = registerThreadDataSection( POSR.ThreadDataSection.toSpan())) return Err; @@ -180,8 +180,8 @@ Error ELFNixPlatformRuntimeState::registerObjectSections( Error ELFNixPlatformRuntimeState::deregisterObjectSections( ELFNixPerObjectSectionsToRegister POSR) { - if (POSR.EHFrameSection.StartAddress) - __deregister_frame(POSR.EHFrameSection.StartAddress.toPtr()); + if (POSR.EHFrameSection.Start) + __deregister_frame(POSR.EHFrameSection.Start.toPtr()); return Error::success(); } diff --git a/compiler-rt/lib/orc/executor_address.h b/compiler-rt/lib/orc/executor_address.h index f39f7d7..79ad9b7 100644 --- a/compiler-rt/lib/orc/executor_address.h +++ b/compiler-rt/lib/orc/executor_address.h @@ -135,20 +135,35 @@ inline ExecutorAddr operator+(const ExecutorAddrDiff &LHS, /// Represents an address range in the exceutor process. struct ExecutorAddrRange { ExecutorAddrRange() = default; - ExecutorAddrRange(ExecutorAddr StartAddress, ExecutorAddr EndAddress) - : StartAddress(StartAddress), EndAddress(EndAddress) {} + ExecutorAddrRange(ExecutorAddr Start, ExecutorAddr End) + : Start(Start), End(End) {} + ExecutorAddrRange(ExecutorAddr Start, ExecutorAddrDiff Size) + : Start(Start), End(Start + Size) {} - bool empty() const { return StartAddress == EndAddress; } - ExecutorAddrDiff size() const { return EndAddress - StartAddress; } + bool empty() const { return Start == End; } + ExecutorAddrDiff size() const { return End - Start; } + + friend bool operator==(const ExecutorAddrRange &LHS, + const ExecutorAddrRange &RHS) { + return LHS.Start == RHS.Start && LHS.End == RHS.End; + } + friend bool operator!=(const ExecutorAddrRange &LHS, + const ExecutorAddrRange &RHS) { + return !(LHS == RHS); + } + bool contains(ExecutorAddr Addr) const { return Start <= Addr && Addr < End; } + bool overlaps(const ExecutorAddrRange &Other) { + return !(Other.End <= Start || End <= Other.Start); + } template span toSpan() const { assert(size().getValue() % sizeof(T) == 0 && "AddressRange is not a multiple of sizeof(T)"); - return span(StartAddress.toPtr(), size().getValue() / sizeof(T)); + return span(Start.toPtr(), size().getValue() / sizeof(T)); } - ExecutorAddr StartAddress; - ExecutorAddr EndAddress; + ExecutorAddr Start; + ExecutorAddr End; }; /// SPS serializatior for ExecutorAddr. @@ -178,18 +193,18 @@ template <> class SPSSerializationTraits { public: static size_t size(const ExecutorAddrRange &Value) { - return SPSArgList::size( - Value.StartAddress, Value.EndAddress); + return SPSArgList::size(Value.Start, + Value.End); } static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddrRange &Value) { return SPSArgList::serialize( - BOB, Value.StartAddress, Value.EndAddress); + BOB, Value.Start, Value.End); } static bool deserialize(SPSInputBuffer &BIB, ExecutorAddrRange &Value) { return SPSArgList::deserialize( - BIB, Value.StartAddress, Value.EndAddress); + BIB, Value.Start, Value.End); } }; diff --git a/compiler-rt/lib/orc/macho_platform.cpp b/compiler-rt/lib/orc/macho_platform.cpp index 62629215..fa38a85 100644 --- a/compiler-rt/lib/orc/macho_platform.cpp +++ b/compiler-rt/lib/orc/macho_platform.cpp @@ -93,7 +93,7 @@ Error validatePointerSectionExtent(const char *SectionName, if (SE.size().getValue() % sizeof(uintptr_t)) { std::ostringstream ErrMsg; ErrMsg << std::hex << "Size of " << SectionName << " 0x" - << SE.StartAddress.getValue() << " -- 0x" << SE.EndAddress.getValue() + << SE.Start.getValue() << " -- 0x" << SE.End.getValue() << " is not a pointer multiple"; return make_error(ErrMsg.str()); } @@ -113,7 +113,7 @@ Error registerObjCSelectors( return Err; fprintf(stderr, "Processing selrefs section at 0x%llx\n", - ObjCSelRefs.StartAddress.getValue()); + ObjCSelRefs.Start.getValue()); for (uintptr_t SelEntry : ObjCSelRefs.toSpan()) { const char *SelName = reinterpret_cast(SelEntry); fprintf(stderr, "Registering selector \"%s\"\n", SelName); @@ -179,8 +179,8 @@ Error registerSwift5Protocols( for (const auto &Swift5Protocols : Swift5ProtocolSections) swift_registerProtocols( - Swift5Protocols.StartAddress.toPtr(), - Swift5Protocols.EndAddress.toPtr()); + Swift5Protocols.Start.toPtr(), + Swift5Protocols.End.toPtr()); return Error::success(); } @@ -196,8 +196,8 @@ Error registerSwift5ProtocolConformances( for (const auto &ProtoConfSec : Swift5ProtocolConformanceSections) swift_registerProtocolConformances( - ProtoConfSec.StartAddress.toPtr(), - ProtoConfSec.EndAddress.toPtr()); + ProtoConfSec.Start.toPtr(), + ProtoConfSec.End.toPtr()); return Error::success(); } @@ -325,11 +325,11 @@ void MachOPlatformRuntimeState::destroy() { Error MachOPlatformRuntimeState::registerObjectSections( MachOPerObjectSectionsToRegister POSR) { - if (POSR.EHFrameSection.StartAddress) + if (POSR.EHFrameSection.Start) walkEHFrameSection(POSR.EHFrameSection.toSpan(), __register_frame); - if (POSR.ThreadDataSection.StartAddress) { + if (POSR.ThreadDataSection.Start) { if (auto Err = registerThreadDataSection( POSR.ThreadDataSection.toSpan())) return Err; @@ -340,7 +340,7 @@ Error MachOPlatformRuntimeState::registerObjectSections( Error MachOPlatformRuntimeState::deregisterObjectSections( MachOPerObjectSectionsToRegister POSR) { - if (POSR.EHFrameSection.StartAddress) + if (POSR.EHFrameSection.Start) walkEHFrameSection(POSR.EHFrameSection.toSpan(), __deregister_frame); diff --git a/compiler-rt/lib/orc/unittests/CMakeLists.txt b/compiler-rt/lib/orc/unittests/CMakeLists.txt index fbbf7fa..95431e0 100644 --- a/compiler-rt/lib/orc/unittests/CMakeLists.txt +++ b/compiler-rt/lib/orc/unittests/CMakeLists.txt @@ -84,6 +84,7 @@ set(UNITTEST_SOURCES c_api_test.cpp endian_test.cpp error_test.cpp + executor_address_test.cpp extensible_rtti_test.cpp orc_unit_test_main.cpp stl_extras_test.cpp diff --git a/compiler-rt/lib/orc/unittests/executor_address_test.cpp b/compiler-rt/lib/orc/unittests/executor_address_test.cpp new file mode 100644 index 0000000..19a794a --- /dev/null +++ b/compiler-rt/lib/orc/unittests/executor_address_test.cpp @@ -0,0 +1,77 @@ +//===-- extensible_address_test.cpp ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of the ORC runtime. +// +// Note: +// This unit test was adapted from +// llvm/unittests/Support/ExecutorAddressTest.cpp +// +//===----------------------------------------------------------------------===// + +#include "executor_address.h" +#include "gtest/gtest.h" + +using namespace __orc_rt; + +TEST(ExecutorAddrTest, DefaultAndNull) { + // Check that default constructed values and isNull behave as expected. + + ExecutorAddr Default; + ExecutorAddr Null(0); + ExecutorAddr NonNull(1); + + EXPECT_TRUE(Null.isNull()); + EXPECT_EQ(Default, Null); + + EXPECT_FALSE(NonNull.isNull()); + EXPECT_NE(Default, NonNull); +} + +TEST(ExecutorAddrTest, Ordering) { + // Check that ordering operations. + ExecutorAddr A1(1), A2(2); + + EXPECT_LE(A1, A1); + EXPECT_LT(A1, A2); + EXPECT_GT(A2, A1); + EXPECT_GE(A2, A2); +} + +TEST(ExecutorAddrTest, PtrConversion) { + // Test toPtr / fromPtr round-tripping. + int X = 0; + auto XAddr = ExecutorAddr::fromPtr(&X); + int *XPtr = XAddr.toPtr(); + + EXPECT_EQ(XPtr, &X); +} + +TEST(ExecutorAddrTest, AddrRanges) { + ExecutorAddr A0(0), A1(1), A2(2), A3(3); + ExecutorAddrRange R0(A0, A1), R1(A1, A2), R2(A2, A3), R3(A0, A2), R4(A1, A3); + // 012 + // R0: # -- Before R1 + // R1: # -- + // R2: # -- After R1 + // R3: ## -- Overlaps R1 start + // R4: ## -- Overlaps R1 end + + EXPECT_EQ(R1, ExecutorAddrRange(A1, A2)); + EXPECT_EQ(R1, ExecutorAddrRange(A1, ExecutorAddrDiff(1))); + EXPECT_NE(R1, R2); + + EXPECT_TRUE(R1.contains(A1)); + EXPECT_FALSE(R1.contains(A0)); + EXPECT_FALSE(R1.contains(A2)); + + EXPECT_FALSE(R1.overlaps(R0)); + EXPECT_FALSE(R1.overlaps(R2)); + EXPECT_TRUE(R1.overlaps(R3)); + EXPECT_TRUE(R1.overlaps(R4)); +} -- 2.7.4