Skip to content

Commit 6eedcd2

Browse files
authored
Replacing fileIO exceptions with error codes (#4841)
Exceptions for error handling can have a significant performance impact. The exception-throw codepaths are usually cold, and rely on large in-memory tables that need to be paged in. This change to instead propagate returned error codes simplifies the code and allows the compiler to more aggressively optimize around both success and failure conditions.
1 parent e78b2dd commit 6eedcd2

7 files changed

Lines changed: 33 additions & 34 deletions

File tree

include/dxc/Support/FileIOHelper.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,16 @@ class CDxcMallocHeapPtr
116116
}
117117
};
118118

119-
void ReadBinaryFile(_In_opt_ IMalloc *pMalloc,
119+
HRESULT ReadBinaryFile(_In_opt_ IMalloc *pMalloc,
120120
_In_z_ LPCWSTR pFileName,
121121
_Outptr_result_bytebuffer_(*pDataSize) void **ppData,
122-
_Out_ DWORD *pDataSize);
123-
void ReadBinaryFile(_In_z_ LPCWSTR pFileName,
122+
_Out_ DWORD *pDataSize) throw();
123+
HRESULT ReadBinaryFile(_In_z_ LPCWSTR pFileName,
124124
_Outptr_result_bytebuffer_(*pDataSize) void **ppData,
125-
_Out_ DWORD *pDataSize);
126-
void WriteBinaryFile(_In_z_ LPCWSTR pFileName,
125+
_Out_ DWORD *pDataSize) throw();
126+
HRESULT WriteBinaryFile(_In_z_ LPCWSTR pFileName,
127127
_In_reads_bytes_(DataSize) const void *pData,
128-
_In_ DWORD DataSize);
128+
_In_ DWORD DataSize) throw();
129129

130130
///////////////////////////////////////////////////////////////////////////////
131131
// Blob and encoding manipulation functions.
@@ -153,8 +153,7 @@ HRESULT DxcCreateBlobEncodingFromBlob(
153153
IMalloc *pMalloc, IDxcBlobEncoding **ppBlobEncoding) throw();
154154

