Skip to content

Commit 8776dda

Browse files
committed
Update patch to new built-time approach
1 parent 5e15fc6 commit 8776dda

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1389
-799
lines changed

make/CompileToolsJdk.gmk

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ $(eval $(call SetupJavaCompilation, BUILD_TOOLS_JDK, \
5959
--add-exports java.base/sun.text=ALL-UNNAMED \
6060
--add-exports java.base/sun.security.util=ALL-UNNAMED \
6161
--add-exports jdk.internal.opt/jdk.internal.opt=jdk.compiler.interim \
62-
--add-exports jdk.internal.opt/jdk.internal.opt=jdk.javadoc.interim, \
62+
--add-exports jdk.internal.opt/jdk.internal.opt=jdk.javadoc.interim \
63+
--add-exports java.base/jdk.internal.module=ALL-UNNAMED \
64+
--add-exports java.base/jdk.internal.jimage=ALL-UNNAMED \
65+
, \
6366
))
6467

6568
TARGETS += $(BUILD_TOOLS_JDK)

make/Images.gmk

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ include MakeBase.gmk
3030
include Execute.gmk
3131
include Modules.gmk
3232
include Utils.gmk
33+
include ToolsJdk.gmk
3334

3435
JDK_TARGETS :=
3536
JRE_TARGETS :=
@@ -85,10 +86,22 @@ JLINK_TOOL := $(JLINK) -J-Djlink.debug=true \
8586

8687
JLINK_JRE_EXTRA_OPTS := --no-man-pages --no-header-files --strip-debug
8788

89+
ifeq ($(JLINK_PRODUCE_RUNTIME_LINK_JDK), true)
90+
JDK_LINK_OUTPUT_DIR := $(RL_INTERMEDIATE_IMAGE_DIR)
91+
else
92+
JDK_LINK_OUTPUT_DIR := $(JDK_IMAGE_DIR)
93+
endif
94+
8895
ifeq ($(JLINK_KEEP_PACKAGED_MODULES), true)
89-
JLINK_JDK_EXTRA_OPTS := --keep-packaged-modules $(JDK_IMAGE_DIR)/jmods
96+
ifeq ($(JLINK_PRODUCE_RUNTIME_LINK_JDK), true)
97+
JLINK_JDK_EXTRA_OPTS := --keep-packaged-modules $(RL_INTERMEDIATE_IMAGE_DIR)/jmods
98+
JLINK_RUNTIME_CREATE_EXTRA := --keep-packaged-modules $(JDK_IMAGE_DIR)/jmods
99+
else
100+
JLINK_JDK_EXTRA_OPTS := --keep-packaged-modules $(JDK_IMAGE_DIR)/jmods
101+
endif
90102
endif
91103

104+
92105
JLINK_DISABLE_WARNINGS := | ( $(GREP) -v -e "WARNING: Using incubator module" || test "$$?" = "1" )
93106

94107
JDK_IMAGE_SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jdk
@@ -98,16 +111,48 @@ $(eval $(call SetupExecute, jlink_jdk, \
98111
WARN := Creating jdk image, \
99112
DEPS := $(JDK_JMODS) $(BASE_RELEASE_FILE) \
100113
$(call DependOnVariable, JDK_MODULES_LIST, $(JDK_IMAGE_SUPPORT_DIR)/_jlink_jdk.vardeps), \
101-
OUTPUT_DIR := $(JDK_IMAGE_DIR), \
114+
OUTPUT_DIR := $(JDK_LINK_OUTPUT_DIR), \
102115
SUPPORT_DIR := $(JDK_IMAGE_SUPPORT_DIR), \
103-
PRE_COMMAND := $(RM) -r $(JDK_IMAGE_DIR), \
116+
PRE_COMMAND := $(RM) -r $(JDK_LINK_OUTPUT_DIR), \
104117
COMMAND := $(JLINK_TOOL) --add-modules $(JDK_MODULES_LIST) \
105-
$(JLINK_JDK_EXTRA_OPTS) --output $(JDK_IMAGE_DIR) \
118+
$(JLINK_JDK_EXTRA_OPTS) --output $(JDK_LINK_OUTPUT_DIR) \
106119
$(JLINK_DISABLE_WARNINGS), \
107120
))
108121

109122
JLINK_JDK_TARGETS := $(jlink_jdk)
110123

