summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/ir-insts.h4
-rw-r--r--source/slang/ir-serialize.cpp440
-rw-r--r--source/slang/ir-serialize.h140
-rw-r--r--source/slang/ir.h27
4 files changed, 352 insertions, 259 deletions
diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h
index 8d1c4708a..05ccd76e7 100644
--- a/source/slang/ir-insts.h
+++ b/source/slang/ir-insts.h
@@ -873,13 +873,13 @@ struct IRBuilder
template <typename T>
T* addRefObjectToFree(T* ptr)
{
- getModule()->addRefObjectToFree(ptr);
+ getModule()->getObjectScopeManager()->addMaybeNull(ptr);
return ptr;
}
StringRepresentation* addStringToFree(const String& string)
{
StringRepresentation* stringRep = string.getStringRepresentation();
- getModule()->addRefObjectToFree(stringRep);
+ getModule()->getObjectScopeManager()->addMaybeNull(stringRep);
return stringRep;
}
diff --git a/source/slang/ir-serialize.cpp b/source/slang/ir-serialize.cpp
index e204944a7..e2fd6d3f8 100644
--- a/source/slang/ir-serialize.cpp
+++ b/source/slang/ir-serialize.cpp
@@ -81,13 +81,183 @@ struct CharReader
} // anonymous
-static UnownedStringSlice asStringSlice(const PrefixString* prefixString)
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StringRepresentationCache !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+StringRepresentationCache::StringRepresentationCache():
+ m_stringTable(nullptr),
+ m_namePool(nullptr),
+ m_scopeManager(nullptr)
+{
+}
+
+void StringRepresentationCache::init(const List<char>* stringTable, NamePool* namePool, ObjectScopeManager* scopeManager)
+{
+ m_stringTable = stringTable;
+ m_namePool = namePool;
+ m_scopeManager = scopeManager;
+
+ // Decode the table
+ m_entries.SetSize(StringSlicePool::kNumDefaultHandles);
+ SLANG_COMPILE_TIME_ASSERT(StringSlicePool::kNumDefaultHandles == 2);
+
+ {
+ Entry& entry = m_entries[0];
+ entry.m_numChars = 0;
+ entry.m_startIndex = 0;
+ entry.m_object = nullptr;
+ }
+ {
+ Entry& entry = m_entries[1];
+ entry.m_numChars = 0;
+ entry.m_startIndex = 0;
+ entry.m_object = nullptr;
+ }
+
+ {
+ const char* start = stringTable->begin();
+ const char* cur = start;
+ const char* end = stringTable->end();
+
+ while (cur < end)
+ {
+ CharReader reader(cur);
+ const int len = GetUnicodePointFromUTF8(reader);
+
+ Entry entry;
+ entry.m_startIndex = uint32_t(reader.m_pos - start);
+ entry.m_numChars = len;
+ entry.m_object = nullptr;
+
+ m_entries.Add(entry);
+
+ cur = reader.m_pos + len;
+ }
+ }
+
+ m_entries.Compress();
+}
+
+Name* StringRepresentationCache::getName(Handle handle)
+{
+ if (handle == StringSlicePool::kNullHandle)
+ {
+ return nullptr;
+ }
+
+ Entry& entry = m_entries[int(handle)];
+ if (entry.m_object)
+ {
+ Name* name = dynamic_cast<Name*>(entry.m_object);
+ if (name)
+ {
+ return name;
+ }
+ StringRepresentation* stringRep = static_cast<StringRepresentation*>(entry.m_object);
+ // Promote it to a name
+ name = m_namePool->getName(String(stringRep));
+ entry.m_object = name;
+ return name;
+ }
+
+ Name* name = m_namePool->getName(String(getStringSlice(handle)));
+ entry.m_object = name;
+ return name;
+}
+
+String StringRepresentationCache::getString(Handle handle)
+{
+ return String(getStringRepresentation(handle));
+}
+
+UnownedStringSlice StringRepresentationCache::getStringSlice(Handle handle) const
+{
+ const Entry& entry = m_entries[int(handle)];
+ const char* start = m_stringTable->begin();
+
+ return UnownedStringSlice(start + entry.m_startIndex, int(entry.m_numChars));
+}
+
+StringRepresentation* StringRepresentationCache::getStringRepresentation(Handle handle)
+{
+ if (handle == StringSlicePool::kNullHandle || handle == StringSlicePool::kEmptyHandle)
+ {
+ return nullptr;
+ }
+
+ Entry& entry = m_entries[int(handle)];
+ if (entry.m_object)
+ {
+ Name* name = dynamic_cast<Name*>(entry.m_object);
+ if (name)
+ {
+ return name->text.getStringRepresentation();
+ }
+ return static_cast<StringRepresentation*>(entry.m_object);
+ }
+
+ const UnownedStringSlice slice = getStringSlice(handle);
+ const UInt size = slice.size();
+
+ StringRepresentation* stringRep = StringRepresentation::createWithCapacityAndLength(size, size);
+ memcpy(stringRep->getData(), slice.begin(), size);
+ entry.m_object = stringRep;
+
+ // Keep the StringRepresentation in scope
+ m_scopeManager->add(stringRep);
+
+ return stringRep;
+}
+
+char* StringRepresentationCache::getCStr(Handle handle)
+{
+ // It turns out StringRepresentation is always 0 terminated, so can just use that
+ StringRepresentation* rep = getStringRepresentation(handle);
+ return rep->getData();
+}
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SerialStringTableUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+/* static */void SerialStringTableUtil::encodeStringTable(const StringSlicePool& pool, List<char>& stringTable)
+{
+ // Skip the default handles -> nothing is encoded via them
+ return encodeStringTable(pool.getSlices().begin() + StringSlicePool::kNumDefaultHandles, pool.getNumSlices() - StringSlicePool::kNumDefaultHandles, stringTable);
+}
+
+/* static */void SerialStringTableUtil::encodeStringTable(const UnownedStringSlice* slices, size_t numSlices, List<char>& stringTable)
+{
+ stringTable.Clear();
+ for (size_t i = 0; i < numSlices; ++i)
+ {
+ const UnownedStringSlice slice = slices[i];
+ const int len = int(slice.size());
+
+ // We need to write into the the string array
+ char prefixBytes[6];
+ const int numPrefixBytes = EncodeUnicodePointToUTF8(prefixBytes, len);
+ const int baseIndex = int(stringTable.Count());
+
+ stringTable.SetSize(baseIndex + numPrefixBytes + len);
+
+ char* dst = stringTable.begin() + baseIndex;
+
+ memcpy(dst, prefixBytes, numPrefixBytes);
+ memcpy(dst + numPrefixBytes, slice.begin(), len);
+ }
+}
+
+/* static */void SerialStringTableUtil::decodeStringTable(const List<char>& stringTable, List<UnownedStringSlice>& slices)
{
- const char* prefix = (char*)prefixString;
+ const char* start = stringTable.begin();
+ const char* cur = start;
+ const char* end = stringTable.end();
- CharReader reader(prefix);
- const int len = GetUnicodePointFromUTF8(reader);
- return UnownedStringSlice(reader.m_pos, len);
+ while (cur < end)
+ {
+ CharReader reader(cur);
+ const int len = GetUnicodePointFromUTF8(reader);
+ slices.Add(UnownedStringSlice(reader.m_pos, len));
+ cur = reader.m_pos + len;
+ }
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! IRSerialData !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -105,8 +275,15 @@ size_t IRSerialData::calcSizeInBytes() const
_calcArraySize(m_childRuns) +
_calcArraySize(m_decorationRuns) +
_calcArraySize(m_externalOperands) +
- _calcArraySize(m_rawSourceLocs) +
- _calcArraySize(m_strings);
+ _calcArraySize(m_stringTable) +
+ /* Raw source locs */
+ _calcArraySize(m_rawSourceLocs) +
+ /* Debug */
+ _calcArraySize(m_debugSourceFiles) +
+ _calcArraySize(m_debugLineOffsets) +
+ _calcArraySize(m_debugViewEntries) +
+ _calcArraySize(m_debugLocRuns) +
+ _calcArraySize(m_debugStrings);
}
void IRSerialData::clear()
@@ -120,9 +297,16 @@ void IRSerialData::clear()
m_externalOperands.Clear();
m_rawSourceLocs.Clear();
- m_strings.SetSize(2);
- m_strings[int(kNullStringIndex)] = 0;
- m_strings[int(kEmptyStringIndex)] = 0;
+ // Debug data
+ m_debugSourceFiles.Clear();
+ m_debugLineOffsets.Clear();
+ m_debugViewEntries.Clear();
+ m_debugLocRuns.Clear();
+ m_debugStrings.Clear();
+
+ m_stringTable.SetSize(2);
+ m_stringTable[int(kNullStringIndex)] = 0;
+ m_stringTable[int(kEmptyStringIndex)] = 0;
m_decorationBaseIndex = 0;
}
@@ -166,7 +350,7 @@ bool IRSerialData::operator==(const ThisType& rhs) const
_isEqual(m_decorationRuns, rhs.m_decorationRuns) &&
_isEqual(m_externalOperands, rhs.m_externalOperands) &&
_isEqual(m_rawSourceLocs, rhs.m_rawSourceLocs) &&
- _isEqual(m_strings, rhs.m_strings));
+ _isEqual(m_stringTable, rhs.m_stringTable));
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! IRSerialWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -208,17 +392,28 @@ void IRSerialWriter::_addInstruction(IRInst* inst)
}
}
-IRSerialData::StringIndex IRSerialWriter::getStringIndex(Name* name)
-{
- return name ? getStringIndex(name->text.getStringRepresentation()) : Ser::kNullStringIndex;
-}
-
-UnownedStringSlice IRSerialWriter::getStringSlice(Ser::StringIndex index) const
+// Find a view index that matches the view by file (and perhaps other characteristics in the future)
+int _findSourceViewIndex(const List<SourceView*>& viewsIn, SourceView* view)
{
- Ser::StringOffset offset = m_stringStarts[int(index)];
- return asStringSlice((const PrefixString*)(m_serialData->m_strings.begin() + int(offset)));
+ const int numViews = int(viewsIn.Count());
+ SourceView*const* views = viewsIn.begin();
+
+ SourceFile* sourceFile = view->getSourceFile();
+
+ for (int i = 0; i < numViews; ++i)
+ {
+ SourceView* curView = views[i];
+ // For now we just match on source file
+ if (curView->getSourceFile() == sourceFile)
+ {
+ // It's a hit
+ return i;
+ }
+ }
+ return -1;
}
+
Result IRSerialWriter::write(IRModule* module, SourceManager* sourceManager, OptionFlags options, IRSerialData* serialData)
{
typedef Ser::Inst::PayloadType PayloadType;
@@ -229,23 +424,6 @@ Result IRSerialWriter::write(IRModule* module, SourceManager* sourceManager, Opt
serialData->clear();
- // Set up the stringStarts
- m_stringStarts.SetSize(2);
- m_stringStarts[0] = Ser::StringOffset(0); // Null
- m_stringStarts[1] = Ser::StringOffset(1); // Empty
- SLANG_ASSERT(serialData->m_strings.Count() == 2);
-
- // We'll keep StringRepresentations in scope (and for simplicity keep in order of StringIndex)
- m_scopeStrings.SetSize(2);
- m_scopeStrings[0] = nullptr;
- m_scopeStrings[1] = nullptr;
-
- m_stringMap.Clear();
-
- // Add the empty string index.
- // We can't add the null string index, because that doesn't have any meaning as an UnownedStringSlice
- m_stringMap.Add(UnownedStringSlice(""), Ser::kEmptyStringIndex);
-
// We reserve 0 for null
m_insts.Clear();
m_insts.Add(nullptr);
@@ -556,6 +734,12 @@ Result IRSerialWriter::write(IRModule* module, SourceManager* sourceManager, Opt
}
}
+ // Convert strings into a string table
+ {
+ SerialStringTableUtil::encodeStringTable(m_stringSlicePool, serialData->m_stringTable);
+ }
+
+
// If the option to use RawSourceLocations is enabled, serialize out as is
if (options & OptionFlag::RawSourceLocation)
{
@@ -571,80 +755,11 @@ Result IRSerialWriter::write(IRModule* module, SourceManager* sourceManager, Opt
dstLocs[i] = Ser::RawSourceLoc(srcInst->sourceLoc.getRaw());
}
}
-
+
m_serialData = nullptr;
return SLANG_OK;
}
-IRSerialData::StringIndex IRSerialWriter::getStringIndex(StringRepresentation* rep)
-{
- if (rep == nullptr)
- {
- return Ser::kNullStringIndex;
- }
-
- const UnownedStringSlice slice(rep->getData(), rep->getLength());
- const int len = int(rep->getLength());
-
- Ser::StringIndex index;
- if (m_stringMap.TryGetValue(slice, index))
- {
- return index;
- }
-
- // We need to write into the the string array
- char prefixBytes[6];
- const int numPrefixBytes = EncodeUnicodePointToUTF8(prefixBytes, len);
- const int baseIndex = int(m_serialData->m_strings.Count());
-
- m_serialData->m_strings.SetSize(baseIndex + numPrefixBytes + len);
-
- char* dst = m_serialData->m_strings.begin() + baseIndex;
-
- memcpy(dst, prefixBytes, numPrefixBytes);
- memcpy(dst + numPrefixBytes, slice.begin(), len);
-
- // We need to add 1, because the 0 is used for null, which is not in the map
- const Ser::StringIndex stringIndex = Ser::StringIndex(m_stringMap.Count() + 1);
-
- SLANG_ASSERT(stringIndex == Ser::StringIndex(m_scopeStrings.Count()));
- // Make sure the rep stays in scope (because the UnownedStringSlice is pointing to it's contents)
- m_scopeStrings.Add(rep);
-
- // Add the start offset
- m_stringStarts.Add(Ser::StringOffset(baseIndex));
- m_stringMap.Add(slice, stringIndex);
-
- return stringIndex;
-}
-
-IRSerialData::StringIndex IRSerialWriter::getStringIndex(const char* chars)
-{
- if (!chars)
- {
- return Ser::kNullStringIndex;
- }
- if (chars[0] == 0)
- {
- return Ser::kEmptyStringIndex;
- }
-
- // Get as a StringRepresentation
- String string(chars);
- return getStringIndex(string.getStringRepresentation());
-}
-
-IRSerialData::StringIndex IRSerialWriter::getStringIndex(const UnownedStringSlice& slice)
-{
- const int len = int(slice.size());
- if (len <= 0)
- {
- return Ser::kEmptyStringIndex;
- }
- String string(slice);
- return getStringIndex(string.getStringRepresentation());
-}
-
template <typename T>
static size_t _calcChunkSize(IRSerialBinary::CompressionType compressionType, const List<T>& array)
{
@@ -966,7 +1081,7 @@ static size_t _calcInstChunkSize(IRSerialBinary::CompressionType compressionType
_calcChunkSize(compressionType, data.m_childRuns) +
_calcChunkSize(compressionType, data.m_decorationRuns) +
_calcChunkSize(compressionType, data.m_externalOperands) +
- _calcChunkSize(Bin::CompressionType::None, data.m_strings) +
+ _calcChunkSize(Bin::CompressionType::None, data.m_stringTable) +
_calcChunkSize(Bin::CompressionType::None, data.m_rawSourceLocs);
{
@@ -990,7 +1105,7 @@ static size_t _calcInstChunkSize(IRSerialBinary::CompressionType compressionType
SLANG_RETURN_ON_FAIL(_writeArrayChunk(compressionType, Bin::kChildRunFourCc, data.m_childRuns, stream));
SLANG_RETURN_ON_FAIL(_writeArrayChunk(compressionType, Bin::kDecoratorRunFourCc, data.m_decorationRuns, stream));
SLANG_RETURN_ON_FAIL(_writeArrayChunk(compressionType, Bin::kExternalOperandsFourCc, data.m_externalOperands, stream));
- SLANG_RETURN_ON_FAIL(_writeArrayChunk(Bin::CompressionType::None, Bin::kStringFourCc, data.m_strings, stream));
+ SLANG_RETURN_ON_FAIL(_writeArrayChunk(Bin::CompressionType::None, Bin::kStringFourCc, data.m_stringTable, stream));
SLANG_RETURN_ON_FAIL(_writeArrayChunk(Bin::CompressionType::None, Bin::kUInt32SourceLocFourCc, data.m_rawSourceLocs, stream));
@@ -1345,7 +1460,7 @@ int64_t _calcChunkTotalSize(const IRSerialBinary::Chunk& chunk)
}
case Bin::kStringFourCc:
{
- SLANG_RETURN_ON_FAIL(_readArrayUncompressedChunk(slangHeader, chunk, stream, &bytesRead, dataOut->m_strings));
+ SLANG_RETURN_ON_FAIL(_readArrayUncompressedChunk(slangHeader, chunk, stream, &bytesRead, dataOut->m_stringTable));
remainingBytes -= _calcChunkTotalSize(chunk);
break;
}
@@ -1367,85 +1482,6 @@ int64_t _calcChunkTotalSize(const IRSerialBinary::Chunk& chunk)
return SLANG_OK;
}
-Name* IRSerialReader::getName(Ser::StringIndex index)
-{
- if (index == Ser::kNullStringIndex)
- {
- return nullptr;
- }
-
- StringRepresentation* rep = getStringRepresentation(index);
- String string(rep);
- Session* session = m_module->getSession();
-
- return session->getNameObj(string);
-}
-
-String IRSerialReader::getString(Ser::StringIndex index)
-{
- return String(getStringRepresentation(index));
-}
-
-UnownedStringSlice IRSerialReader::getStringSlice(Ser::StringOffset offset)
-{
- return asStringSlice((PrefixString*)(m_serialData->m_strings.begin() + int(offset)));
-}
-
-StringRepresentation* IRSerialReader::getStringRepresentation(Ser::StringIndex index)
-{
- if (index == Ser::kNullStringIndex)
- {
- return nullptr;
- }
-
- StringRepresentation* rep = m_stringRepresentationCache[int(index)];
- if (rep)
- {
- return rep;
- }
-
- const UnownedStringSlice slice = getStringSlice(index);
- String string(slice);
-
- StringRepresentation* stringRep = string.getStringRepresentation();
- m_module->addRefObjectToFree(stringRep);
-
- m_stringRepresentationCache[int(index)] = stringRep;
-
- return stringRep;
-}
-
-char* IRSerialReader::getCStr(Ser::StringIndex index)
-{
- // It turns out StringRepresentation is always 0 terminated, so can just use that
- StringRepresentation* rep = getStringRepresentation(index);
- return rep->getData();
-}
-
-void IRSerialReader::_calcStringStarts()
-{
- m_stringStarts.Clear();
-
- const char* start = m_serialData->m_strings.begin();
- const char* cur = start;
- const char* end = m_serialData->m_strings.end();
-
- while (cur < end)
- {
- m_stringStarts.Add(Ser::StringOffset(cur - start));
-
- CharReader reader(cur);
- const int len = GetUnicodePointFromUTF8(reader);
- cur = reader.m_pos + len;
- }
-
- m_stringRepresentationCache.Clear();
- // Resize cache
- m_stringRepresentationCache.SetSize(m_stringStarts.Count());
- // Make sure all values are null initially
- memset(m_stringRepresentationCache.begin(), 0, sizeof(StringRepresentation*) * m_stringStarts.Count());
-}
-
IRDecoration* IRSerialReader::_createDecoration(const Ser::Inst& srcInst)
{
typedef Ser::Inst::PayloadType PayloadType;
@@ -1478,29 +1514,29 @@ IRDecoration* IRSerialReader::_createDecoration(const Ser::Inst& srcInst)
{
auto decor = createEmptyDecoration<IRTargetDecoration>(m_module);
SLANG_ASSERT(srcInst.m_payloadType == PayloadType::String_1);
- decor->targetName = getStringRepresentation(srcInst.m_payload.m_stringIndices[0]);
+ decor->targetName = m_stringRepresentationCache.getStringRepresentation(StringHandle(srcInst.m_payload.m_stringIndices[0]));
return decor;
}
case kIRDecorationOp_TargetIntrinsic:
{
auto decor = createEmptyDecoration<IRTargetIntrinsicDecoration>(m_module);
SLANG_ASSERT(srcInst.m_payloadType == PayloadType::String_2);
- decor->targetName = getStringRepresentation(srcInst.m_payload.m_stringIndices[0]);
- decor->definition = getStringRepresentation(srcInst.m_payload.m_stringIndices[1]);
+ decor->targetName = m_stringRepresentationCache.getStringRepresentation(StringHandle(srcInst.m_payload.m_stringIndices[0]));
+ decor->definition = m_stringRepresentationCache.getStringRepresentation(StringHandle(srcInst.m_payload.m_stringIndices[1]));
return decor;
}
case kIRDecorationOp_GLSLOuterArray:
{
auto decor = createEmptyDecoration<IRGLSLOuterArrayDecoration>(m_module);
SLANG_ASSERT(srcInst.m_payloadType == PayloadType::String_1);
- decor->outerArrayName = getCStr(srcInst.m_payload.m_stringIndices[0]);
+ decor->outerArrayName = m_stringRepresentationCache.getCStr(StringHandle(srcInst.m_payload.m_stringIndices[0]));
return decor;
}
case kIRDecorationOp_Semantic:
{
auto decor = createEmptyDecoration<IRSemanticDecoration>(m_module);
SLANG_ASSERT(srcInst.m_payloadType == PayloadType::String_1);
- decor->semanticName = getName(srcInst.m_payload.m_stringIndices[0]);
+ decor->semanticName = m_stringRepresentationCache.getName(StringHandle(srcInst.m_payload.m_stringIndices[0]));
return decor;
}
case kIRDecorationOp_InterpolationMode:
@@ -1514,7 +1550,7 @@ IRDecoration* IRSerialReader::_createDecoration(const Ser::Inst& srcInst)
{
auto decor = createEmptyDecoration<IRNameHintDecoration>(m_module);
SLANG_ASSERT(srcInst.m_payloadType == PayloadType::String_1);
- decor->name = getName(srcInst.m_payload.m_stringIndices[0]);
+ decor->name = m_stringRepresentationCache.getName(StringHandle(srcInst.m_payload.m_stringIndices[0]));
return decor;
}
case kIRDecorationOp_VulkanRayPayload:
@@ -1533,7 +1569,7 @@ IRDecoration* IRSerialReader::_createDecoration(const Ser::Inst& srcInst)
{
auto decor = createEmptyDecoration<IRRequireGLSLExtensionDecoration>(m_module);
SLANG_ASSERT(srcInst.m_payloadType == PayloadType::String_1);
- decor->extensionName = getStringRepresentation(srcInst.m_payload.m_stringIndices[0]);
+ decor->extensionName = m_stringRepresentationCache.getStringRepresentation(StringHandle(srcInst.m_payload.m_stringIndices[0]));
return decor;
}
case kIRDecorationOp_RequireGLSLVersion:
@@ -1556,13 +1592,15 @@ IRDecoration* IRSerialReader::_createDecoration(const Ser::Inst& srcInst)
typedef Ser::Inst::PayloadType PayloadType;
m_serialData = &data;
- _calcStringStarts();
-
+
auto module = new IRModule();
moduleOut = module;
m_module = module;
module->session = session;
+
+ // Set up the string rep cache
+ m_stringRepresentationCache.init(&data.m_stringTable, session->getNamePool(), module->getObjectScopeManager());
// Add all the instructions
@@ -1613,7 +1651,7 @@ IRDecoration* IRSerialReader::_createDecoration(const Ser::Inst& srcInst)
insts[i] = globalValueInst;
// Set the global value
SLANG_ASSERT(srcInst.m_payloadType == PayloadType::String_1);
- globalValueInst->mangledName = getName(srcInst.m_payload.m_stringIndices[0]);
+ globalValueInst->mangledName = m_stringRepresentationCache.getName(StringHandle(srcInst.m_payload.m_stringIndices[0]));
}
else
{
@@ -1659,7 +1697,7 @@ IRDecoration* IRSerialReader::_createDecoration(const Ser::Inst& srcInst)
{
SLANG_ASSERT(srcInst.m_payloadType == PayloadType::String_1);
- const UnownedStringSlice slice = getStringSlice(srcInst.m_payload.m_stringIndices[0]);
+ const UnownedStringSlice slice = m_stringRepresentationCache.getStringSlice(StringHandle(srcInst.m_payload.m_stringIndices[0]));
const size_t sliceSize = slice.size();
const size_t instSize = prefixSize + SLANG_OFFSET_OF(IRConstant::StringValue, chars) + sliceSize;
@@ -1813,6 +1851,8 @@ IRDecoration* IRSerialReader::_createDecoration(const Ser::Inst& srcInst)
// !!!!!!!!!!!!!!!!!!!!!!!!!!!! Free functions !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+#if 0
+
Result serializeModule(IRModule* module, SourceManager* sourceManager, Stream* stream)
{
IRSerialWriter serializer;
@@ -1837,4 +1877,6 @@ Result readModule(Session* session, Stream* stream, RefPtr<IRModule>& moduleOut)
return reader.read(serialData, session, moduleOut);
}
+#endif
+
} // namespace Slang
diff --git a/source/slang/ir-serialize.h b/source/slang/ir-serialize.h
index 0146765a0..ec560233f 100644
--- a/source/slang/ir-serialize.h
+++ b/source/slang/ir-serialize.h
@@ -5,6 +5,8 @@
#include "../core/basic.h"
#include "../core/stream.h"
+#include "../core/slang-object-scope-manager.h"
+
#include "ir.h"
// For TranslationUnitRequest
@@ -12,6 +14,51 @@
namespace Slang {
+class StringRepresentationCache
+{
+ public:
+ typedef StringSlicePool::Handle Handle;
+
+ struct Entry
+ {
+ uint32_t m_startIndex;
+ uint32_t m_numChars;
+ RefObject* m_object; ///< Could be nullptr, Name, or StringRepresentation.
+ };
+
+ /// Get as a name
+ Name* getName(Handle handle);
+ /// Get as a string
+ String getString(Handle handle);
+ /// Get as string representation
+ StringRepresentation* getStringRepresentation(Handle handle);
+ /// Get as a string slice
+ UnownedStringSlice getStringSlice(Handle handle) const;
+ /// Get as a 0 terminated 'c style' string
+ char* getCStr(Handle handle);
+
+ /// Initialize a cache to use a string table, namePool and scopeManager
+ void init(const List<char>* stringTable, NamePool* namePool, ObjectScopeManager* scopeManager);
+
+ /// Ctor
+ StringRepresentationCache();
+
+ protected:
+ ObjectScopeManager* m_scopeManager;
+ NamePool* m_namePool;
+ const List<char>* m_stringTable;
+ List<Entry> m_entries;
+};
+
+struct SerialStringTableUtil
+{
+ /// Convert a pool into a string table
+ static void encodeStringTable(const StringSlicePool& pool, List<char>& stringTable);
+ static void encodeStringTable(const UnownedStringSlice* slices, size_t numSlices, List<char>& stringTable);
+ /// Converts a pool into a string table, appending the strings to the slices
+ static void decodeStringTable(const List<char>& stringTable, List<UnownedStringSlice>& slicesOut);
+};
+
// Pre-declare
class Name;
@@ -23,13 +70,13 @@ struct IRSerialData
enum class StringIndex : uint32_t;
enum class ArrayIndex : uint32_t;
- enum class RawSourceLoc : SourceLoc::RawValue; ///< This is just to copy over source loc data (ie not strictly serialize)
- enum class StringOffset : uint32_t; ///< Offset into the m_stringsBuffer
+ enum class RawSourceLoc : SourceLoc::RawValue; ///< This is just to copy over source loc data (ie not strictly serialize)
+ enum class StringOffset : uint32_t; ///< Offset into the m_stringsBuffer
typedef uint32_t SizeType;
- static const StringIndex kNullStringIndex = StringIndex(0);
- static const StringIndex kEmptyStringIndex = StringIndex(1);
+ static const StringIndex kNullStringIndex = StringIndex(StringSlicePool::kNullHandle);
+ static const StringIndex kEmptyStringIndex = StringIndex(StringSlicePool::kEmptyHandle);
/// A run of instructions
struct InstRun
@@ -125,6 +172,32 @@ struct IRSerialData
Payload m_payload;
};
+
+ struct DebugSourceFile
+ {
+ uint32_t m_startLoc; ///< Start of the location range
+ uint32_t m_endLoc; ///< The end of the location range
+
+ uint32_t m_pathIndex; ///< Path associated
+
+ uint32_t m_numLocRuns; ///< The number of location runs associated with this source file
+ uint32_t m_numLineOffsets; ///< The number of offsets associated with the file
+ uint32_t m_numDebugViewEntries; ///< The number of debug view entries
+ };
+
+ struct DebugViewEntry
+ {
+ uint32_t m_startLoc; ///< Where does this entry begin?
+ uint32_t m_pathIndex; ///< What is the presumed path for this entry. If 0 it means there is no path.
+ int32_t m_lineAdjust; ///< The line adjustment
+ };
+
+ struct DebugLocRun
+ {
+ uint32_t m_sourceLoc; ///< The location
+ uint32_t startInstIndex; ///< The start instruction index
+ uint32_t numInst; ///< The amount of instructions
+ };
/// Clear to initial state
void clear();
@@ -150,10 +223,16 @@ struct IRSerialData
List<InstIndex> m_externalOperands; ///< Holds external operands (for instructions with more than kNumOperands)
- List<char> m_strings; ///< All strings. Indexed into by StringIndex
+ List<char> m_stringTable; ///< All strings. Indexed into by StringIndex
List<RawSourceLoc> m_rawSourceLocs; ///< A source location per instruction (saved without modification from IRInst)s
+ List<DebugSourceFile> m_debugSourceFiles; ///< The files associated
+ List<uint32_t> m_debugLineOffsets; ///< All of the debug line offsets
+ List<uint32_t> m_debugViewEntries; ///< The debug view entries - that modify line meanings
+ List<DebugLocRun> m_debugLocRuns; ///< Maps source locations to instructions
+ List<char> m_debugStrings; ///< All of the debug strings
+
static const PayloadInfo s_payloadInfos[int(Inst::PayloadType::CountOf)];
int m_decorationBaseIndex; ///< All decorations insts are at indices >= to this value
@@ -296,24 +375,26 @@ struct IRSerialWriter
static Result writeStream(const IRSerialData& data, Bin::CompressionType compressionType, Stream* stream);
- /// Get a slice from an index
- UnownedStringSlice getStringSlice(Ser::StringIndex index) const;
-
+
/// Get an instruction index from an instruction
Ser::InstIndex getInstIndex(IRInst* inst) const { return inst ? Ser::InstIndex(m_instMap[inst]) : Ser::InstIndex(0); }
- Ser::StringIndex getStringIndex(StringRepresentation* string);
- Ser::StringIndex getStringIndex(const UnownedStringSlice& string);
- Ser::StringIndex getStringIndex(Name* name);
- Ser::StringIndex getStringIndex(const char* chars);
-
+ /// Get a slice from an index
+ UnownedStringSlice getStringSlice(Ser::StringIndex index) const { return m_stringSlicePool.getSlice(StringSlicePool::Handle(index)); }
+ /// Get index from string representations
+ Ser::StringIndex getStringIndex(StringRepresentation* string) { return Ser::StringIndex(m_stringSlicePool.add(string)); }
+ Ser::StringIndex getStringIndex(const UnownedStringSlice& slice) { return Ser::StringIndex(m_stringSlicePool.add(slice)); }
+ Ser::StringIndex getStringIndex(Name* name) { return name ? getStringIndex(name->text) : Ser::kNullStringIndex; }
+ Ser::StringIndex getStringIndex(const char* chars) { return Ser::StringIndex(m_stringSlicePool.add(chars)); }
+ Ser::StringIndex getStringIndex(const String& string) { return Ser::StringIndex(m_stringSlicePool.add(string.getUnownedSlice())); }
+
IRSerialWriter() :
m_serialData(nullptr)
{}
protected:
void _addInstruction(IRInst* inst);
-
+
List<IRInst*> m_insts; ///< Instructions in same order as stored in the
List<IRDecoration*> m_decorations; ///< Holds all decorations in order of the instructions as found
@@ -321,20 +402,16 @@ protected:
Dictionary<IRInst*, Ser::InstIndex> m_instMap; ///< Map an instruction to an instruction index
- List<Ser::StringOffset> m_stringStarts; ///< Offset for each string index into the m_strings
+ StringSlicePool m_stringSlicePool;
+ IRSerialData* m_serialData; ///< Where the data is stored
- // TODO (JS):
- // We could perhaps improve this, if we stored at string indices (when linearized) the StringRepresentation
- // Doing so would mean if a String or Name was looked up we wouldn't have to re-allocate on the arena
- Dictionary<UnownedStringSlice, Ser::StringIndex> m_stringMap; ///< String map
- List<RefPtr<StringRepresentation> > m_scopeStrings; ///<
-
- IRSerialData* m_serialData; ///< Where the data is stored
+ StringSlicePool m_debugStringSlicePool; ///< Slices held just for debug usage
};
struct IRSerialReader
{
typedef IRSerialData Ser;
+ typedef StringRepresentationCache::Handle StringHandle;
/// Read a stream to fill in dataOut IRSerialData
static Result readStream(Stream* stream, IRSerialData* dataOut);
@@ -342,14 +419,9 @@ struct IRSerialReader
/// Read a module from serial data
Result read(const IRSerialData& data, Session* session, RefPtr<IRModule>& moduleOut);
- Name* getName(Ser::StringIndex index);
- String getString(Ser::StringIndex index);
- StringRepresentation* getStringRepresentation(Ser::StringIndex index);
- UnownedStringSlice getStringSlice(Ser::StringIndex index) { return getStringSlice(m_stringStarts[int(index)]); }
- char* getCStr(Ser::StringIndex index);
-
- UnownedStringSlice getStringSlice(Ser::StringOffset offset);
-
+ /// Get the representation cache
+ StringRepresentationCache& getStringRepresentationCache() { return m_stringRepresentationCache; }
+
IRSerialReader():
m_serialData(nullptr),
m_module(nullptr)
@@ -358,21 +430,15 @@ struct IRSerialReader
protected:
- void _calcStringStarts();
IRDecoration* _createDecoration(const Ser::Inst& srcIns);
static Result _skip(const IRSerialBinary::Chunk& chunk, Stream* stream, int64_t* remainingBytesInOut);
- List<Ser::StringOffset> m_stringStarts;
- List<StringRepresentation*> m_stringRepresentationCache;
+ StringRepresentationCache m_stringRepresentationCache;
const IRSerialData* m_serialData;
IRModule* m_module;
};
-
-Result serializeModule(IRModule* module, SourceManager* sourceManager, Stream* stream);
-Result readModule(Session* session, Stream* stream, RefPtr<IRModule>& moduleOut);
-
} // namespace Slang
#endif
diff --git a/source/slang/ir.h b/source/slang/ir.h
index e54a32043..41c9ab6ab 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -12,6 +12,7 @@
#include "source-loc.h"
#include "../core/slang-memory-arena.h"
+#include "../core/slang-object-scope-manager.h"
#include "type-system-shared.h"
@@ -1073,32 +1074,15 @@ struct IRModule : RefObject
IRInstListBase getGlobalInsts() const { return getModuleInst()->getChildren(); }
- void addRefObjectToFree(RefObject* obj)
- {
- if (obj)
- {
- obj->addReference();
- m_refObjectsToFree.Add(obj);
- }
- }
-
+ /// Get the object scope manager
+ SLANG_FORCE_INLINE ObjectScopeManager* getObjectScopeManager() { return &m_objectScopeManager; }
+
/// Ctor
IRModule():
memoryArena(kMemoryArenaBlockSize)
{
}
- ~IRModule()
- {
- // Release all ref objects
- for (RefObject* ptr: m_refObjectsToFree)
- {
- ptr->releaseReference();
- }
- // Clear any memory too
- m_refObjectsToFree = List<RefObject*>();
- }
-
MemoryArena memoryArena;
// The compilation session in use.
@@ -1106,7 +1090,8 @@ struct IRModule : RefObject
IRModuleInst* moduleInst;
protected:
- List<RefObject*> m_refObjectsToFree;
+
+ ObjectScopeManager m_objectScopeManager;
};
void printSlangIRAssembly(StringBuilder& builder, IRModule* module);