2012-06-04 22 views
12

Ich möchte Funktionen in einem Modul ausführen, dieses Modul wird Abhängigkeiten in anderen Modulen aufgelöst haben. die Module könnten sich ändern (dynamische Kompilierungsumgebung), so würde ich nicht alle Abhängigkeiten in einem einzigen monolithischen Modul verknüpfen wollen, das heißt, wenn es vermieden werden kannDynamische Verknüpfung mit LLVM

Ich hoffe, Linker::linkModules zu verwenden, aber dies ist immer destruktiv auf die Quelle Modul. Das ist in Ordnung für ein Modul, abhängig von einem einzigen, denn wenn sich das geändert hat, ist das keine große Sache, aber ist es nicht übertrieben, N-1 Module, die sich nicht geändert haben, nur wegen einer einzigen Änderung neu zu erstellen?

Ich frage mich, ob es eine nicht-destruktive Version von LinkModule gibt, die für die JIT-Ausführung funktionieren kann.

Antwort

3

Try this:

Linker::LinkModules(destinationModule, sourceModule, Linker::PreserveSource, &error); 

Wenn Sie passieren Linker::PreserveSource statt Linker::DestroySource, können Sie weiterhin sourceModule nach dem Aufruf verwenden.

0

Ich glaube nicht, dass dies möglich ist, wie Sie das Problem beschreiben.

Wenn in Ihrer idealen Lösung die Module A und B verbunden wären, wäre die Änderung B sofort in A zu sehen?

Wenn dies der Fall ist, glaube ich nicht, dass dies möglich ist. (Versuchen, auf den Inhalt von A suchen nach B verbindet. Die Symbole von B in A kopiert wurden)

Wenn Sie einfach die Informationen in B perserve möchten, können Sie B zuerst mit llvm::CloneModule kopieren kann, vorbei an das Ergebnis zu Linker::linkModules .

+0

wie in normalen gemeinsam genutzten Bibliotheken, wenn 'B'changes,' A' müsste noch mit dem neuen B neu verknüpft werden. Mein Punkt ist: wenn A ist verknüpft mit 'B0',' B1' ... 'BN 'und einer von ihnen ändert sich, ich sollte nur die Verweise auf diesen wieder verknüpfen müssen, da der Rest sich nicht änderte. Das aktuelle linkModules funktioniert als statischer Linker (alles in das Zielmodul kopieren) – lurscher

+1

Der Linux-Kernel mit seinen Modulen erlaubt so etwas (entlädt ein Modul, lädt eine neue Version neu). Aber dort ist der Prozess unter der Kontrolle des Kernels, und es gibt Verriegelungen, um sicherzustellen, dass der Code nicht verwendet wird. – vonbrand

1

Wir haben etwas Ähnliches in der dynamischen Kompilierungsumgebung innerhalb unseres Fabric Engine-Produkts() gemacht. LLVM ist derzeit nicht sehr gut für diese Art von komplexer "JIT" -Umgebung geeignet, aber wir haben es geschafft, es durch eine zusätzliche Dereferenzierungsebene (dh einen Doppelzeiger) zu verknüpfen und dann llvm :: MemoryManager zu overload llvm zu unterklassifizieren: : MemoryManager :: getPointerToNamedFunction zum globalen Auflösen von Symbolen zwischen Modulen. Mit einem Doppelzeiger können Sie ein Modul ändern, ohne andere zu ändern. Sie müssen ein wenig vorsichtig sein, aber es ist nicht so schlimm.