124+
ifeq ($(JLINK_PRODUCE_RUNTIME_LINK_JDK), true)
125+
126+
JDK_RUN_TIME_IMAGE_SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jlink-run-time
127+
JDK_JMODS_DIFF := $(JDK_RUN_TIME_IMAGE_SUPPORT_DIR)/jimage_packaged_modules_diff.data
128+
JLINK_RUNTIME_CREATE_EXTRA += --create-linkable-runtime=$(JDK_JMODS_DIFF)
129+
130+
$(eval $(call SetupExecute, generate_jimage_diff, \
131+
WARN := Generating the jimage to packaged modules diff, \
132+
DEPS := $(jlink_jdk), \
133+
OUTPUT_FILE := $(JDK_JMODS_DIFF), \
134+
SUPPORT_DIR := $(JDK_RUN_TIME_IMAGE_SUPPORT_DIR), \
135+
COMMAND := $(TOOL_JIMAGE_DIFF_TO_JMODS) $(IMAGES_OUTPUTDIR)/jmods \
136+
$(JDK_LINK_OUTPUT_DIR)/lib/modules $(JDK_JMODS_DIFF), \
137+
))
138+
139+
$(eval $(call SetupExecute, jlink_runtime_jdk, \
140+
WARN := Creating jdk image for runtime linking, \
141+
DEPS := $(generate_jimage_diff), \
142+
OUTPUT_DIR := $(JDK_IMAGE_DIR), \
143+
SUPPORT_DIR := $(JDK_RUN_TIME_IMAGE_SUPPORT_DIR), \
144+
PRE_COMMAND := $(RM) -r $(JDK_IMAGE_DIR), \
145+
COMMAND := $(JLINK_TOOL) --add-modules $(JDK_MODULES_LIST) \
146+
$(JLINK_RUNTIME_CREATE_EXTRA) \
147+
--output $(JDK_IMAGE_DIR) \
148+
$(JLINK_DISABLE_WARNINGS), \
149+
))
150+
151+
JLINK_JDK_TARGETS += $(generate_jimage_diff)
152+
JLINK_JDK_TARGETS += $(jlink_runtime_jdk)
153+
154+
endif
155+
111156
$(eval $(call SetupExecute, jlink_jre, \
112157
WARN := Creating legacy jre image, \
113158
DEPS := $(JRE_JMODS) $(BASE_RELEASE_FILE) \

make/ToolsJdk.gmk

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ TOOL_GENERATEEXTRAPROPERTIES = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_too
8282
TOOL_MAKEZIPREPRODUCIBLE = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
8383
build.tools.makezipreproducible.MakeZipReproducible
8484

85+
TOOL_JIMAGE_DIFF_TO_JMODS = $(BUILD_JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
86+
--add-modules=jdk.jlink --add-exports=java.base/jdk.internal.module=ALL-UNNAMED \
87+
--add-exports=java.base/jdk.internal.jimage=ALL-UNNAMED \
88+
build.tools.runtimelink.JimageDiffGenerator
89+
8590
# TODO: There are references to the jdwpgen.jar in jdk/make/netbeans/jdwpgen/build.xml
8691
# and nbproject/project.properties in the same dir. Needs to be looked at.
8792
TOOL_JDWPGEN = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes build.tools.jdwpgen.Main

make/autoconf/configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ BASIC_SETUP_DEFAULT_LOG
137137
# We need build & target for this.
138138
JDKOPT_SETUP_JMOD_OPTIONS
139139
JDKOPT_SETUP_JLINK_OPTIONS
140+
JDKOPT_SETUP_JLINK_RUN_TIME_LINK_IMAGE
140141
JDKVER_SETUP_JDK_VERSION_NUMBERS
141142

142143
###############################################################################

make/autoconf/jdk-options.m4

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,22 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JLINK_OPTIONS],
591591
AC_SUBST(JLINK_KEEP_PACKAGED_MODULES)
592592
])
593593

