From 588991f6df3d6813378721166a7260990835817e Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 19 Apr 2023 17:06:56 -0400 Subject: Make SourceMap a value type (#2812) * #include an absolute path didn't work - because paths were taken to always be relative. * Moved JSON source map writing logic to JSONSourceMapUtil. * Use ArtifactHandler to read/write SourceMaps. Use ObjectCastableAdapter to hold SourceMap Only serialize SourceMap <-> JSON on demand. * Make some types swappable. * BoxValue impl. * Added asBoxValue. * Remove const get funcs. * Fix typo in asBoxValue. * Fix another typo in asBoxValue. * Slightly simplify conversion to blob of SourceMap. * Small fix for asBoxValue --- source/core/slang-castable.cpp | 31 ----------- source/core/slang-castable.h | 94 +++++++++++++++++++++++---------- source/core/slang-dictionary.h | 15 ++++++ source/core/slang-free-list.cpp | 16 ++++++ source/core/slang-free-list.h | 3 ++ source/core/slang-memory-arena.cpp | 17 ++++++ source/core/slang-memory-arena.h | 3 ++ source/core/slang-string-slice-pool.cpp | 8 +++ source/core/slang-string-slice-pool.h | 3 ++ source/core/slang-uint-set.h | 4 ++ 10 files changed, 135 insertions(+), 59 deletions(-) (limited to 'source/core') diff --git a/source/core/slang-castable.cpp b/source/core/slang-castable.cpp index 6b7644bf2..f3c6541dd 100644 --- a/source/core/slang-castable.cpp +++ b/source/core/slang-castable.cpp @@ -20,37 +20,6 @@ namespace Slang { return castable; } -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ObjectCastableAdapter !!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -void* ObjectCastableAdapter::castAs(const Guid& guid) -{ - if (auto intf = getInterface(guid)) - { - return intf; - } - return getObject(guid); -} - -void* ObjectCastableAdapter::getInterface(const Guid& guid) -{ - if (guid == ISlangUnknown::getTypeGuid() || - guid == ICastable::getTypeGuid() || - guid == IObjectCastableAdapter::getTypeGuid()) - { - return static_cast(this); - } - return nullptr; -} - -void* ObjectCastableAdapter::getObject(const Guid& guid) -{ - if (guid == m_containedGuid) - { - return m_contained; - } - return nullptr; -} - /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! UnknownCastableAdapter !!!!!!!!!!!!!!!!!!!!!!!!!!! */ void* UnknownCastableAdapter::castAs(const Guid& guid) diff --git a/source/core/slang-castable.h b/source/core/slang-castable.h index 4f4fdc940..dc6c49a89 100644 --- a/source/core/slang-castable.h +++ b/source/core/slang-castable.h @@ -35,18 +35,36 @@ SLANG_FORCE_INLINE T* as(ICastable* castable) return nullptr; } -/* Adapter interface to make non castable ref counted object usable as ICastable */ -class IObjectCastableAdapter : public ICastable +/* An interface for boxing values */ +class IBoxValueBase: public ICastable { SLANG_COM_INTERFACE(0x8b4aad81, 0x4934, 0x4a67, { 0xb2, 0xe2, 0xe9, 0x17, 0xfc, 0x29, 0x12, 0x54 }); /// Get the contained object - virtual SLANG_NO_THROW RefObject* SLANG_MCALL getContained() = 0; + virtual SLANG_NO_THROW void* SLANG_MCALL getValuePtr() = 0; /// Get the guid that represents the contained ref object - virtual SLANG_NO_THROW SlangUUID getContainedGuid() = 0; + virtual SLANG_NO_THROW SlangUUID SLANG_MCALL getValueTypeGuid() = 0; }; -class ObjectCastableAdapter : public ComBaseObject, public IObjectCastableAdapter +template +class IBoxValue : public IBoxValueBase +{ + public: + + SLANG_FORCE_INLINE T& get() { return *reinterpret_cast(getValuePtr()); } + SLANG_FORCE_INLINE T* getPtr() { return reinterpret_cast(getValuePtr()); } +}; + +// Cast into a boxed value type +template +SLANG_FORCE_INLINE IBoxValue* asBoxValue(ICastable* castable) +{ + IBoxValueBase* base = as(castable); + return (base && base->getValueTypeGuid() == T::getTypeGuid()) ? static_cast*>(base) : nullptr; +} + +template +class BoxValue : public ComBaseObject, public IBoxValue { public: SLANG_COM_BASE_IUNKNOWN_ALL @@ -54,39 +72,59 @@ public: // ICastable SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE; - // IObjectCastableAdapter - virtual SLANG_NO_THROW RefObject* SLANG_MCALL getContained() SLANG_OVERRIDE { return m_contained; } - virtual SlangUUID getContainedGuid() SLANG_OVERRIDE { return m_containedGuid; } + // IBoxValue + virtual SLANG_NO_THROW void* SLANG_MCALL getValuePtr() SLANG_OVERRIDE { return &m_value; } + virtual SlangUUID SLANG_MCALL getValueTypeGuid() SLANG_OVERRIDE { return T::getTypeGuid(); } - template - explicit ObjectCastableAdapter(T* ptr) - { - m_containedGuid = T::getTypeGuid(); - m_contained = ptr; - } - template - explicit ObjectCastableAdapter(const RefPtr& ptr) - { - m_containedGuid = T::getTypeGuid(); - m_contained = ptr; - } + BoxValue() {} - ObjectCastableAdapter(RefObject* obj, const Guid& containedGuid) : - m_contained(obj), - m_containedGuid(containedGuid) + explicit BoxValue(const T& rhs): + m_value(rhs) { - SLANG_ASSERT(obj); } protected: - void* getInterface(const Guid& guid); + void* getInterface(const Guid& guid); void* getObject(const Guid& guid); - - RefPtr m_contained; - SlangUUID m_containedGuid; + + T m_value; }; +// ------------------------------------------------------------ +template +void* BoxValue::getInterface(const Guid& guid) +{ + if (guid == ISlangUnknown::getTypeGuid() || + guid == ICastable::getTypeGuid() || + guid == IBoxValueBase::getTypeGuid()) + { + return static_cast(this); + } + return nullptr; +} + +// ------------------------------------------------------------ +template +void* BoxValue::getObject(const Guid& guid) +{ + if (guid == T::getTypeGuid()) + { + return &m_value; + } + return nullptr; +} +// ------------------------------------------------------------ +template +void* BoxValue::castAs(const Guid& guid) +{ + if (auto ptr = getObject(guid)) + { + return ptr; + } + return getInterface(guid); +} + /* Adapter interface to make a non castable types work as ICastable */ class IUnknownCastableAdapter : public ICastable { diff --git a/source/core/slang-dictionary.h b/source/core/slang-dictionary.h index fffec9640..0839a649c 100644 --- a/source/core/slang-dictionary.h +++ b/source/core/slang-dictionary.h @@ -83,6 +83,7 @@ namespace Slang public: typedef TValue ValueType; typedef TKey KeyType; + typedef Dictionary ThisType; private: inline int GetProbeOffset(int /*probeId*/) const { @@ -481,6 +482,10 @@ namespace Slang { return _count; } + + /// Swap this with rhs + void swapWith(ThisType& rhs); + private: template void Init(const KeyValuePair & kvPair, Args... args) @@ -543,6 +548,16 @@ namespace Slang } }; + // --------------------------------------------------------- + template + void Dictionary::swapWith(ThisType& rhs) + { + Swap(bucketSizeMinusOne, rhs.bucketSizeMinusOne); + Swap(_count, rhs._count); + marks.swapWith(rhs.marks); + Swap(hashMap, rhs.hashMap); + } + class _DummyClass {}; diff --git a/source/core/slang-free-list.cpp b/source/core/slang-free-list.cpp index 4bada9434..d364b548c 100644 --- a/source/core/slang-free-list.cpp +++ b/source/core/slang-free-list.cpp @@ -63,6 +63,22 @@ void FreeList::init(size_t elementSize, size_t alignment, size_t elemsPerBlock) _init(elementSize, alignment, elemsPerBlock); } +void FreeList::swapWith(ThisType& rhs) +{ + Swap(m_top, rhs.m_top); + Swap(m_end, rhs.m_end); + + Swap(m_activeBlocks, rhs.m_activeBlocks); + Swap(m_freeBlocks, rhs.m_freeBlocks); + + Swap(m_freeElements, rhs.m_freeElements); + + Swap(m_elementSize, rhs.m_elementSize); + Swap(m_alignment, rhs.m_alignment); + Swap(m_blockSize, rhs.m_blockSize); + Swap(m_blockAllocationSize, rhs.m_blockAllocationSize); +} + void FreeList::_deallocateBlocks(Block* block) { while (block) diff --git a/source/core/slang-free-list.h b/source/core/slang-free-list.h index ee0158279..090c13613 100644 --- a/source/core/slang-free-list.h +++ b/source/core/slang-free-list.h @@ -69,6 +69,9 @@ class FreeList /// Initialize. If called on an already initialized heap, the heap will be deallocated. void init(size_t elementSize, size_t alignment, size_t elemsPerBlock); + /// Swap this with rhs + void swapWith(ThisType& rhs); + /// Default Ctor FreeList() { _init(); } /// Ctor diff --git a/source/core/slang-memory-arena.cpp b/source/core/slang-memory-arena.cpp index 6fc6c0c3f..6a13addb6 100644 --- a/source/core/slang-memory-arena.cpp +++ b/source/core/slang-memory-arena.cpp @@ -23,6 +23,7 @@ MemoryArena::~MemoryArena() reset(); } + MemoryArena::MemoryArena(size_t blockPayloadSize, size_t blockAlignment) { _initialize(blockPayloadSize, blockAlignment); @@ -62,6 +63,22 @@ void MemoryArena::_initialize(size_t blockPayloadSize, size_t alignment) _resetCurrentBlock(); } +void MemoryArena::swapWith(ThisType& rhs) +{ + Swap(m_start, rhs.m_start); + Swap(m_end, rhs.m_end); + Swap(m_current, rhs.m_current); + + Swap(m_blockPayloadSize, rhs.m_blockPayloadSize); + Swap(m_blockAllocSize, rhs.m_blockAllocSize); + Swap(m_blockAlignment, rhs.m_blockAlignment); + + Swap(m_availableBlocks, rhs.m_availableBlocks); + Swap(m_usedBlocks, rhs.m_usedBlocks); + + m_blockFreeList.swapWith(rhs.m_blockFreeList); +} + void MemoryArena::_resetCurrentBlock() { m_start = nullptr; diff --git a/source/core/slang-memory-arena.h b/source/core/slang-memory-arena.h index f63a48413..a947de5a2 100644 --- a/source/core/slang-memory-arena.h +++ b/source/core/slang-memory-arena.h @@ -149,6 +149,9 @@ public: /// Add a block such that it will be freed when everything else is freed. void addExternalBlock(void* data, size_t size); + // Swap this with rhs + void swapWith(ThisType& rhs); + /// Default Ctor MemoryArena(); /// Construct with block size and alignment. Block alignment must be a power of 2. diff --git a/source/core/slang-string-slice-pool.cpp b/source/core/slang-string-slice-pool.cpp index a0af3ba68..45cc811a3 100644 --- a/source/core/slang-string-slice-pool.cpp +++ b/source/core/slang-string-slice-pool.cpp @@ -41,6 +41,14 @@ void StringSlicePool::clear() } } +void StringSlicePool::swapWith(ThisType& rhs) +{ + Swap(m_style, rhs.m_style); + m_slices.swapWith(rhs.m_slices); + m_map.swapWith(rhs.m_map); + m_arena.swapWith(rhs.m_arena); +} + StringSlicePool::Handle StringSlicePool::add(const Slice& slice) { const Handle* handlePtr = m_map.TryGetValue(slice); diff --git a/source/core/slang-string-slice-pool.h b/source/core/slang-string-slice-pool.h index 15d204468..90586a527 100644 --- a/source/core/slang-string-slice-pool.h +++ b/source/core/slang-string-slice-pool.h @@ -99,6 +99,9 @@ public: /// Get the index of the first added handle Index getFirstAddedIndex() const { return m_style == Style::Default ? kDefaultHandlesCount : 0; } + /// Swap this with rhs + void swapWith(ThisType& rhs); + /// Ctor explicit StringSlicePool(Style style); diff --git a/source/core/slang-uint-set.h b/source/core/slang-uint-set.h index 334e7ebe8..f2c573865 100644 --- a/source/core/slang-uint-set.h +++ b/source/core/slang-uint-set.h @@ -15,6 +15,7 @@ namespace Slang class UIntSet { public: + typedef UIntSet ThisType; typedef uint32_t Element; ///< Type that holds the bits to say if value is present UIntSet() {} @@ -64,6 +65,9 @@ public: /// bool isEmpty() const; + /// Swap this with rhs + void swapWith(ThisType& rhs) { m_buffer.swapWith(rhs.m_buffer); } + /// Store the union of set1 and set2 in outRs static void calcUnion(UIntSet& outRs, const UIntSet& set1, const UIntSet& set2); /// Store the intersection of set1 and set2 in outRs -- cgit v1.2.3