[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