Skip to content

Commit 84aa0e0

Browse files
haxorzcopybara-github
authored andcommitted
Don't create-and-retain a PathFragment instance for suffix for each Runfiles instance.
In practice, `suffix` is always the workspace name string, so all these `PathFragment`s are wasteful dupes. Instead, we create the `PathFragment` on the fly (and then throw it away) when needed. Thus this is essentially a logical rollback of unknown commit (in other words, that CL was actually a memory regression). As an alternative, I considered threading through a logical singleton `PathFragment` to all `Runfiles` instances (e.g. from `RuleClassProvider`) but that had a much larger blast radius. While I'm here, rename `suffix` to `prefix`. Afaict, the code actually means to say "prefix" and "suffix" was a mistake in unknown commit. PiperOrigin-RevId: 671429745 Change-Id: I1e72588859ceab39bcd3f05fa8760aa0d7096b79
1 parent b663e0c commit 84aa0e0

File tree

4 files changed

+28
-40
lines changed

4 files changed

+28
-40
lines changed

src/main/java/com/google/devtools/build/lib/analysis/Runfiles.java

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ public void fingerprint(Fingerprint fp) {
118118
*
119119
* <p>Using "foo" will put runfiles under &lt;target&gt;.runfiles/foo.
120120
*
121-
* <p>This is either set to the workspace name, or is empty.
121+
* <p>This is either set to the workspace name, or the empty string.
122122
*/
123-
private final PathFragment suffix;
123+
private final String prefix;
124124

125125
/**
126126
* The artifacts that should be present in the runfiles directory.
@@ -194,14 +194,14 @@ public enum ConflictPolicy {
194194
private final boolean legacyExternalRunfiles;
195195

196196
private Runfiles(
197-
PathFragment suffix,
197+
String prefix,
198198
NestedSet<Artifact> artifacts,
199199
NestedSet<SymlinkEntry> symlinks,
200200
NestedSet<SymlinkEntry> rootSymlinks,
201201
EmptyFilesSupplier emptyFilesSupplier,
202202
ConflictPolicy conflictPolicy,
203203
boolean legacyExternalRunfiles) {
204-
this.suffix = suffix;
204+
this.prefix = prefix;
205205
this.artifacts = Preconditions.checkNotNull(artifacts);
206206
this.symlinks = Preconditions.checkNotNull(symlinks);
207207
this.rootSymlinks = Preconditions.checkNotNull(rootSymlinks);
@@ -215,11 +215,9 @@ public boolean isImmutable() {
215215
return true; // immutable and Starlark-hashable
216216
}
217217

218-
/**
219-
* Returns the runfiles' suffix.
220-
*/
221-
public PathFragment getSuffix() {
222-
return suffix;
218+
/** Returns the runfiles' prefix. This is the same as the workspace name. */
219+
public String getPrefix() {
220+
return prefix;
223221
}
224222

225223
/** Returns the collection of runfiles as artifacts. */
@@ -366,7 +364,8 @@ public Map<PathFragment, Artifact> getRunfilesInputs(
366364
// Copy manifest map to another manifest map, prepending the workspace name to every path.
367365
// E.g. for workspace "myworkspace", the runfile entry "mylib.so"->"/path/to/mylib.so" becomes
368366
// "myworkspace/mylib.so"->"/path/to/mylib.so".
369-
ManifestBuilder builder = new ManifestBuilder(suffix, legacyExternalRunfiles);
367+
ManifestBuilder builder =
368+
new ManifestBuilder(PathFragment.create(prefix), legacyExternalRunfiles);
370369
builder.addUnderWorkspace(manifest, checker);
371370

372371
// Finally add symlinks relative to the root of the runfiles tree, on top of everything else.
@@ -640,7 +639,7 @@ public void put(Map<PathFragment, Artifact> map, PathFragment path, Artifact art
640639
public static final class Builder {
641640

642641
/** This is set to the workspace name */
643-
private final PathFragment suffix;
642+
private final String prefix;
644643

645644
/**
646645
* This must be COMPILE_ORDER because {@link #asMapWithoutRootSymlinks} overwrites earlier
@@ -662,7 +661,7 @@ public static final class Builder {
662661
* Only used for Runfiles.EMPTY.
663662
*/
664663
private Builder() {
665-
this.suffix = PathFragment.EMPTY_FRAGMENT;
664+
this.prefix = "";
666665
this.legacyExternalRunfiles = false;
667666
}
668667

@@ -678,23 +677,12 @@ public Builder(String workspace) {
678677

679678
/**
680679
* Creates a builder with the given suffix.
681-
* @param workspace is the string specified in workspace() in the WORKSPACE file.
682-
* @param legacyExternalRunfiles if the wsname/external/repo symlinks should also be
683-
* created.
684-
*/
685-
public Builder(String workspace, boolean legacyExternalRunfiles) {
686-
this(PathFragment.create(workspace), legacyExternalRunfiles);
687-
}
688-
689-
/**
690-
* Creates a builder with the given suffix.
691-
* @param suffix is the PathFragment wrapping the string specified in workspace() in the
692-
* WORKSPACE file.
693-
* @param legacyExternalRunfiles if the wsname/external/repo symlinks should also be
694-
* created.
680+
*
681+
* @param prefix is the string specified in workspace() in the WORKSPACE file.
682+
* @param legacyExternalRunfiles if the wsname/external/repo symlinks should also be created.
695683
*/
696-
private Builder(PathFragment suffix, boolean legacyExternalRunfiles) {
697-
this.suffix = suffix;
684+
public Builder(String prefix, boolean legacyExternalRunfiles) {
685+
this.prefix = prefix;
698686
this.legacyExternalRunfiles = legacyExternalRunfiles;
699687
}
700688

@@ -703,7 +691,7 @@ private Builder(PathFragment suffix, boolean legacyExternalRunfiles) {
703691
*/
704692
public Runfiles build() {
705693
return new Runfiles(
706-
suffix,
694+
prefix,
707695
artifactsBuilder.build(),
708696
symlinksBuilder.build(),
709697
rootSymlinksBuilder.build(),
@@ -832,10 +820,10 @@ public Builder merge(Runfiles runfiles) {
832820
if (runfiles.isEmpty()) {
833821
return this;
834822
}
835-
// The suffix should be the same within any blaze build, except for the EMPTY runfiles, which
836-
// may have an empty suffix, but that is covered above.
823+
// The prefix should be the same within any blaze build, except for the EMPTY runfiles, which
824+
// may have an empty prefix, but that is covered above.
837825
Preconditions.checkArgument(
838-
suffix.equals(runfiles.suffix), "%s != %s", suffix, runfiles.suffix);
826+
prefix.equals(runfiles.prefix), "%s != %s", prefix, runfiles.prefix);
839827
artifactsBuilder.addTransitive(runfiles.getArtifacts());
840828
symlinksBuilder.addTransitive(runfiles.getSymlinks());
841829
rootSymlinksBuilder.addTransitive(runfiles.getRootSymlinks());
@@ -1026,7 +1014,7 @@ public Runfiles merge(RunfilesApi other, StarlarkThread thread) throws EvalExcep
10261014
} else if (o.isEmpty()) {
10271015
return this;
10281016
}
1029-
return new Runfiles.Builder(suffix, false)
1017+
return new Runfiles.Builder(prefix, false)
10301018
.merge(this)
10311019
.merge(o)
10321020
.build()
@@ -1044,15 +1032,15 @@ public Runfiles mergeAll(Sequence<?> sequence, StarlarkThread thread) throws Eva
10441032
// and `x.merge(y)` in Starlark.
10451033
Runfiles uniqueNonEmptyMergee = null;
10461034
if (!this.isEmpty()) {
1047-
builder = new Builder(suffix, false).merge(this);
1035+
builder = new Builder(prefix, false).merge(this);
10481036
uniqueNonEmptyMergee = this;
10491037
}
10501038

10511039
Sequence<Runfiles> runfilesSequence = Sequence.cast(sequence, Runfiles.class, "param");
10521040
for (Runfiles runfiles : runfilesSequence) {
10531041
if (!runfiles.isEmpty()) {
10541042
if (builder == null) {
1055-
builder = new Builder(runfiles.suffix, /* legacyExternalRunfiles = */ false);
1043+
builder = new Builder(runfiles.prefix, /* legacyExternalRunfiles= */ false);
10561044
uniqueNonEmptyMergee = runfiles;
10571045
} else {
10581046
uniqueNonEmptyMergee = null;
@@ -1075,7 +1063,7 @@ public void fingerprint(
10751063
ActionKeyContext actionKeyContext, Fingerprint fp, boolean digestAbsolutePaths) {
10761064
fp.addInt(conflictPolicy.ordinal());
10771065
fp.addBoolean(legacyExternalRunfiles);
1078-
fp.addPath(suffix);
1066+
fp.addString(prefix);
10791067

10801068
actionKeyContext.addNestedSetToFingerprint(SYMLINK_ENTRY_MAP_FN, fp, symlinks);
10811069
actionKeyContext.addNestedSetToFingerprint(SYMLINK_ENTRY_MAP_FN, fp, rootSymlinks);
@@ -1094,7 +1082,7 @@ public void fingerprint(
10941082
String describeFingerprint(boolean digestAbsolutePaths) {
10951083
return String.format("conflictPolicy: %s\n", conflictPolicy)
10961084
+ String.format("legacyExternalRunfiles: %s\n", legacyExternalRunfiles)
1097-
+ String.format("suffix: %s\n", suffix)
1085+
+ String.format("prefix: %s\n", prefix)
10981086
+ String.format(
10991087
"symlinks: %s\n", describeNestedSetFingerprint(SYMLINK_ENTRY_MAP_FN, symlinks))
11001088
+ String.format(

src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public boolean isBuildRunfileLinks() {
175175

176176
@Override
177177
public String getWorkspaceName() {
178-
return runfiles.getSuffix().getPathString();
178+
return runfiles.getPrefix();
179179
}
180180
}
181181

src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -926,7 +926,7 @@ private static Path ensureRunfilesBuilt(
926926
// On Windows, runfiles tree is disabled.
927927
// Workspace name directory doesn't exist, so don't add it.
928928
if (configuration.runfilesEnabled()) {
929-
workingDir = workingDir.getRelative(runfilesSupport.getRunfiles().getSuffix());
929+
workingDir = workingDir.getRelative(runfilesSupport.getRunfiles().getPrefix());
930930
}
931931

932932
// Always create runfiles directory and the workspace-named directory underneath, even if we

src/test/java/com/google/devtools/build/lib/analysis/util/FakeRunfilesTree.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,6 @@ public boolean isBuildRunfileLinks() {
8888

8989
@Override
9090
public String getWorkspaceName() {
91-
return runfiles.getSuffix().getPathString();
91+
return runfiles.getPrefix();
9292
}
9393
}

0 commit comments

Comments
 (0)