Sfoglia il codice sorgente

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.
harshpg 2 anni fa
parent
commit
6eedcd2afa

+ 7 - 8
include/dxc/Support/FileIOHelper.h

@@ -116,16 +116,16 @@ public:
   }
   }
 };
 };
 
 
-void ReadBinaryFile(_In_opt_ IMalloc *pMalloc,
+HRESULT ReadBinaryFile(_In_opt_ IMalloc *pMalloc,
                     _In_z_ LPCWSTR pFileName,
                     _In_z_ LPCWSTR pFileName,
                     _Outptr_result_bytebuffer_(*pDataSize) void **ppData,
                     _Outptr_result_bytebuffer_(*pDataSize) void **ppData,
-                    _Out_ DWORD *pDataSize);
-void ReadBinaryFile(_In_z_ LPCWSTR pFileName,
+                    _Out_ DWORD *pDataSize) throw();
+HRESULT ReadBinaryFile(_In_z_ LPCWSTR pFileName,
                     _Outptr_result_bytebuffer_(*pDataSize) void **ppData,
                     _Outptr_result_bytebuffer_(*pDataSize) void **ppData,
-                    _Out_ DWORD *pDataSize);
-void WriteBinaryFile(_In_z_ LPCWSTR pFileName,
+                    _Out_ DWORD *pDataSize) throw();
+HRESULT WriteBinaryFile(_In_z_ LPCWSTR pFileName,
                      _In_reads_bytes_(DataSize) const void *pData,
                      _In_reads_bytes_(DataSize) const void *pData,
-                     _In_ DWORD DataSize);
+                     _In_ DWORD DataSize) throw();
 
 
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 // Blob and encoding manipulation functions.
 // Blob and encoding manipulation functions.
@@ -153,8 +153,7 @@ HRESULT DxcCreateBlobEncodingFromBlob(
     IMalloc *pMalloc, IDxcBlobEncoding **ppBlobEncoding) throw();
     IMalloc *pMalloc, IDxcBlobEncoding **ppBlobEncoding) throw();
 
 
 // Load files
 // Load files
-HRESULT
-DxcCreateBlobFromFile(_In_opt_ IMalloc *pMalloc, LPCWSTR pFileName,
+HRESULT DxcCreateBlobFromFile(_In_opt_ IMalloc *pMalloc, LPCWSTR pFileName,
                       _In_opt_ UINT32 *pCodePage,
                       _In_opt_ UINT32 *pCodePage,
                       _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) throw();
                       _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) throw();
 
 

+ 19 - 16
lib/DxcSupport/FileIOHelper.cpp

@@ -92,60 +92,63 @@ IMalloc *GetGlobalHeapMalloc() throw() {
 }
 }
 
 
 _Use_decl_annotations_
 _Use_decl_annotations_
