[ORC] Add an Error return to the JITCompileCallbackManager::grow method.

Calling grow may result in an error if, for example, this is a callback
manager for a remote target. We need to be able to return this error to the
callee.

llvm-svn: 312429
diff --git a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h
index d10e474..841ea74 100644
--- a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h
+++ b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter4/KaleidoscopeJIT.h
@@ -135,7 +135,7 @@
   Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
     // Create a CompileCallback - this is the re-entry point into the compiler
     // for functions that haven't been compiled yet.
-    auto CCInfo = CompileCallbackMgr->getCompileCallback();
+    auto CCInfo = cantFail(CompileCallbackMgr->getCompileCallback());
 
     // Create an indirect stub. This serves as the functions "canonical
     // definition" - an unchanging (constant address) entry point to the
diff --git a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h
index 7ea535b..d318314 100644
--- a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h
+++ b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter5/KaleidoscopeJIT.h
@@ -164,7 +164,7 @@
   Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
     // Create a CompileCallback - this is the re-entry point into the compiler
     // for functions that haven't been compiled yet.
-    auto CCInfo = CompileCallbackMgr->getCompileCallback();
+    auto CCInfo = cantFail(CompileCallbackMgr->getCompileCallback());
 
     // Create an indirect stub. This serves as the functions "canonical
     // definition" - an unchanging (constant address) entry point to the
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index 27b5457..cbe9ff5 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -349,19 +349,22 @@
         // Create a callback, associate it with the stub for the function,
         // and set the compile action to compile the partition containing the
         // function.
-        auto CCInfo = CompileCallbackMgr.getCompileCallback();
-        StubInits[MangledName] =
-          std::make_pair(CCInfo.getAddress(),
-                         JITSymbolFlags::fromGlobalValue(F));
-        CCInfo.setCompileAction([this, &LD, LMId, &F]() -> JITTargetAddress {
-            if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
-              return *FnImplAddrOrErr;
-            else {
-              // FIXME: Report error, return to 'abort' or something similar.
-              consumeError(FnImplAddrOrErr.takeError());
-              return 0;
-            }
-          });
+        if (auto CCInfoOrErr = CompileCallbackMgr.getCompileCallback()) {
+          auto &CCInfo = *CCInfoOrErr;
+          StubInits[MangledName] =
+            std::make_pair(CCInfo.getAddress(),
+                           JITSymbolFlags::fromGlobalValue(F));
+          CCInfo.setCompileAction([this, &LD, LMId, &F]() -> JITTargetAddress {
+              if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
+                return *FnImplAddrOrErr;
+              else {
+                // FIXME: Report error, return to 'abort' or something similar.
+                consumeError(FnImplAddrOrErr.takeError());
+                return 0;
+              }
+            });
+        } else
+          return CCInfoOrErr.takeError();
       }
 
       if (auto Err = LD.StubsMgr->createStubs(StubInits))
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
index e038093..029b86a 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
@@ -105,10 +105,13 @@
   }
 
   /// @brief Reserve a compile callback.
-  CompileCallbackInfo getCompileCallback() {
-    JITTargetAddress TrampolineAddr = getAvailableTrampolineAddr();
-    auto &Compile = this->ActiveTrampolines[TrampolineAddr];
-    return CompileCallbackInfo(TrampolineAddr, Compile);
+  Expected<CompileCallbackInfo> getCompileCallback() {
+    if (auto TrampolineAddrOrErr = getAvailableTrampolineAddr()) {
+      const auto &TrampolineAddr = *TrampolineAddrOrErr;
+      auto &Compile = this->ActiveTrampolines[TrampolineAddr];
+      return CompileCallbackInfo(TrampolineAddr, Compile);
+    } else
+      return TrampolineAddrOrErr.takeError();
   }
 
   /// @brief Get a CompileCallbackInfo for an existing callback.
@@ -138,9 +141,10 @@
   std::vector<JITTargetAddress> AvailableTrampolines;
 
 private:
-  JITTargetAddress getAvailableTrampolineAddr() {
+  Expected<JITTargetAddress> getAvailableTrampolineAddr() {
     if (this->AvailableTrampolines.empty())
-      grow();
+      if (auto Err = grow())
+        return std::move(Err);
     assert(!this->AvailableTrampolines.empty() &&
            "Failed to grow available trampolines.");
     JITTargetAddress TrampolineAddr = this->AvailableTrampolines.back();
@@ -149,7 +153,7 @@
   }
 
   // Create new trampolines - to be implemented in subclasses.
-  virtual void grow() = 0;
+  virtual Error grow() = 0;
 
   virtual void anchor();
 };
@@ -188,7 +192,7 @@
             reinterpret_cast<uintptr_t>(TrampolineId)));
   }
 