594+
################################################################################
595+
#
596+
# jlink related.
597+
#
598+
# Determines whether or not a run-time linkable JDK image is being
599+
# produced from the product image.
600+
#
601+
AC_DEFUN_ONCE([JDKOPT_SETUP_JLINK_RUN_TIME_LINK_IMAGE],
602+
[
603+
UTIL_ARG_ENABLE(NAME: runtime-link-image, DEFAULT: false,
604+
RESULT: JLINK_PRODUCE_RUNTIME_LINK_JDK,
605+
DESC: [enable producing an image suitable for runtime linking],
606+
CHECKING_MSG: [whether or not an image suitable for runtime linking should be produced])
607+
AC_SUBST(JLINK_PRODUCE_RUNTIME_LINK_JDK)
608+
])
609+
594610
################################################################################
595611
#
596612
# Enable or disable generation of the classlist at build time

make/autoconf/spec.gmk.template

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,7 @@ NEW_JAVADOC = $(INTERIM_LANGTOOLS_ARGS) $(JAVADOC_MAIN_CLASS)
729729

730730
JMOD_COMPRESS := @JMOD_COMPRESS@
731731
JLINK_KEEP_PACKAGED_MODULES := @JLINK_KEEP_PACKAGED_MODULES@
732+
JLINK_PRODUCE_RUNTIME_LINK_JDK := @JLINK_PRODUCE_RUNTIME_LINK_JDK@
732733

733734
RCFLAGS := @RCFLAGS@
734735

