Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Sep 7, 2024
1 parent e1ace5e commit 2e326cc
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 144 deletions.
10 changes: 8 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,15 @@ else()
endif()

if(WIN32)
list(APPEND MOLD_ELF_TEMPLATE_FILES src/subprocess-win32.cc)
list(APPEND MOLD_ELF_TEMPLATE_FILES
src/output-file-win32.cc
src/subprocess-win32.cc
)
else()
list(APPEND MOLD_ELF_TEMPLATE_FILES src/subprocess-unix.cc)
list(APPEND MOLD_ELF_TEMPLATE_FILES
src/output-file-unix.cc
src/subprocess-unix.cc
)
endif()

function(mold_instantiate_templates SOURCE TARGET)
Expand Down
89 changes: 1 addition & 88 deletions lib/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ namespace mold {
using namespace std::literals::string_literals;
using namespace std::literals::string_view_literals;

template <typename Context> class OutputFile;

inline char *output_tmpfile;

inline u8 *output_buffer_start = nullptr;
Expand All @@ -76,7 +74,7 @@ std::string get_self_path();
void cleanup();
void install_signal_handler();

static u64 combine_hash(u64 a, u64 b) {
inline u64 combine_hash(u64 a, u64 b) {
return a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2));
}

Expand Down Expand Up @@ -525,15 +523,6 @@ inline void overwrite_uleb(u8 *loc, u64 val) {
*loc = val & 0b0111'1111;
}

template <typename Context>
std::string_view save_string(Context &ctx, const std::string &str) {
u8 *buf = new u8[str.size() + 1];
memcpy(buf, str.data(), str.size());
buf[str.size()] = '\0';
ctx.string_pool.push_back(std::unique_ptr<u8[]>(buf));
return {(char *)buf, str.size()};
}

