[pkg-d-commits] [ldc] 160/211: Implement different cache recovery mechanisms.
Matthias Klumpp
mak at moszumanska.debian.org
Sun Apr 23 22:36:19 UTC 2017
This is an automated email from the git hooks/post-receive script.
mak pushed a commit to annotated tag v1.1.0
in repository ldc.
commit 05ce3a3170ce481597135920504caf9a3ab7b5eb
Author: Johan Engelen <jbc.engelen at gmail.com>
Date: Wed Nov 23 16:15:57 2016 +0100
Implement different cache recovery mechanisms.
---
driver/cache.cpp | 115 +++++++++++++++++++++++++++++--
tests/linking/ir2obj_caching.d | 1 -
tests/linking/ir2obj_caching_retrieval.d | 19 +++++
3 files changed, 128 insertions(+), 7 deletions(-)
diff --git a/driver/cache.cpp b/driver/cache.cpp
index 2ca64c1..2e014e9 100644
--- a/driver/cache.cpp
+++ b/driver/cache.cpp
@@ -55,6 +55,61 @@
#include <io.h>
#endif
+#if LDC_POSIX
+#include <unistd.h>
+// Returns true upon error.
+static bool createHardLink(const char *to, const char *from) {
+ return link(to, from) == -1;
+}
+// Returns true upon error.
+static bool createSymLink(const char *to, const char *from) {
+ return symlink(to, from) == -1;
+}
+#elif _WIN32
+#include <windows.h>
+namespace llvm {
+namespace sys {
+namespace path {
+// Fwd declaration to an internal LLVM function.
+std::error_code widenPath(const llvm::Twine &Path8,
+ llvm::SmallVectorImpl<wchar_t> &Path16);
+}
+}
+}
+// Returns true upon error.
+namespace {
+template <typename FType>
+bool createLink(FType f, const char *to, const char *from) {
+ //===----------------------------------------------------------------------===//
+ //
+ // Code copied from LLVM 3.9 llvm/Support/Windows/Path.inc, distributed under
+ // the University of Illinois Open Source License. See LICENSE for details.
+ //
+ //===----------------------------------------------------------------------===//
+
+ llvm::SmallVector<wchar_t, 128> wide_from;
+ llvm::SmallVector<wchar_t, 128> wide_to;
+ if (llvm::sys::path::widenPath(from, wide_from))
+ return true;
+ if (llvm::sys::path::widenPath(to, wide_to))
+ return true;
+
+ if (!(*f)(wide_from.begin(), wide_to.begin(), NULL))
+ return true;
+
+ return false;
+}
+}
+// Returns true upon error.
+static bool createHardLink(const char *to, const char *from) {
+ return createLink(&CreateHardLinkW, to, from);
+}
+// Returns true upon error.
+static bool createSymLink(const char *to, const char *from) {
+ return createLink(&CreateSymbolicLinkW, to, from);
+}
+#endif
+
namespace {
// Options for the cache pruning algorithm
@@ -85,6 +140,22 @@ llvm::cl::opt<unsigned> pruneSizeLimitPercentage(
"space (default: 75%). Implies -cache-prune."),
llvm::cl::value_desc("perc"), llvm::cl::init(75));
+enum class RetrievalMode { Copy, HardLink, AnyLink, SymLink };
+llvm::cl::opt<RetrievalMode> cacheRecoveryMode(
+ "cache-retrieval",
+ llvm::cl::desc("Set the cache retrieval mechanism (default: copy)."),
+ llvm::cl::init(RetrievalMode::Copy),
+ clEnumValues(
+ clEnumValN(RetrievalMode::Copy, "copy",
+ "Make a copy of the cache file"),
+ clEnumValN(RetrievalMode::HardLink, "hardlink",
+ "Create a hard link to the cache file (recommended)"),
+ clEnumValN(
+ RetrievalMode::AnyLink, "link",
+ "Equal to 'hardlink' on Windows, but 'symlink' on Unix and OS X"),
+ clEnumValN(RetrievalMode::SymLink, "symlink",
+ "Create a symbolic link to the cache file")));
+
bool isPruningEnabled() {
if (pruneEnabled)
return true;
@@ -323,12 +394,44 @@ void recoverObjectFile(llvm::StringRef cacheObjectHash,
// Remove the potentially pre-existing output file.
llvm::sys::fs::remove(objectFile);
- IF_LOG Logger::println("SymLink output to cached object file: %s -> %s",
- objectFile.str().c_str(), cacheFile.c_str());
- if (llvm::sys::fs::create_link(cacheFile.c_str(), objectFile)) {
- error(Loc(), "Failed to create a symlink to the cached file: %s -> %s",
- cacheFile.c_str(), objectFile.str().c_str());
- fatal();
+ switch (cacheRecoveryMode) {
+ case RetrievalMode::Copy: {
+ IF_LOG Logger::println("Copy cached object file: %s -> %s",
+ cacheFile.c_str(), objectFile.str().c_str());
+ if (llvm::sys::fs::copy_file(cacheFile.c_str(), objectFile)) {
+ error(Loc(), "Failed to copy the cached file: %s -> %s",
+ cacheFile.c_str(), objectFile.str().c_str());
+ fatal();
+ }
+ } break;
+ case RetrievalMode::HardLink: {
+ IF_LOG Logger::println("HardLink output to cached object file: %s -> %s",
+ objectFile.str().c_str(), cacheFile.c_str());
+ if (createHardLink(cacheFile.c_str(), objectFile.str().c_str())) {
+ error(Loc(), "Failed to create a hard link to the cached file: %s -> %s",
+ cacheFile.c_str(), objectFile.str().c_str());
+ fatal();
+ }
+ } break;
+ case RetrievalMode::AnyLink: {
+ IF_LOG Logger::println("Link output to cached object file: %s -> %s",
+ objectFile.str().c_str(), cacheFile.c_str());
+ if (llvm::sys::fs::create_link(cacheFile.c_str(), objectFile)) {
+ error(Loc(), "Failed to create a link to the cached file: %s -> %s",
+ cacheFile.c_str(), objectFile.str().c_str());
+ fatal();
+ }
+ } break;
+ case RetrievalMode::SymLink: {
+ IF_LOG Logger::println("SymLink output to cached object file: %s -> %s",
+ objectFile.str().c_str(), cacheFile.c_str());
+ if (createSymLink(cacheFile.c_str(), objectFile.str().c_str())) {
+ error(Loc(),
+ "Failed to create a symbolic link to the cached file: %s -> %s",
+ cacheFile.c_str(), objectFile.str().c_str());
+ fatal();
+ }
+ } break;
}
// We reset the modification time to "now" such that the pruning algorithm
diff --git a/tests/linking/ir2obj_caching.d b/tests/linking/ir2obj_caching.d
index d82af8a..3f8e881 100644
--- a/tests/linking/ir2obj_caching.d
+++ b/tests/linking/ir2obj_caching.d
@@ -9,7 +9,6 @@
// SECOND: Use IR-to-Object cache in {{.*}}cachedirectory
// SECOND: Cache object found!
-// SECOND: SymLink output to cached object file
void main()
{
diff --git a/tests/linking/ir2obj_caching_retrieval.d b/tests/linking/ir2obj_caching_retrieval.d
new file mode 100644
index 0000000..431051c
--- /dev/null
+++ b/tests/linking/ir2obj_caching_retrieval.d
@@ -0,0 +1,19 @@
+// Test recognition of -cache-retrieval commandline flag
+
+// RUN: %ldc -c -of=%t%obj -cache=%T/cachedirectory %s -vv | FileCheck --check-prefix=FIRST %s \
+// RUN: && %ldc -c -of=%t%obj -cache=%T/cachedirectory %s -cache-retrieval=copy -vv | FileCheck --check-prefix=MUST_HIT %s \
+// RUN: && %ldc %t%obj \
+// RUN: && %ldc -c -of=%t%obj -cache=%T/cachedirectory %s -cache-retrieval=link -vv | FileCheck --check-prefix=MUST_HIT %s \
+// RUN: && %ldc %t%obj \
+// RUN: && %ldc -c -of=%t%obj -cache=%T/cachedirectory %s -cache-retrieval=hardlink -vv | FileCheck --check-prefix=MUST_HIT %s \
+// RUN: && %ldc %t%obj
+
+// FIRST: Use IR-to-Object cache in {{.*}}cachedirectory
+// Don't check whether the object is in the cache on the first run, because if this test is ran twice the cache will already be there.
+
+// MUST_HIT: Use IR-to-Object cache in {{.*}}cachedirectory
+// MUST_HIT: Cache object found!
+
+void main()
+{
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git
More information about the pkg-d-commits
mailing list