//===-- JITEmitter.cpp - Write machine code to executable memory ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a MachineCodeEmitter object that is used by the JIT to
// write machine code to memory and remember where relocatable values are.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "jit"
#include "JIT.h"
#include "JITDwarfEmitter.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRelocation.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetJITInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/System/Disassembler.h"
#include "llvm/System/Memory.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
#include <algorithm>
#ifndef NDEBUG
#include <iomanip>
#endif
using namespace llvm;
STATISTIC(NumBytes, "Number of bytes of machine code compiled");
STATISTIC(NumRelos, "Number of relocations applied");
static JIT *TheJIT = 0;
//===----------------------------------------------------------------------===//
// JIT lazy compilation code.
//
namespace {
class JITResolverState {
private:
/// FunctionToStubMap - Keep track of the stub created for a particular
/// function so that we can reuse them if necessary.
std::map<Function*, void*> FunctionToStubMap;
/// StubToFunctionMap - Keep track of the function that each stub
/// corresponds to.
std::map<void*, Function*> StubToFunctionMap;
/// GlobalToNonLazyPtrMap - Keep track of the lazy pointer created for a
/// particular GlobalVariable so that we can reuse them if necessary.
std::map<GlobalValue*, void*> GlobalToNonLazyPtrMap;
public:
std::map<Function*, void*>& getFunctionToStubMap(const MutexGuard& locked) {
assert(locked.holds(TheJIT->lock));
return FunctionToStubMap;
}
std::map<void*, Function*>& getStubToFunctionMap(const MutexGuard& locked) {
assert(locked.holds(TheJIT->lock));
return StubToFunctionMap;
}
std::map<GlobalValue*, void*>&
getGlobalToNonLazyPtrMap(const MutexGuard& locked) {
assert(locked.holds(TheJIT->lock));
return GlobalToNonLazyPtrMap;
}
};
/// JITResolver - Keep track of, and resolve, call sites for functions that
/// have not yet been compiled.
class JITResolver {
/// LazyResolverFn - The target lazy resolver function that we actually
/// rewrite instructions to use.
TargetJITInfo::LazyResolverFn LazyResolverFn;
JITResolverState state;
/// ExternalFnToStubMap - This is the equivalent of FunctionToStubMap for
/// external functions.
std::map<void*, void*> ExternalFnToStubMap;
//map addresses to indexes in the GOT
std::map<void*, unsigned> revGOTMap;
unsigned nextGOTIndex;
static JITResolver *TheJITResolver;
public:
explicit JITResolver(JIT &jit) : nextGOTIndex(0) {
TheJIT = &jit;
LazyResolverFn = jit.getJITInfo().getLazyResolverFunction(JITCompilerFn);
assert(TheJITResolver == 0 &&