Skip to content

Commit

Permalink
[MCJIT] Clean up RuntimeDyld's quirky object-ownership/modification s…
Browse files Browse the repository at this point in the history
…cheme.

Previously, when loading an object file, RuntimeDyld (1) took ownership of the
ObjectFile instance (and associated MemoryBuffer), (2) potentially modified the
object in-place, and (3) returned an ObjectImage that managed ownership of the
now-modified object and provided some convenience methods. This scheme accreted
over several years as features were tacked on to RuntimeDyld, and was both
unintuitive and unsafe (See e.g. http://llvm.org/PR20722).

This patch fixes the issue by removing all ownership and in-place modification
of object files from RuntimeDyld. Existing behavior, including debugger
registration, is preserved.

Noteworthy changes include:

(1) ObjectFile instances are now passed to RuntimeDyld by const-ref.
(2) The ObjectImage and ObjectBuffer classes have been removed entirely, they
    existed to model ownership within RuntimeDyld, and so are no longer needed.
(3) RuntimeDyld::loadObject now returns an instance of a new class,
    RuntimeDyld::LoadedObjectInfo, which can be used to construct a modified
    object suitable for registration with the debugger, following the existing
    debugger registration scheme.
(4) The JITRegistrar class has been removed, and the GDBRegistrar class has been
    re-written as a JITEventListener.

This should fix http://llvm.org/PR20722 .



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222810 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
lhames committed Nov 26, 2014
1 parent 568f7e8 commit 7acaefa
Show file tree
Hide file tree
Showing 31 changed files with 633 additions and 871 deletions.
19 changes: 14 additions & 5 deletions include/llvm/ExecutionEngine/JITEventListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
#define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H

#include "RuntimeDyld.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/DataTypes.h"
Expand All @@ -25,7 +26,10 @@ class Function;
class MachineFunction;
class OProfileWrapper;
class IntelJITEventsWrapper;
class ObjectImage;

namespace object {
class ObjectFile;
}

/// JITEvent_EmittedFunctionDetails - Helper struct for containing information
/// about a generated machine code function.
Expand Down Expand Up @@ -57,7 +61,7 @@ class JITEventListener {

public:
JITEventListener() {}
virtual ~JITEventListener();
virtual ~JITEventListener() {}

/// NotifyObjectEmitted - Called after an object has been successfully
/// emitted to memory. NotifyFunctionEmitted will not be called for
Expand All @@ -67,11 +71,15 @@ class JITEventListener {
/// The ObjectImage contains the generated object image
/// with section headers updated to reflect the address at which sections
/// were loaded and with relocations performed in-place on debug sections.
virtual void NotifyObjectEmitted(const ObjectImage &Obj) {}
virtual void NotifyObjectEmitted(const object::ObjectFile &Obj,
const RuntimeDyld::LoadedObjectInfo &L) {}

/// NotifyFreeingObject - Called just before the memory associated with
/// a previously emitted object is released.
virtual void NotifyFreeingObject(const ObjectImage &Obj) {}
virtual void NotifyFreeingObject(const object::ObjectFile &Obj) {}

// Get a pointe to the GDB debugger registration listener.
static JITEventListener *createGDBRegistrationListener();

#if LLVM_USE_INTEL_JITEVENTS
// Construct an IntelJITEventListener
Expand Down Expand Up @@ -105,7 +113,8 @@ class JITEventListener {
return nullptr;
}
#endif // USE_OPROFILE

private:
virtual void anchor();
};

} // end namespace llvm.
Expand Down
76 changes: 0 additions & 76 deletions include/llvm/ExecutionEngine/ObjectBuffer.h

This file was deleted.

76 changes: 0 additions & 76 deletions include/llvm/ExecutionEngine/ObjectImage.h

This file was deleted.

7 changes: 5 additions & 2 deletions include/llvm/ExecutionEngine/RTDyldMemoryManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
namespace llvm {

class ExecutionEngine;
class ObjectImage;

namespace object {
class ObjectFile;
}

// RuntimeDyld clients often want to handle the memory management of
// what gets placed where. For JIT clients, this is the subset of
Expand Down Expand Up @@ -109,7 +112,7 @@ class RTDyldMemoryManager {
/// address space can use this call to remap the section addresses for the
/// newly loaded object.
virtual void notifyObjectLoaded(ExecutionEngine *EE,
const ObjectImage *) {}
const object::ObjectFile &) {}

/// This method is called when object loading is complete and section page
/// permissions can be applied. It is up to the memory manager implementation
Expand Down
43 changes: 28 additions & 15 deletions include/llvm/ExecutionEngine/RuntimeDyld.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H

#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/ObjectBuffer.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/Support/Memory.h"
#include <memory>

namespace llvm {

namespace object {
class ObjectFile;
template <typename T> class OwningBinary;
}

class RuntimeDyldImpl;
class RuntimeDyldCheckerImpl;
class ObjectImage;

class RuntimeDyld {
friend class RuntimeDyldCheckerImpl;
Expand All @@ -46,22 +46,35 @@ class RuntimeDyld {
// Any relocations already associated with the symbol will be re-resolved.
void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
public:

/// \brief Information about the loaded object.
class LoadedObjectInfo {
friend class RuntimeDyldImpl;
public:
LoadedObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
unsigned EndIdx)
: RTDyld(RTDyld), BeginIdx(BeginIdx), EndIdx(EndIdx) { }

virtual ~LoadedObjectInfo() {}

virtual object::OwningBinary<object::ObjectFile>
getObjectForDebug(const object::ObjectFile &Obj) const = 0;

uint64_t getSectionLoadAddress(StringRef Name) const;

protected:
virtual void anchor();

RuntimeDyldImpl &RTDyld;
unsigned BeginIdx, EndIdx;
};

RuntimeDyld(RTDyldMemoryManager *);
~RuntimeDyld();

/// Prepare the object contained in the input buffer for execution.
/// Ownership of the input buffer is transferred to the ObjectImage
/// instance returned from this function if successful. In the case of load
/// failure, the input buffer will be deleted.
std::unique_ptr<ObjectImage>
loadObject(std::unique_ptr<ObjectBuffer> InputBuffer);

/// Prepare the referenced object file for execution.
/// Ownership of the input object is transferred to the ObjectImage
/// instance returned from this function if successful. In the case of load
/// failure, the input object will be deleted.
std::unique_ptr<ObjectImage>
loadObject(std::unique_ptr<object::ObjectFile> InputObject);
/// Add the referenced object file to the list of objects to be loaded and
/// relocated.
std::unique_ptr<LoadedObjectInfo> loadObject(const object::ObjectFile &O);

/// Get the address of our local copy of the symbol. This may or may not
/// be the address used for relocation (clients can copy the data around
Expand Down
1 change: 0 additions & 1 deletion lib/ExecutionEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
add_llvm_library(LLVMExecutionEngine
ExecutionEngine.cpp
ExecutionEngineBindings.cpp
JITEventListener.cpp
RTDyldMemoryManager.cpp
TargetSelect.cpp
)
Expand Down
11 changes: 4 additions & 7 deletions lib/ExecutionEngine/ExecutionEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/ObjectBuffer.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
Expand All @@ -43,17 +42,15 @@ using namespace llvm;
STATISTIC(NumInitBytes, "Number of bytes of global vars initialized");
STATISTIC(NumGlobals , "Number of global vars initialized");

// Pin the vtable to this file.
void ObjectCache::anchor() {}
void ObjectBuffer::anchor() {}
void ObjectBufferStream::anchor() {}

ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
std::unique_ptr<Module> M, std::string *ErrorStr,
RTDyldMemoryManager *MCJMM, std::unique_ptr<TargetMachine> TM) = nullptr;
ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr<Module> M,
std::string *ErrorStr) =nullptr;

// Anchor for the JITEventListener class.
void JITEventListener::anchor() {}

ExecutionEngine::ExecutionEngine(std::unique_ptr<Module> M)
: EEState(*this),
LazyFunctionCreator(nullptr) {
Expand Down
Loading

0 comments on commit 7acaefa

Please sign in to comment.