Pete Cooper 8ad55fb2d0 Use owning pointers instead of raw pointers for Atom's to fix leaks.
This is a re-commit of r264022 with a fix for MSVC.  The issue there was
that the code was running DefinedAtom::~Atom() for some value and instead
needed to cast to Atom before running ~Atom.  Original commit message follows.

Currently each File contains an BumpPtrAllocator in which Atom's are
allocated.  Some Atom's contain data structures like std::vector which
leak as we don't run ~Atom when they are BumpPtrAllocate'd.

Now each File actually owns its Atom's using an OwningAtomPtr.  This
is analygous to std::unique_ptr and may be replaced by it if possible.

An Atom can therefore only be owned by a single File, so the Resolver now
moves them from one File to another.  The MachOLinkingContext owns the File's
and so clears all the Atom's in ~MachOLinkingContext, then delete's all the
File's.  This makes sure all Atom's have been destructed before any of the
BumpPtrAllocator's in which they run have gone away.

Should hopefully fix the remaining leaks.  Will keep an eye on the bots to
make sure.

llvm-svn: 264067
2016-03-22 17:15:50 +00:00

129 lines
3.3 KiB
C++

//===- lib/ReaderWriter/MachO/ObjCPass.cpp -------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//
#include "ArchHandler.h"
#include "File.h"
#include "MachOPasses.h"
#include "lld/Core/DefinedAtom.h"
#include "lld/Core/File.h"
#include "lld/Core/LLVM.h"
#include "lld/Core/Reference.h"
#include "lld/Core/Simple.h"
#include "lld/ReaderWriter/MachOLinkingContext.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
namespace lld {
namespace mach_o {
///
/// ObjC Image Info Atom created by the ObjC pass.
///
class ObjCImageInfoAtom : public SimpleDefinedAtom {
public:
ObjCImageInfoAtom(const File &file,
MachOLinkingContext::ObjCConstraint objCConstraint,
uint32_t swiftVersion)
: SimpleDefinedAtom(file) {
Data.info.version = 0;
switch (objCConstraint) {
case MachOLinkingContext::objc_unknown:
llvm_unreachable("Shouldn't run the objc pass without a constraint");
case MachOLinkingContext::objc_supports_gc:
case MachOLinkingContext::objc_gc_only:
llvm_unreachable("GC is not supported");
case MachOLinkingContext::objc_retainReleaseForSimulator:
// The retain/release for simulator flag is already the correct
// encoded value for the data so just set it here.
Data.info.flags = (uint32_t)objCConstraint;
break;
case MachOLinkingContext::objc_retainRelease:
// We don't need to encode this flag, so just leave the flags as 0.
Data.info.flags = 0;
break;
}
Data.info.flags |= (swiftVersion << 8);
}
~ObjCImageInfoAtom() override = default;
ContentType contentType() const override {
return DefinedAtom::typeObjCImageInfo;
}
Alignment alignment() const override {
return 4;
}
uint64_t size() const override {
return 8;
}
ContentPermissions permissions() const override {
return DefinedAtom::permR__;
}
ArrayRef<uint8_t> rawContent() const override {
return llvm::makeArrayRef(Data.bytes, size());
}
private:
struct objc_image_info {
uint32_t version;
uint32_t flags;
};
union {
objc_image_info info;
uint8_t bytes[8];
} Data;
};
class ObjCPass : public Pass {
public:
ObjCPass(const MachOLinkingContext &context)
: _ctx(context),
_file(*_ctx.make_file<MachOFile>("<mach-o objc pass>")) {
_file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
}
std::error_code perform(SimpleFile &mergedFile) override {
// Add the image info.
mergedFile.addAtom(*getImageInfo());
return std::error_code();
}
private:
const DefinedAtom* getImageInfo() {
return new (_file.allocator()) ObjCImageInfoAtom(_file,
_ctx.objcConstraint(),
_ctx.swiftVersion());
}
const MachOLinkingContext &_ctx;
MachOFile &_file;
};
void addObjCPass(PassManager &pm, const MachOLinkingContext &ctx) {
pm.add(llvm::make_unique<ObjCPass>(ctx));
}
} // end namespace mach_o
} // end namespace lld