static inline void pause() {
#if defined(__x86_64__)
asm volatile("pause");
Expand Down Expand Up @@ -718,82 +707,6 @@ class ConcurrentMap {

void get_random_bytes(u8 *buf, i64 size);

//
// output-file.h
//

template <typename Context>
class OutputFile {
public:
static std::unique_ptr<OutputFile<Context>>
open(Context &ctx, std::string path, i64 filesize, int perm);

virtual void close(Context &ctx) = 0;
virtual ~OutputFile() = default;

u8 *buf = nullptr;
std::vector<u8> buf2;
std::string path;
int fd = -1;
i64 filesize = 0;
bool is_mmapped = false;
bool is_unmapped = false;

protected:
OutputFile(std::string path, i64 filesize, bool is_mmapped)
: path(path), filesize(filesize), is_mmapped(is_mmapped) {}
};

template <typename Context>
class MallocOutputFile : public OutputFile<Context> {
public:
MallocOutputFile(Context &ctx, std::string path, i64 filesize, int perm)
: OutputFile<Context>(path, filesize, false), ptr(new u8[filesize]),
perm(perm) {
this->buf = ptr.get();
}

void close(Context &ctx) override {
Timer t(ctx, "close_file");
FILE *fp;

if (this->path == "-") {
fp = stdout;
} else {
#ifdef _WIN32
int pmode = (perm & 0200) ? (_S_IREAD | _S_IWRITE) : _S_IREAD;
i64 fd = _open(this->path.c_str(), _O_RDWR | _O_CREAT | _O_BINARY, pmode);
#else
i64 fd = ::open(this->path.c_str(), O_RDWR | O_CREAT, perm);
#endif
if (fd == -1)
Fatal(ctx) << "cannot open " << this->path << ": " << errno_string();
#ifdef _WIN32
fp = _fdopen(fd, "wb");
#else
fp = fdopen(fd, "w");
#endif
}

fwrite(this->buf, this->filesize, 1, fp);
if (!this->buf2.empty())
fwrite(this->buf2.data(), this->buf2.size(), 1, fp);
fclose(fp);
}

private:
std::unique_ptr<u8[]> ptr;
int perm;
};

template <typename Context>
class LockingOutputFile : public OutputFile<Context> {
public:
LockingOutputFile(Context &ctx, std::string path, int perm);
void resize(Context &ctx, i64 filesize);
void close(Context &ctx) override;
};

//
// hyperloglog.cc
//
Expand Down
5 changes: 0 additions & 5 deletions lib/output-file.h

This file was deleted.

4 changes: 1 addition & 3 deletions src/main.cc
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "mold.h"
#include "filetype.h"
#include "../lib/archive-file.h"
#include "../lib/output-file.h"

#include <cstring>
#include <functional>
Expand Down Expand Up @@ -655,8 +654,7 @@ int mold_main(int argc, char **argv) {
t_before_copy.stop();

// Create an output file
ctx.output_file =
OutputFile<Context<E>>::open(ctx, ctx.arg.output, filesize, 0777);
ctx.output_file = OutputFile<E>::open(ctx, ctx.arg.output, filesize, 0777);
ctx.buf = ctx.output_file->buf;

Timer t_copy(ctx, "copy");
Expand Down
87 changes: 86 additions & 1 deletion src/mold.h
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,82 @@ class ComdatGroupSection : public Chunk<E> {
std::vector<Chunk<E> *> members;
};

//
// output-file.cc
//

template <typename E>
class OutputFile {
public:
static std::unique_ptr<OutputFile<E>>
open(Context<E> &ctx, std::string path, i64 filesize, int perm);

virtual void close(Context<E> &ctx) = 0;
virtual ~OutputFile() = default;

u8 *buf = nullptr;
std::vector<u8> buf2;
std::string path;
int fd = -1;
i64 filesize = 0;
bool is_mmapped = false;
bool is_unmapped = false;

protected:
OutputFile(std::string path, i64 filesize, bool is_mmapped)
: path(path), filesize(filesize), is_mmapped(is_mmapped) {}
};

template <typename E>
class MallocOutputFile : public OutputFile<E> {
public:
MallocOutputFile(Context<E> &ctx, std::string path, i64 filesize, int perm)
: OutputFile<E>(path, filesize, false), ptr(new u8[filesize]),
perm(perm) {
this->buf = ptr.get();
}

void close(Context<E> &ctx) override {
Timer t(ctx, "close_file");
FILE *fp;

if (this->path == "-") {
fp = stdout;
} else {
#ifdef _WIN32
int pmode = (perm & 0200) ? (_S_IREAD | _S_IWRITE) : _S_IREAD;
i64 fd = _open(this->path.c_str(), _O_RDWR | _O_CREAT | _O_BINARY, pmode);
#else
i64 fd = ::open(this->path.c_str(), O_RDWR | O_CREAT, perm);
#endif
if (fd == -1)
Fatal(ctx) << "cannot open " << this->path << ": " << errno_string();
#ifdef _WIN32
fp = _fdopen(fd, "wb");
#else
fp = fdopen(fd, "w");
#endif
}

fwrite(this->buf, this->filesize, 1, fp);
if (!this->buf2.empty())
fwrite(this->buf2.data(), this->buf2.size(), 1, fp);
fclose(fp);
}

private:
std::unique_ptr<u8[]> ptr;
int perm;
};

template <typename E>
class LockingOutputFile : public OutputFile<E> {
public:
LockingOutputFile(Context<E> &ctx, std::string path, int perm);
void resize(Context<E> &ctx, i64 filesize);
void close(Context<E> &ctx) override;
};

//
// gdb-index.cc
//
Expand Down Expand Up @@ -1956,7 +2032,7 @@ struct Context {
std::vector<ElfSym<E>> internal_esyms;

// Output buffer
std::unique_ptr<OutputFile<Context<E>>> output_file;
std::unique_ptr<OutputFile<E>> output_file;
u8 *buf = nullptr;
bool overwrite_output_file = true;

Expand Down Expand Up @@ -3021,4 +3097,13 @@ inline bool is_c_identifier(std::string_view s) {
return true;
}

template <typename E>
std::string_view save_string(Context<E> &ctx, const std::string &str) {
u8 *buf = new u8[str.size() + 1];
memcpy(buf, str.data(), str.size());
buf[str.size()] = '\0';
ctx.string_pool.push_back(std::unique_ptr<u8[]>(buf));
return {(char *)buf, str.size()};
}

} // namespace mold
47 changes: 26 additions & 21 deletions lib/output-file-unix.h → src/output-file-unix.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "common.h"
#include "mold.h"

#include <fcntl.h>
#include <filesystem>
Expand All @@ -9,15 +9,15 @@

namespace mold {

inline u32 get_umask() {
static u32 get_umask() {
u32 orig_umask = umask(0);
umask(orig_umask);
return orig_umask;
}

template <typename Context>
template <typename E>
static int
open_or_create_file(Context &ctx, std::string path, std::string tmpfile,
open_or_create_file(Context<E> &ctx, std::string path, std::string tmpfile,
int perm) {
// Reuse an existing file if exists and writable because on Linux,
// writing to an existing file is much faster than creating a fresh
Expand All @@ -35,11 +35,11 @@ open_or_create_file(Context &ctx, std::string path, std::string tmpfile,
return fd;
}

template <typename Context>
class MemoryMappedOutputFile : public OutputFile<Context> {
template <typename E>
class MemoryMappedOutputFile : public OutputFile<E> {
public:
MemoryMappedOutputFile(Context &ctx, std::string path, i64 filesize, int perm)
: OutputFile<Context>(path, filesize, true) {
MemoryMappedOutputFile(Context<E> &ctx, std::string path, i64 filesize, int perm)
: OutputFile<E>(path, filesize, true) {
std::filesystem::path dir = filepath(path).parent_path();
std::string filename = filepath(path).filename().string();
std::string tmpfile = dir / ("." + filename + "." + std::to_string(getpid()));
Expand Down Expand Up @@ -72,7 +72,7 @@ class MemoryMappedOutputFile : public OutputFile<Context> {
::close(fd2);
}

void close(Context &ctx) override {
void close(Context<E> &ctx) override {
Timer t(ctx, "close_file");

if (!this->is_unmapped)
Expand Down Expand Up @@ -103,9 +103,9 @@ class MemoryMappedOutputFile : public OutputFile<Context> {
int fd2 = -1;
};

template <typename Context>
std::unique_ptr<OutputFile<Context>>
OutputFile<Context>::open(Context &ctx, std::string path, i64 filesize, int perm) {
template <typename E>
std::unique_ptr<OutputFile<E>>
OutputFile<E>::open(Context<E> &ctx, std::string path, i64 filesize, int perm) {
Timer t(ctx, "open_file");

if (path.starts_with('/') && !ctx.arg.chroot.empty())
Expand All @@ -120,7 +120,7 @@ OutputFile<Context>::open(Context &ctx, std::string path, i64 filesize, int perm
is_special = true;
}

OutputFile<Context> *file;
OutputFile<E> *file;
if (is_special)
file = new MallocOutputFile(ctx, path, filesize, perm);
else
Expand All @@ -146,10 +146,10 @@ OutputFile<Context>::open(Context &ctx, std::string path, i64 filesize, int perm

// LockingOutputFile is similar to MemoryMappedOutputFile, but it doesn't
// rename output files and instead acquires file lock using flock().
template <typename Context>
LockingOutputFile<Context>::LockingOutputFile(Context &ctx, std::string path,
int perm)
: OutputFile<Context>(path, 0, true) {
template <typename E>
LockingOutputFile<E>::LockingOutputFile(Context<E> &ctx, std::string path,
int perm)
: OutputFile<E>(path, 0, true) {
this->fd = ::open(path.c_str(), O_RDWR | O_CREAT, perm);
if (this->fd == -1)
Fatal(ctx) << "cannot open " << path << ": " << errno_string();
Expand All @@ -162,8 +162,8 @@ LockingOutputFile<Context>::LockingOutputFile(Context &ctx, std::string path,
(void)!!write(this->fd, buf, sizeof(buf));
}

template <typename Context>
void LockingOutputFile<Context>::resize(Context &ctx, i64 filesize) {
template <typename E>
void LockingOutputFile<E>::resize(Context<E> &ctx, i64 filesize) {
if (ftruncate(this->fd, filesize) == -1)
Fatal(ctx) << "ftruncate failed: " << errno_string();

Expand All @@ -177,8 +177,8 @@ void LockingOutputFile<Context>::resize(Context &ctx, i64 filesize) {
mold::output_buffer_end = this->buf + filesize;
}

template <typename Context>
void LockingOutputFile<Context>::close(Context &ctx) {
template <typename E>
void LockingOutputFile<E>::close(Context<E> &ctx) {
if (!this->is_unmapped)
munmap(this->buf, this->filesize);

Expand All @@ -192,4 +192,9 @@ void LockingOutputFile<Context>::close(Context &ctx) {
::close(this->fd);
}

using E = MOLD_TARGET;

template class OutputFile<E>;
template class LockingOutputFile<E>;

} // namespace mold
Loading

0 comments on commit 2e326cc

Please sign in to comment.