+void JIT::updateFunctionStub(Function *F) {
+ // Get the empty stub we generated earlier.
+ assert(isa<JITEmitter>(MCE) && "Unexpected MCE?");
+ JITEmitter *JE = cast<JITEmitter>(getCodeEmitter());
+ void *Stub = JE->getJITResolver().getFunctionStub(F);
+
+ // Tell the target jit info to rewrite the stub at the specified address,
+ // rather than creating a new one.
+ void *Addr = getPointerToGlobalIfAvailable(F);
+ getJITInfo().emitFunctionStubAtAddr(F, Addr, Stub, *getCodeEmitter());
+}
+
+/// updateDlsymStubTable - Emit the data necessary to relocate the stubs
+/// that were emitted during code generation.
+///
+void JIT::updateDlsymStubTable() {
+ assert(isa<JITEmitter>(MCE) && "Unexpected MCE?");
+ JITEmitter *JE = cast<JITEmitter>(getCodeEmitter());
+
+ SmallVector<GlobalValue*, 8> GVs;
+ SmallVector<void*, 8> Ptrs;
+
+ JE->getJITResolver().getRelocatableGVs(GVs, Ptrs);
+
+ // If there are no relocatable stubs, return.
+ if (GVs.empty())
+ return;
+
+ // If there are no new relocatable stubs, return.
+ void *CurTable = JE->getMemMgr()->getDlsymTable();
+ if (CurTable && (*(unsigned *)CurTable == GVs.size()))
+ return;
+
+ // Calculate the size of the stub info
+ unsigned offset = 4 + 4 * GVs.size();
+
+ SmallVector<unsigned, 8> Offsets;
+ for (unsigned i = 0; i != GVs.size(); ++i) {
+ Offsets.push_back(offset);
+ offset += GVs[i]->getName().length() + 1;
+ }
+
+ // FIXME: This currently allocates new space every time it's called. A
+ // different data structure could be used to make this unnecessary.
+ JE->startGVStub(0, offset, 4);
+
+ // Emit the number of records
+ MCE->emitInt32(GVs.size());
+
+ // Emit the string offsets
+ for (unsigned i = 0; i != GVs.size(); ++i)
+ MCE->emitInt32(Offsets[i]);
+
+ // Emit the pointers
+ for (unsigned i = 0; i != GVs.size(); ++i)
+ if (sizeof(void *) == 8)
+ MCE->emitInt64((intptr_t)Ptrs[i]);
+ else
+ MCE->emitInt32((intptr_t)Ptrs[i]);
+
+ // Emit the strings
+ for (unsigned i = 0; i != GVs.size(); ++i)
+ MCE->emitString(GVs[i]->getName());
+
+ // Tell the JIT memory manager where it is.
+ JE->getMemMgr()->SetDlsymTable(JE->finishGVStub(0));
+}
+