-void ReadBinaryFile(IMalloc *pMalloc, LPCWSTR pFileName, void **ppData,
-                    DWORD *pDataSize) {
+HRESULT ReadBinaryFile(IMalloc *pMalloc, LPCWSTR pFileName, void **ppData,
+                    DWORD *pDataSize) throw() {
   HANDLE hFile = CreateFileW(pFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
   HANDLE hFile = CreateFileW(pFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
                              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
                              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
   if (hFile == INVALID_HANDLE_VALUE) {
   if (hFile == INVALID_HANDLE_VALUE) {
-    IFT(HRESULT_FROM_WIN32(GetLastError()));
+    return HRESULT_FROM_WIN32(GetLastError());
   }
   }
 
 
   CHandle h(hFile);
   CHandle h(hFile);
 
 
   LARGE_INTEGER FileSize;
   LARGE_INTEGER FileSize;
   if (!GetFileSizeEx(hFile, &FileSize)) {
   if (!GetFileSizeEx(hFile, &FileSize)) {
-    IFT(HRESULT_FROM_WIN32(GetLastError()));
+    return HRESULT_FROM_WIN32(GetLastError());
   }
   }
   if (FileSize.u.HighPart != 0) {
   if (FileSize.u.HighPart != 0) {
-    throw(hlsl::Exception(DXC_E_INPUT_FILE_TOO_LARGE, "input file is too large"));
+    return DXC_E_INPUT_FILE_TOO_LARGE;
   }
   }
 
 
   char *pData = (char *)pMalloc->Alloc(FileSize.u.LowPart);
   char *pData = (char *)pMalloc->Alloc(FileSize.u.LowPart);
   if (!pData) {
   if (!pData) {
-    throw std::bad_alloc();
+    return E_OUTOFMEMORY;
   }
   }
 
 
   DWORD BytesRead;
   DWORD BytesRead;
   if (!ReadFile(hFile, pData, FileSize.u.LowPart, &BytesRead, nullptr)) {
   if (!ReadFile(hFile, pData, FileSize.u.LowPart, &BytesRead, nullptr)) {
     HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
     HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
     pMalloc->Free(pData);
     pMalloc->Free(pData);
-    throw ::hlsl::Exception(hr);
+    return hr;
   }
   }
   DXASSERT(FileSize.u.LowPart == BytesRead, "ReadFile operation failed");
   DXASSERT(FileSize.u.LowPart == BytesRead, "ReadFile operation failed");
 
 
   *ppData = pData;
   *ppData = pData;
   *pDataSize = FileSize.u.LowPart;
   *pDataSize = FileSize.u.LowPart;
 
 
+  return S_OK;
 }
 }
 
 
 _Use_decl_annotations_
 _Use_decl_annotations_
-void ReadBinaryFile(LPCWSTR pFileName, void **ppData, DWORD *pDataSize) {
+HRESULT ReadBinaryFile(LPCWSTR pFileName, void **ppData, DWORD *pDataSize) throw() {
   return ReadBinaryFile(GetGlobalHeapMalloc(), pFileName, ppData, pDataSize);
   return ReadBinaryFile(GetGlobalHeapMalloc(), pFileName, ppData, pDataSize);
 }
 }
 
 
 _Use_decl_annotations_
 _Use_decl_annotations_
-void WriteBinaryFile(LPCWSTR pFileName, const void *pData, DWORD DataSize) {
+HRESULT WriteBinaryFile(LPCWSTR pFileName, const void *pData, DWORD DataSize) throw() {
   HANDLE hFile = CreateFileW(pFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
   HANDLE hFile = CreateFileW(pFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
   if(hFile == INVALID_HANDLE_VALUE) {
   if(hFile == INVALID_HANDLE_VALUE) {
-    IFT(HRESULT_FROM_WIN32(GetLastError()));
+    return HRESULT_FROM_WIN32(GetLastError());
   }
   }
   CHandle h(hFile);
   CHandle h(hFile);
 
 
   DWORD BytesWritten;
   DWORD BytesWritten;
   if(!WriteFile(hFile, pData, DataSize, &BytesWritten, nullptr)) {
   if(!WriteFile(hFile, pData, DataSize, &BytesWritten, nullptr)) {
-    IFT(HRESULT_FROM_WIN32(GetLastError()));
+    return HRESULT_FROM_WIN32(GetLastError());
   }
   }
   DXASSERT(DataSize == BytesWritten, "WriteFile operation failed");
   DXASSERT(DataSize == BytesWritten, "WriteFile operation failed");
+
+  return S_OK;
 }
 }
 
 
 _Use_decl_annotations_
 _Use_decl_annotations_
@@ -825,15 +828,15 @@ DxcCreateBlobFromFile(IMalloc *pMalloc, LPCWSTR pFileName, UINT32 *pCodePage,
   LPVOID pData;
   LPVOID pData;
   DWORD dataSize;
   DWORD dataSize;
   *ppBlobEncoding = nullptr;
   *ppBlobEncoding = nullptr;
-  try {
-    ReadBinaryFile(pMalloc, pFileName, &pData, &dataSize);
-  }
-  CATCH_CPP_RETURN_HRESULT();
+
+  HRESULT hr = ReadBinaryFile(pMalloc, pFileName, &pData, &dataSize);
+  if (FAILED(hr))
+    return hr;
 
 
   bool known = (pCodePage != nullptr);
   bool known = (pCodePage != nullptr);
   UINT32 codePage = (pCodePage != nullptr) ? *pCodePage : 0;
   UINT32 codePage = (pCodePage != nullptr) ? *pCodePage : 0;
 
 
-  HRESULT hr = DxcCreateBlob(pData, dataSize, false, false, known, codePage, pMalloc, ppBlobEncoding);
+  hr = DxcCreateBlob(pData, dataSize, false, false, known, codePage, pMalloc, ppBlobEncoding);
   if (FAILED(hr))
   if (FAILED(hr))
     pMalloc->Free(pData);
     pMalloc->Free(pData);
   return hr;
   return hr;

+ 3 - 3
projects/dxilconv/tools/dxbc2dxil/dxbc2dxil.cpp

@@ -200,7 +200,7 @@ void Converter::Run() {
   // Load DXBC blob.
   // Load DXBC blob.
   CComHeapPtr<void> pDxbcPtr;
   CComHeapPtr<void> pDxbcPtr;
   DWORD DxbcSize;
   DWORD DxbcSize;
-  hlsl::ReadBinaryFile(m_InputFile.c_str(), &pDxbcPtr, &DxbcSize);
+  IFT(hlsl::ReadBinaryFile(m_InputFile.c_str(), &pDxbcPtr, &DxbcSize));
 
 
   // Disassemble Dxbc blob and exit.
   // Disassemble Dxbc blob and exit.
   if (m_bDisasmDxbc) {
   if (m_bDisasmDxbc) {
@@ -222,7 +222,7 @@ void Converter::Run() {
     if (m_OutputFile.empty())
     if (m_OutputFile.empty())
       printf("%s", pText);
       printf("%s", pText);
     else
     else
-      hlsl::WriteBinaryFile(m_OutputFile.c_str(), pText, strlen(pText));
+      IFT(hlsl::WriteBinaryFile(m_OutputFile.c_str(), pText, strlen(pText)));
 
 
     return;
     return;
   }
   }
@@ -291,7 +291,7 @@ void Converter::Run() {
     }
     }
   }
   }
 
 
-  hlsl::WriteBinaryFile(m_OutputFile.c_str(), pOutput, OutputSize);
+  IFT(hlsl::WriteBinaryFile(m_OutputFile.c_str(), pOutput, OutputSize));
 }
 }
 
 
 HRESULT Converter::CreateDxcLibrary(_Outptr_ IDxcLibrary **ppLibrary) {
 HRESULT Converter::CreateDxcLibrary(_Outptr_ IDxcLibrary **ppLibrary) {

+ 1 - 1
tools/clang/tools/dxclib/dxc.cpp

@@ -535,7 +535,7 @@ HRESULT DxcContext::ReadFileIntoPartContent(hlsl::DxilFourCC fourCC, LPCWSTR fil
     CComPtr<IDxcBlob> pResult;
     CComPtr<IDxcBlob> pResult;
     CComHeapPtr<BYTE> pData;
     CComHeapPtr<BYTE> pData;
     DWORD dataSize;
     DWORD dataSize;
-    hlsl::ReadBinaryFile(fileName, (void**)&pData, &dataSize);
+    IFT(hlsl::ReadBinaryFile(fileName, (void**)&pData, &dataSize));
     DXASSERT(pData != nullptr, "otherwise ReadBinaryFile should throw an exception");
     DXASSERT(pData != nullptr, "otherwise ReadBinaryFile should throw an exception");
     hlsl::DxilContainerHeader *pHeader = hlsl::IsDxilContainerLike(pData.m_pData, dataSize);
     hlsl::DxilContainerHeader *pHeader = hlsl::IsDxilContainerLike(pData.m_pData, dataSize);
     IFRBOOL(hlsl::IsValidDxilContainer(pHeader, dataSize), E_INVALIDARG);
     IFRBOOL(hlsl::IsValidDxilContainer(pHeader, dataSize), E_INVALIDARG);

+ 1 - 4
tools/clang/tools/dxcompiler/dxclibrary.cpp

@@ -277,10 +277,7 @@ public:
     _In_z_ LPCWSTR pFileName, _In_opt_ UINT32* pCodePage,
     _In_z_ LPCWSTR pFileName, _In_opt_ UINT32* pCodePage,
     _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) override {
     _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) override {
     DxcThreadMalloc TM(m_pMalloc);
     DxcThreadMalloc TM(m_pMalloc);
-    try {
-      return ::hlsl::DxcCreateBlobFromFile(pFileName, pCodePage, pBlobEncoding);
-    }
-    CATCH_CPP_RETURN_HRESULT();
+    return ::hlsl::DxcCreateBlobFromFile(pFileName, pCodePage, pBlobEncoding);
   }
   }
 
 
   HRESULT STDMETHODCALLTYPE CreateReadOnlyStreamFromBlob(
   HRESULT STDMETHODCALLTYPE CreateReadOnlyStreamFromBlob(

+ 1 - 1
tools/clang/unittests/HLSL/ExecutionTest.cpp

@@ -193,7 +193,7 @@ static void SavePixelsToFile(LPCVOID pPixels, DXGI_FORMAT format, UINT32 m_width
   VERIFY_SUCCEEDED(pFrameEncode->WriteSource(pBitmap, nullptr));
   VERIFY_SUCCEEDED(pFrameEncode->WriteSource(pBitmap, nullptr));
   VERIFY_SUCCEEDED(pFrameEncode->Commit());
   VERIFY_SUCCEEDED(pFrameEncode->Commit());
   VERIFY_SUCCEEDED(pEncoder->Commit());
   VERIFY_SUCCEEDED(pEncoder->Commit());
-  hlsl::WriteBinaryFile(pFileName, pStream->GetPtr(), pStream->GetPtrSize());
+  IFT(hlsl::WriteBinaryFile(pFileName, pStream->GetPtr(), pStream->GetPtrSize()));
 }
 }
 
 
 // Checks if the given warp version supports the given operation.
 // Checks if the given warp version supports the given operation.

+ 1 - 1
tools/clang/unittests/dxc_batch/dxc_batch.cpp

@@ -406,7 +406,7 @@ HRESULT DxcContext::ReadFileIntoPartContent(hlsl::DxilFourCC fourCC,
     CComPtr<IDxcBlob> pResult;
     CComPtr<IDxcBlob> pResult;
     CComHeapPtr<BYTE> pData;
     CComHeapPtr<BYTE> pData;
     DWORD dataSize;
     DWORD dataSize;
-    hlsl::ReadBinaryFile(fileName, (void **)&pData, &dataSize);
+    IFT(hlsl::ReadBinaryFile(fileName, (void **)&pData, &dataSize));
     DXASSERT(pData != nullptr,
     DXASSERT(pData != nullptr,
              "otherwise ReadBinaryFile should throw an exception");
              "otherwise ReadBinaryFile should throw an exception");
     hlsl::DxilContainerHeader *pHeader = 
     hlsl::DxilContainerHeader *pHeader =