-  void grow() override {
+  Error grow() override {
     assert(this->AvailableTrampolines.empty() && "Growing prematurely?");
 
     std::error_code EC;
@@ -196,7 +200,8 @@
         sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
             sys::Process::getPageSize(), nullptr,
             sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
-    assert(!EC && "Failed to allocate trampoline block");
+    if (EC)
+      return errorCodeToError(EC);
 
     unsigned NumTrampolines =
         (sys::Process::getPageSize() - TargetT::PointerSize) /
@@ -211,12 +216,13 @@
           static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(
               TrampolineMem + (I * TargetT::TrampolineSize))));
 
-    EC = sys::Memory::protectMappedMemory(TrampolineBlock.getMemoryBlock(),
-                                          sys::Memory::MF_READ |
-                                              sys::Memory::MF_EXEC);
-    assert(!EC && "Failed to mprotect trampoline block");
+    if (auto EC = sys::Memory::protectMappedMemory(
+                    TrampolineBlock.getMemoryBlock(),
+                    sys::Memory::MF_READ | sys::Memory::MF_EXEC))
+      return errorCodeToError(EC);
 
     TrampolineBlocks.push_back(std::move(TrampolineBlock));
+    return Error::success();
   }
 
   sys::OwningMemoryBlock ResolverBlock;
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
index c602f1d..d683767 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h
@@ -543,19 +543,19 @@
         : JITCompileCallbackManager(ErrorHandlerAddress), Remote(Remote) {}
 
   private:
-    void grow() override {
+    Error grow() override {
       JITTargetAddress BlockAddr = 0;
       uint32_t NumTrampolines = 0;
       if (auto TrampolineInfoOrErr = Remote.emitTrampolineBlock())
         std::tie(BlockAddr, NumTrampolines) = *TrampolineInfoOrErr;
-      else {
-        // FIXME: Return error.
-        llvm_unreachable("Failed to create trampolines");
-      }
+      else
+        return TrampolineInfoOrErr.takeError();
 
       uint32_t TrampolineSize = Remote.getTrampolineSize();
       for (unsigned I = 0; I < NumTrampolines; ++I)
         this->AvailableTrampolines.push_back(BlockAddr + (I * TrampolineSize));
+
+      return Error::success();
     }
 
     OrcRemoteTargetClient &Remote;
diff --git a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
index e38decf..ecb4c20 100644
--- a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
+++ b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
@@ -145,12 +145,15 @@
   createLazyCompileCallback(JITTargetAddress &RetAddr,
                             LLVMOrcLazyCompileCallbackFn Callback,
                             void *CallbackCtx) {
-    auto CCInfo = CCMgr->getCompileCallback();
-    CCInfo.setCompileAction([=]() -> JITTargetAddress {
-      return Callback(wrap(this), CallbackCtx);
-    });
-    RetAddr = CCInfo.getAddress();
-    return LLVMOrcErrSuccess;
+    if (auto CCInfoOrErr = CCMgr->getCompileCallback()) {
+      auto &CCInfo = *CCInfoOrErr;
+      CCInfo.setCompileAction([=]() -> JITTargetAddress {
+          return Callback(wrap(this), CallbackCtx);
+        });
+      RetAddr = CCInfo.getAddress();
+      return LLVMOrcErrSuccess;
+    } else
+      return mapError(CCInfoOrErr.takeError());
   }
 
   LLVMOrcErrorCode createIndirectStub(StringRef StubName,
diff --git a/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
index 844746f..24258ec 100644
--- a/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/CompileOnDemandLayerTest.cpp
@@ -21,7 +21,7 @@
   DummyCallbackManager() : JITCompileCallbackManager(0) {}
 
 public:
-  void grow() override { llvm_unreachable("not implemented"); }
+  Error grow() override { llvm_unreachable("not implemented"); }
 };
 
 class DummyStubsManager : public orc::IndirectStubsManager {