155155
// Load files
156-
HRESULT
157-
DxcCreateBlobFromFile(_In_opt_ IMalloc *pMalloc, LPCWSTR pFileName,
156+
HRESULT DxcCreateBlobFromFile(_In_opt_ IMalloc *pMalloc, LPCWSTR pFileName,
158157
_In_opt_ UINT32 *pCodePage,
159158
_COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) throw();
160159

lib/DxcSupport/FileIOHelper.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,60 +92,63 @@ IMalloc *GetGlobalHeapMalloc() throw() {
9292
}
9393

9494
_Use_decl_annotations_
95-
void ReadBinaryFile(IMalloc *pMalloc, LPCWSTR pFileName, void **ppData,
96-
DWORD *pDataSize) {
95+
HRESULT ReadBinaryFile(IMalloc *pMalloc, LPCWSTR pFileName, void **ppData,
96+
DWORD *pDataSize) throw() {
9797
HANDLE hFile = CreateFileW(pFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
9898
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
9999
if (hFile == INVALID_HANDLE_VALUE) {
100-
IFT(HRESULT_FROM_WIN32(GetLastError()));
100+
return HRESULT_FROM_WIN32(GetLastError());
101101
}
102102

103103
CHandle h(hFile);
104104

105105
LARGE_INTEGER FileSize;
106106
if (!GetFileSizeEx(hFile, &FileSize)) {
107-
IFT(HRESULT_FROM_WIN32(GetLastError()));
107+
return HRESULT_FROM_WIN32(GetLastError());
108108
}
109109
if (FileSize.u.HighPart != 0) {
110-
throw(hlsl::Exception(DXC_E_INPUT_FILE_TOO_LARGE, "input file is too large"));
110+
return DXC_E_INPUT_FILE_TOO_LARGE;
111111
}
112112

113113
char *pData = (char *)pMalloc->Alloc(FileSize.u.LowPart);
114114
if (!pData) {
115-
throw std::bad_alloc();
115+
return E_OUTOFMEMORY;
116116
}
117117

118118
DWORD BytesRead;
119119
if (!ReadFile(hFile, pData, FileSize.u.LowPart, &BytesRead, nullptr)) {
120120
HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
121121
pMalloc->Free(pData);
122-
throw ::hlsl::Exception(hr);
122+
return hr;
123123
}
124124
DXASSERT(FileSize.u.LowPart == BytesRead, "ReadFile operation failed");
125125

126126
*ppData = pData;
127127
*pDataSize = FileSize.u.LowPart;
128128

129+
return S_OK;
129130
}
130131

131132
_Use_decl_annotations_
132-
void ReadBinaryFile(LPCWSTR pFileName, void **ppData, DWORD *pDataSize) {
133+
HRESULT ReadBinaryFile(LPCWSTR pFileName, void **ppData, DWORD *pDataSize) throw() {
133134
return ReadBinaryFile(GetGlobalHeapMalloc(), pFileName, ppData, pDataSize);
134135
}
135136

136137
_Use_decl_annotations_
137-
void WriteBinaryFile(LPCWSTR pFileName, const void *pData, DWORD DataSize) {
138+
HRESULT WriteBinaryFile(LPCWSTR pFileName, const void *pData, DWORD DataSize) throw() {
138139
HANDLE hFile = CreateFileW(pFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
139140
if(hFile == INVALID_HANDLE_VALUE) {
140-
IFT(HRESULT_FROM_WIN32(GetLastError()));
141+
return HRESULT_FROM_WIN32(GetLastError());
141142
}
142143
CHandle h(hFile);
143144

144145
DWORD BytesWritten;
145146
if(!WriteFile(hFile, pData, DataSize, &BytesWritten, nullptr)) {
146-
IFT(HRESULT_FROM_WIN32(GetLastError()));
147+
return HRESULT_FROM_WIN32(GetLastError());
147148
}
148149
DXASSERT(DataSize == BytesWritten, "WriteFile operation failed");
150+
151+
return S_OK;
149152
}
150153

151154
_Use_decl_annotations_
@@ -825,15 +828,15 @@ DxcCreateBlobFromFile(IMalloc *pMalloc, LPCWSTR pFileName, UINT32 *pCodePage,
825828
LPVOID pData;
826829
DWORD dataSize;
827830
*ppBlobEncoding = nullptr;
828-
try {
829-
ReadBinaryFile(pMalloc, pFileName, &pData, &dataSize);
830-
}
831-
CATCH_CPP_RETURN_HRESULT();
831+
832+
HRESULT hr = ReadBinaryFile(pMalloc, pFileName, &pData, &dataSize);
833+
if (FAILED(hr))
834+
return hr;
832835

833836
bool known = (pCodePage != nullptr);
834837
UINT32 codePage = (pCodePage != nullptr) ? *pCodePage : 0;
835838

836-
HRESULT hr = DxcCreateBlob(pData, dataSize, false, false, known, codePage, pMalloc, ppBlobEncoding);
839+
hr = DxcCreateBlob(pData, dataSize, false, false, known, codePage, pMalloc, ppBlobEncoding);
837840
if (FAILED(hr))
838841
pMalloc->Free(pData);
839842
return hr;

projects/dxilconv/tools/dxbc2dxil/dxbc2dxil.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ void Converter::Run() {
200200
// Load DXBC blob.
201201
CComHeapPtr<void> pDxbcPtr;
202202
DWORD DxbcSize;
203-
hlsl::ReadBinaryFile(m_InputFile.c_str(), &pDxbcPtr, &DxbcSize);
203+
IFT(hlsl::ReadBinaryFile(m_InputFile.c_str(), &pDxbcPtr, &DxbcSize));
204204

205205
// Disassemble Dxbc blob and exit.
206206
if (m_bDisasmDxbc) {
@@ -222,7 +222,7 @@ void Converter::Run() {
222222
if (m_OutputFile.empty())
223223
printf("%s", pText);
224224
else
225-
hlsl::WriteBinaryFile(m_OutputFile.c_str(), pText, strlen(pText));
225+
IFT(hlsl::WriteBinaryFile(m_OutputFile.c_str(), pText, strlen(pText)));
226226

227227
return;
228228
}
@@ -291,7 +291,7 @@ void Converter::Run() {
291291
}
292292
}
293293

294-
hlsl::WriteBinaryFile(m_OutputFile.c_str(), pOutput, OutputSize);
294+
IFT(hlsl::WriteBinaryFile(m_OutputFile.c_str(), pOutput, OutputSize));
295295
}
296296

297297
HRESULT Converter::CreateDxcLibrary(_Outptr_ IDxcLibrary **ppLibrary) {

tools/clang/tools/dxclib/dxc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ HRESULT DxcContext::ReadFileIntoPartContent(hlsl::DxilFourCC fourCC, LPCWSTR fil
535535
CComPtr<IDxcBlob> pResult;
536536
CComHeapPtr<BYTE> pData;
537537
DWORD dataSize;
538-
hlsl::ReadBinaryFile(fileName, (void**)&pData, &dataSize);
538+
IFT(hlsl::ReadBinaryFile(fileName, (void**)&pData, &dataSize));
539539
DXASSERT(pData != nullptr, "otherwise ReadBinaryFile should throw an exception");
540540
hlsl::DxilContainerHeader *pHeader = hlsl::IsDxilContainerLike(pData.m_pData, dataSize);
541541
IFRBOOL(hlsl::IsValidDxilContainer(pHeader, dataSize), E_INVALIDARG);

tools/clang/tools/dxcompiler/dxclibrary.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,7 @@ class DxcUtils : public IDxcUtils {
277277
_In_z_ LPCWSTR pFileName, _In_opt_ UINT32* pCodePage,
278278
_COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) override {
279279
DxcThreadMalloc TM(m_pMalloc);
280-
try {
281-
return ::hlsl::DxcCreateBlobFromFile(pFileName, pCodePage, pBlobEncoding);
282-
}
283-
CATCH_CPP_RETURN_HRESULT();
280+
return ::hlsl::DxcCreateBlobFromFile(pFileName, pCodePage, pBlobEncoding);
284281
}
285282

286283
HRESULT STDMETHODCALLTYPE CreateReadOnlyStreamFromBlob(

tools/clang/unittests/HLSL/ExecutionTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ static void SavePixelsToFile(LPCVOID pPixels, DXGI_FORMAT format, UINT32 m_width
193193
VERIFY_SUCCEEDED(pFrameEncode->WriteSource(pBitmap, nullptr));
194194
VERIFY_SUCCEEDED(pFrameEncode->Commit());
195195
VERIFY_SUCCEEDED(pEncoder->Commit());
196-
hlsl::WriteBinaryFile(pFileName, pStream->GetPtr(), pStream->GetPtrSize());
196+
IFT(hlsl::WriteBinaryFile(pFileName, pStream->GetPtr(), pStream->GetPtrSize()));
197197
}
198198

199199
// Checks if the given warp version supports the given operation.

tools/clang/unittests/dxc_batch/dxc_batch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ HRESULT DxcContext::ReadFileIntoPartContent(hlsl::DxilFourCC fourCC,
406406
CComPtr<IDxcBlob> pResult;
407407
CComHeapPtr<BYTE> pData;
408408
DWORD dataSize;
409-
hlsl::ReadBinaryFile(fileName, (void **)&pData, &dataSize);
409+
IFT(hlsl::ReadBinaryFile(fileName, (void **)&pData, &dataSize));
410410
DXASSERT(pData != nullptr,
411411
"otherwise ReadBinaryFile should throw an exception");
412412
hlsl::DxilContainerHeader *pHeader =

0 commit comments

Comments
 (0)