@@ -897,6 +898,10 @@ STATIC_LIBS_GRAAL_IMAGE_DIR := $(IMAGES_OUTPUTDIR)/$(STATIC_LIBS_GRAAL_IMAGE_SUB
897898
GRAAL_BUILDER_IMAGE_SUBDIR := graal-builder-jdk
898899
GRAAL_BUILDER_IMAGE_DIR := $(IMAGES_OUTPUTDIR)/$(GRAAL_BUILDER_IMAGE_SUBDIR)
899900

901+
# Runtime jdk link image
902+
RL_INTERMEDIATE_IMAGE_SUBDIR := runtime-link-initial-jdk
903+
RL_INTERMEDIATE_IMAGE_DIR := $(IMAGES_OUTPUTDIR)/$(RL_INTERMEDIATE_IMAGE_SUBDIR)
904+
900905
# Macosx bundles directory definitions
901906
JDK_MACOSX_BUNDLE_SUBDIR := jdk-bundle
902907
JRE_MACOSX_BUNDLE_SUBDIR := jre-bundle
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
/*
2-
* Copyright (c) 2023, Red Hat, Inc.
2+
* Copyright (c) 2024, Red Hat, Inc.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
66
* under the terms of the GNU General Public License version 2 only, as
7-
* published by the Free Software Foundation. Oracle designates this
8-
* particular file as subject to the "Classpath" exception as provided
9-
* by Oracle in the LICENSE file that accompanied this code.
7+
* published by the Free Software Foundation.
108
*
119
* This code is distributed in the hope that it will be useful, but WITHOUT
1210
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@@ -22,18 +20,37 @@
2220
* or visit www.oracle.com if you need additional information or have any
2321
* questions.
2422
*/
23+
package build.tools.runtimelink;
2524

26-
package jdk.tools.jlink.internal;
27-
25+
import java.io.IOException;
26+
import java.nio.file.Path;
27+
import java.util.Arrays;
2828
import java.util.List;
29+
import java.util.stream.Collectors;
2930

30-
/**
31-
*
32-
* Plugins wishing to observe the command list that was used to
33-
* trigger the link must implement this interface.
34-
*
35-
*/
36-
public interface JlinkCLIArgsListener {
31+
import jdk.internal.jimage.BasicImageReader;
32+
33+
public class ImageReader extends BasicImageReader implements JimageDiffGenerator.ImageResource {
34+
35+
public ImageReader(Path path) throws IOException {
36+
super(path);
37+
}
38+
39+
public static boolean isNotTreeInfoResource(String path) {
40+
return !(path.startsWith("/packages") || path.startsWith("/modules"));
41+
}
42+
43+
@Override
44+
public List<String> getEntries() {
45+
return Arrays.asList(getEntryNames()).stream()
46+
.filter(ImageReader::isNotTreeInfoResource)
47+
.sorted()
48+
.collect(Collectors.toList());
49+
}
50+
51+
@Override
52+
public byte[] getResourceBytes(String name) {
53+
return getResource(name);
54+
}
3755

38-
public void process(List<String> cliArgs);
3956
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright (c) 2024, Red Hat, Inc.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package build.tools.runtimelink;
24+
25+
import java.io.File;
26+
import java.io.FileOutputStream;
27+
import java.nio.file.Path;
28+
import java.util.ArrayList;
29+
import java.util.Arrays;
30+
import java.util.HashSet;
31+
import java.util.List;
32+
import java.util.Set;
33+
import java.util.stream.Collectors;
34+
35+
public class JimageDiffGenerator {
36+
37+
private static final boolean DEBUG = false;
38+
39+
@SuppressWarnings("try")
40+
public interface ImageResource extends AutoCloseable {
41+
public List<String> getEntries();
42+
public byte[] getResourceBytes(String name);
43+
}
44+
45+
public List<ResourceDiff> generateDiff(ImageResource baseImg, ImageResource optImage) throws Exception {
46+
List<String> baseResources;
47+
Set<String> optResSet = new HashSet<>();
48+
List<ResourceDiff> diffs = new ArrayList<>();
49+
try (baseImg;
50+
optImage) {
51+
optResSet.addAll(optImage.getEntries());
52+
baseResources = baseImg.getEntries();
53+
for (String item: baseResources) {
54+
byte[] baseBytes = baseImg.getResourceBytes(item);
55+
// First check that every item in the base image exist in
56+
// the optimized image as well. If it does not, it's a removed
57+
// item in the optimized image.
58+
if (!optResSet.remove(item)) {
59+
// keep track of original bytes for removed item in the
60+
// optimized image, since we need to restore them for the
61+
// runtime image link
62+
ResourceDiff.Builder builder = new ResourceDiff.Builder();
63+
ResourceDiff diff = builder.setKind(ResourceDiff.Kind.REMOVED)
64+
.setName(item)
65+
.setResourceBytes(baseBytes)
66+
.build();
67+
diffs.add(diff);
68+
continue;
69+
}
70+
// Verify resource bytes are equal if present in both images
71+
boolean contentEquals = Arrays.equals(baseBytes, optImage.getResourceBytes(item));
72+
if (!contentEquals) {
73+
// keep track of original bytes (non-optimized)
74+
ResourceDiff.Builder builder = new ResourceDiff.Builder();
75+
ResourceDiff diff = builder.setKind(ResourceDiff.Kind.MODIFIED)
76+
.setName(item)
77+
.setResourceBytes(baseBytes)
78+
.build();
79+
diffs.add(diff);
80+
}
81+
}
82+
}
83+
// What's now left in optResSet are the resources only present in the
84+
// optimized image (generated by some plugins; not present in jmods)
85+
for (String e: optResSet) {
86+
ResourceDiff.Builder builder = new ResourceDiff.Builder();
87+
ResourceDiff diff = builder.setKind(ResourceDiff.Kind.ADDED)
88+
.setName(e)
89+
.build();
90+
diffs.add(diff);
91+
}
92+
return diffs;
93+
}
94+
95+
public static void main(String[] args) throws Exception {
96+
if (args.length != 3) {
97+
System.out.println("Usage: java -cp jrt-fs.jar:. JimageDiffGenerator <packaged-modules> <image-to-compare> <output-file>");
98+
System.exit(1);
99+
}
100+
ImageResource base = new JmodsReader(Path.of(args[0]));
101+
ImageResource opt = new ImageReader(Path.of(args[1]));
102+
JimageDiffGenerator diffGen = new JimageDiffGenerator();
103+
List<ResourceDiff> diffs = diffGen.generateDiff(base, opt);
104+
105+
if (DEBUG) {
106+
printDiffs(diffs);
107+
}
108+
FileOutputStream fout = new FileOutputStream(new File(args[2]));
109+
ResourceDiff.write(diffs, fout);
110+
}
111+
112+
private static void printDiffs(List<ResourceDiff> diffs) {
113+
for (ResourceDiff diff: diffs.stream().sorted().collect(Collectors.toList())) {
114+
switch (diff.getKind()) {
115+
case ADDED:
116+
System.out.println("Only added in opt: " + diff.getName());
117+
break;
118+
case MODIFIED:
119+
System.out.println("Modified in opt: " + diff.getName());
120+
break;
121+
case REMOVED:
122+
System.out.println("Removed in opt: " + diff.getName());
123+
break;
124+
default:
125+
break;
126+
}
127+
}
128+
}
129+
130+
}

0 commit comments

Comments
 (0)