Change indirect-globals to use a dedicated allocIndirectGV.  This lets us
remove start/finishGVStub and the BufferState helper class from the
MachineCodeEmitter interface.  It has the side-effect of not setting the
indirect global writable and then executable on ARM, but that shouldn't be
necessary.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91464 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index bbac762..a670772 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -271,6 +271,10 @@
   class JITEmitter : public JITCodeEmitter {
     JITMemoryManager *MemMgr;
 
+    // When outputting a function stub in the context of some other function, we
+    // save BufferBegin/BufferEnd/CurBufferPtr here.
+    uint8_t *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr;
+
     // When reattempting to JIT a function after running out of space, we store
     // the estimated size of the function we're trying to JIT here, so we can
     // ask the memory manager for at least this much space.  When we
@@ -396,11 +400,13 @@
     void initJumpTableInfo(MachineJumpTableInfo *MJTI);
     void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
 
-    virtual void startGVStub(BufferState &BS, const GlobalValue* GV,
-                             unsigned StubSize, unsigned Alignment = 1);
-    virtual void startGVStub(BufferState &BS, void *Buffer,
-                             unsigned StubSize);
-    virtual void* finishGVStub(BufferState &BS);
+    void startGVStub(const GlobalValue* GV,
+                     unsigned StubSize, unsigned Alignment = 1);
+    void startGVStub(void *Buffer, unsigned StubSize);
+    void finishGVStub();
+    virtual void *allocIndirectGV(const GlobalValue *GV,
+                                  const uint8_t *Buffer, size_t Size,
+                                  unsigned Alignment);
 
     /// allocateSpace - Reserves space in the current block if any, or
     /// allocate a new one of the given size.
@@ -521,13 +527,12 @@
     if (!Actual) return 0;
   }
 
-  MachineCodeEmitter::BufferState BS;
   TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
-  JE.startGVStub(BS, F, SL.Size, SL.Alignment);
+  JE.startGVStub(F, SL.Size, SL.Alignment);
   // Codegen a new stub, calling the lazy resolver or the actual address of the
   // external function, if it was resolved.
   Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, JE);
-  JE.finishGVStub(BS);
+  JE.finishGVStub();
 
   if (Actual != (void*)(intptr_t)LazyResolverFn) {
     // If we are getting the stub for an external function, we really want the
@@ -579,11 +584,10 @@
   void *&Stub = ExternalFnToStubMap[FnAddr];
   if (Stub) return Stub;
 
-  MachineCodeEmitter::BufferState BS;
   TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout();
-  JE.startGVStub(BS, 0, SL.Size, SL.Alignment);
+  JE.startGVStub(0, SL.Size, SL.Alignment);
   Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, JE);
-  JE.finishGVStub(BS);
+  JE.finishGVStub();
 
   DEBUG(errs() << "JIT: Stub emitted at [" << Stub
                << "] for external function at '" << FnAddr << "'\n");
@@ -1215,8 +1219,9 @@
 
   if (DwarfExceptionHandling || JITEmitDebugInfo) {
     uintptr_t ActualSize = 0;
-    BufferState BS;
-    SaveStateTo(BS);
+    SavedBufferBegin = BufferBegin;
+    SavedBufferEnd = BufferEnd;
+    SavedCurBufferPtr = CurBufferPtr;
 
     if (MemMgr->NeedsExactSize()) {
       ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd);
@@ -1232,7 +1237,9 @@
     MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
                               FrameRegister);
     uint8_t *EhEnd = CurBufferPtr;
-    RestoreStateFrom(BS);
+    BufferBegin = SavedBufferBegin;
+    BufferEnd = SavedBufferEnd;
+    CurBufferPtr = SavedCurBufferPtr;
 
     if (DwarfExceptionHandling) {
       TheJIT->RegisterTable(FrameRegister);
@@ -1438,27 +1445,39 @@
   }
 }
 
-void JITEmitter::startGVStub(BufferState &BS, const GlobalValue* GV,
+void JITEmitter::startGVStub(const GlobalValue* GV,
                              unsigned StubSize, unsigned Alignment) {
-  SaveStateTo(BS);
+  SavedBufferBegin = BufferBegin;
+  SavedBufferEnd = BufferEnd;
+  SavedCurBufferPtr = CurBufferPtr;
 
   BufferBegin = CurBufferPtr = MemMgr->allocateStub(GV, StubSize, Alignment);
   BufferEnd = BufferBegin+StubSize+1;
 }
 
-void JITEmitter::startGVStub(BufferState &BS, void *Buffer, unsigned StubSize) {
-  SaveStateTo(BS);
+void JITEmitter::startGVStub(void *Buffer, unsigned StubSize) {
+  SavedBufferBegin = BufferBegin;
+  SavedBufferEnd = BufferEnd;
+  SavedCurBufferPtr = CurBufferPtr;
 
   BufferBegin = CurBufferPtr = (uint8_t *)Buffer;
   BufferEnd = BufferBegin+StubSize+1;
 }
 
-void *JITEmitter::finishGVStub(BufferState &BS) {
+void JITEmitter::finishGVStub() {
   assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
   NumBytes += getCurrentPCOffset();
-  void *Result = BufferBegin;
-  RestoreStateFrom(BS);
-  return Result;
+  BufferBegin = SavedBufferBegin;
+  BufferEnd = SavedBufferEnd;
+  CurBufferPtr = SavedCurBufferPtr;
+}
+
+void *JITEmitter::allocIndirectGV(const GlobalValue *GV,
+                                  const uint8_t *Buffer, size_t Size,
+                                  unsigned Alignment) {
+  uint8_t *IndGV = MemMgr->allocateStub(GV, Size, Alignment);
+  memcpy(IndGV, Buffer, Size);
+  return IndGV;
 }
 
 // getConstantPoolEntryAddress - Return the address of the 'ConstantNum' entry
@@ -1546,11 +1565,10 @@
 
   // Tell the target jit info to rewrite the stub at the specified address,
   // rather than creating a new one.
-  MachineCodeEmitter::BufferState BS;
   TargetJITInfo::StubLayout layout = getJITInfo().getStubLayout();
-  JE->startGVStub(BS, Stub, layout.Size);
+  JE->startGVStub(Stub, layout.Size);
   getJITInfo().emitFunctionStub(F, Addr, *getCodeEmitter());
-  JE->finishGVStub(BS);
+  JE->finishGVStub();
 }
 
 /// freeMachineCodeForFunction - release machine code memory for given Function.