Skip to content

Commit 704775a

Browse files
Cleanup and changes based on reviews
1 parent 40bcb5d commit 704775a

File tree

14 files changed

+124
-108
lines changed

14 files changed

+124
-108
lines changed

substratevm/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This changelog summarizes major changes to GraalVM Native Image.
77
* (GR-59313) Deprecated class-level metadata extraction using `native-image-inspect` and removed option `DumpMethodsData`. Use class-level SBOMs instead by passing `--enable-sbom=class-level,export` to the `native-image` builder. The default value of option `IncludeMethodData` was changed to `false`.
88
* (GR-52400) The build process now uses 85% of system memory in containers and CI environments. Otherwise, it tries to only use available memory. If less than 8GB of memory are available, it falls back to 85% of system memory. The reason for the selected memory limit is now also shown in the build resources section of the build output.
99
* (GR-59864) Added JVM version check to the Native Image agent. The agent will abort execution if the JVM major version does not match the version it was built with, and warn if the full JVM version is different.
10-
* (GR-54697) Parallelize debug info generator and add support run-time debug info generation. `-H:+RuntimeDebugInfo` adds a run-time debug info generator into a native image. The run-time debug info generator notifies GDB via the [JIT Compilation Interface](https://sourceware.org/gdb/current/onlinedocs/gdb.html/JIT-Interface.html) about new object files for run-time compilations.
10+
* (GR-54697) Parallelize debug info generation and add support for run-time debug info generation. `-H:+RuntimeDebugInfo` adds a run-time debug info generator into a native image for use with GDB.
1111

1212
## GraalVM for JDK 24 (Internal Version 24.2.0)
1313
* (GR-59717) Added `DuringSetupAccess.registerObjectReachabilityHandler` to allow registering a callback that is executed when an object of a specified type is marked as reachable during heap scanning.

substratevm/debug/gdbpy/gdb-debughelpers.py

Lines changed: 17 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,6 @@ class SVMUtil:
9797

9898
hlreps = dict()
9999

100-
# AMD64 registers
101-
AMD64_RSP = 7
102-
AMD64_RIP = 16
103-
104-
# aarch64 registers
105-
AARCH64_RSP = 30
106-
AARCH64_RIP = 31
107-
108100
# static methods
109101
@staticmethod
110102
def get_deopt_stub_adr() -> int:
@@ -143,24 +135,6 @@ def prompt_hook(cls, current_prompt: str = None):
143135
cls.selfref_cycles.clear()
144136
SVMCommandPrint.cache.clear()
145137

146-
@classmethod
147-
def get_rsp(cls) -> int:
148-
arch = gdb.selected_frame().architecture().name()
149-
if "x86-64" in arch:
150-
return cls.AMD64_RSP
151-
elif "aarch64" in arch:
152-
return cls.AARCH64_RSP
153-
return 0
154-
155-
@classmethod
156-
def get_rip(cls) -> int:
157-
arch = gdb.selected_frame().architecture().name()
158-
if "x86-64" in arch:
159-
return cls.AMD64_RIP
160-
elif "aarch64" in arch:
161-
return cls.AARCH64_RIP
162-
return 0
163-
164138
@classmethod
165139
# checks if node this is reachable from node other (this node is parent of other node)
166140
def is_reachable(cls, this: hex, other: hex) -> bool:
@@ -1626,26 +1600,26 @@ def __call__(self, pending_frame: gdb.Frame):
16261600
if self.deopt_stub_adr == 0:
16271601
self.deopt_stub_adr = SVMUtil.get_deopt_stub_adr()
16281602

1629-
rsp = 0
1603+
sp = 0
16301604
try:
1631-
rsp = pending_frame.read_register('sp')
1632-
rip = pending_frame.read_register('pc')
1633-
if int(rip) == self.deopt_stub_adr:
1634-
deopt_frame_stack_slot = rsp.cast(self.svm_util.stack_type.pointer()).dereference()
1605+
sp = pending_frame.read_register('sp')
1606+
pc = pending_frame.read_register('pc')
1607+
if int(pc) == self.deopt_stub_adr:
1608+
deopt_frame_stack_slot = sp.cast(self.svm_util.stack_type.pointer()).dereference()
16351609
deopt_frame = deopt_frame_stack_slot.cast(self.svm_util.get_compressed_type(self.svm_util.object_type).pointer())
16361610
rtt = self.svm_util.get_rtt(deopt_frame)
16371611
deopt_frame = self.svm_util.cast_to(deopt_frame, rtt)
16381612
encoded_frame_size = self.svm_util.get_int_field(deopt_frame, 'sourceEncodedFrameSize')
16391613
source_frame_size = encoded_frame_size & ~self.svm_util.frame_size_status_mask
16401614
# Now find the register-values for the caller frame
1641-
unwind_info = pending_frame.create_unwind_info(gdb.unwinder.FrameId(rsp, rip))
1642-
caller_rsp = rsp + int(source_frame_size)
1643-
unwind_info.add_saved_register(SVMUtil.get_rsp(), gdb.Value(caller_rsp))
1644-
caller_rip = gdb.Value(caller_rsp - 8).cast(self.svm_util.stack_type.pointer()).dereference()
1645-
unwind_info.add_saved_register(SVMUtil.get_rip(), gdb.Value(caller_rip))
1615+
unwind_info = pending_frame.create_unwind_info(gdb.unwinder.FrameId(sp, pc))
1616+
caller_sp = sp + int(source_frame_size)
1617+
unwind_info.add_saved_register('sp', gdb.Value(caller_sp))
1618+
caller_pc = gdb.Value(caller_sp - 8).cast(self.svm_util.stack_type.pointer()).dereference()
1619+
unwind_info.add_saved_register('pc', gdb.Value(caller_pc))
16461620
return unwind_info
16471621
except Exception as ex:
1648-
trace(f'<SVMFrameUnwinder> - Failed to unwind frame at {hex(rsp)}')
1622+
trace(f'<SVMFrameUnwinder> - Failed to unwind frame at {hex(sp)}')
16491623
trace(ex)
16501624
# Fallback to default frame unwinding via debug_frame (dwarf)
16511625

@@ -1712,9 +1686,9 @@ def __init__(self, svm_util: SVMUtil, frame: gdb.Frame, deopt_stub_adr: int):
17121686
super().__init__(frame)
17131687

17141688
# fetch deoptimized frame from stack
1715-
rsp = frame.read_register('sp')
1689+
sp = frame.read_register('sp')
17161690
assert deopt_stub_adr and frame.pc() == deopt_stub_adr
1717-
deopt_frame_stack_slot = rsp.cast(svm_util.stack_type.pointer()).dereference()
1691+
deopt_frame_stack_slot = sp.cast(svm_util.stack_type.pointer()).dereference()
17181692
deopt_frame = deopt_frame_stack_slot.cast(svm_util.get_compressed_type(svm_util.object_type).pointer())
17191693
rtt = svm_util.get_rtt(deopt_frame)
17201694
deopt_frame = svm_util.cast_to(deopt_frame, rtt)
@@ -1754,11 +1728,13 @@ def filename(self):
17541728
return None
17551729

17561730
source_class = self.__svm_util.get_obj_field(self.__frame_info, 'sourceClass')
1731+
companion = self.__svm_util.get_obj_field(source_class, 'companion')
1732+
source_file_name = self.__svm_util.get_obj_field(companion, 'sourceFileName')
17571733

1758-
if self.__svm_util.is_null(source_class):
1734+
if self.__svm_util.is_null(source_file_name):
17591735
source_file_name = ''
17601736
else:
1761-
source_file_name = str(self.__svm_util.get_obj_field(source_class, 'sourceFileName'))[1:-1]
1737+
source_file_name = str(source_file_name)[1:-1]
17621738

17631739
return source_file_name
17641740

substratevm/mx.substratevm/mx_substratevm.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,7 @@ def run_debug_test(image_name: str, testfile: str, source_path: str, with_isolat
11421142
'-iex', f"set auto-load safe-path {join(build_dir, 'gdb-debughelpers.py')}",
11431143
'-x', testfile, join(build_dir, image_name)
11441144
]
1145-
mx.log(' '.join([(f"'{c}'" if ' ' in c else c) for c in gdb_command]))
1145+
log_gdb_command(gdb_command)
11461146
# unittest may result in different exit code, nonZeroIsFatal ensures that we can go on with other test
11471147
return mx.run(gdb_command, cwd=build_dir, nonZeroIsFatal=False)
11481148
return 0
@@ -1169,7 +1169,11 @@ def run_debug_test(image_name: str, testfile: str, source_path: str, with_isolat
11691169
mx.abort(status)
11701170

11711171

1172-
def _runtimedebuginfotest(native_image, output_path, with_isolates_only, args=None):
1172+
def log_gdb_command(gdb_command):
1173+
mx.log(' '.join([(f"'{c}'" if ' ' in c else c) for c in gdb_command]))
1174+
1175+
1176+
def _runtimedebuginfotest(native_image, output_path, args=None):
11731177
"""Build and run the runtimedebuginfotest"""
11741178

11751179
args = [] if args is None else args
@@ -1221,7 +1225,7 @@ def _runtimedebuginfotest(native_image, output_path, with_isolates_only, args=No
12211225
'-iex', f"set auto-load safe-path {join(output_path, 'gdb-debughelpers.py')}",
12221226
'-x', test_runtime_compilation_py, runtime_compile_binary
12231227
]
1224-
mx.log(' '.join([(f"'{c}'" if ' ' in c else c) for c in gdb_command]))
1228+
log_gdb_command(gdb_command)
12251229
# unittest may result in different exit code, nonZeroIsFatal ensures that we can go on with other test
12261230
status = mx.run(gdb_command, cwd=output_path, nonZeroIsFatal=False)
12271231

@@ -1243,7 +1247,7 @@ def _runtimedebuginfotest(native_image, output_path, with_isolates_only, args=No
12431247
'-iex', f"set auto-load safe-path {join(output_path, 'gdb-debughelpers.py')}",
12441248
'-x', test_runtime_deopt_py, '--args', js_launcher, testdeopt_js
12451249
]
1246-
mx.log(' '.join([(f"'{c}'" if ' ' in c else c) for c in gdb_command]))
1250+
log_gdb_command(gdb_command)
12471251
# unittest may result in different exit code, nonZeroIsFatal ensures that we can go on with other test
12481252
status |= mx.run(gdb_command, cwd=output_path, nonZeroIsFatal=False)
12491253

@@ -1859,14 +1863,12 @@ def runtimedebuginfotest(args, config=None):
18591863
all_args = ['--output-path', '--with-isolates-only']
18601864
masked_args = [_mask(arg, all_args) for arg in args]
18611865
parser.add_argument(all_args[0], metavar='<output-path>', nargs=1, help='Path of the generated image', default=[join(svmbuild_dir(), "runtimedebuginfotest")])
1862-
parser.add_argument(all_args[1], action='store_true', help='Only build and test the native image with isolates')
18631866
parser.add_argument('image_args', nargs='*', default=[])
18641867
parsed = parser.parse_args(masked_args)
18651868
output_path = unmask(parsed.output_path)[0]
1866-
with_isolates_only = parsed.with_isolates_only
18671869
native_image_context_run(
18681870
lambda native_image, a:
1869-
_runtimedebuginfotest(native_image, output_path, with_isolates_only, a), unmask(parsed.image_args),
1871+
_runtimedebuginfotest(native_image, output_path, a), unmask(parsed.image_args),
18701872
config=config
18711873
)
18721874

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/ObjectFile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ private static ObjectFile getNativeObjectFile(int pageSize, boolean runtimeDebug
223223
case ELF -> new ELFObjectFile(pageSize, runtimeDebugInfoGeneration);
224224
case MACH_O -> new MachOObjectFile(pageSize);
225225
case PECOFF -> new PECoffObjectFile(pageSize);
226-
default -> throw new AssertionError("Unreachable");
226+
case LLVM -> throw new AssertionError("Unsupported NativeObjectFile for format " + ObjectFile.getNativeFormat());
227227
};
228228
}
229229

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import org.graalvm.nativeimage.ImageSingletons;
4646
import org.graalvm.nativeimage.Platform;
4747
import org.graalvm.nativeimage.Platforms;
48-
import org.graalvm.nativeimage.ProcessProperties;
4948

5049
import com.oracle.svm.core.c.libc.LibCBase;
5150
import com.oracle.svm.core.c.libc.MuslLibC;
@@ -466,22 +465,6 @@ public static void setImageLayerCreateEnabledHandler(OptionEnabledHandler<Boolea
466465
@Option(help = "Track NodeSourcePositions during runtime-compilation")//
467466
public static final HostedOptionKey<Boolean> IncludeNodeSourcePositions = new HostedOptionKey<>(false);
468467

469-
@Option(help = "Directory where Java source-files will be placed for the debugger")//
470-
public static final RuntimeOptionKey<String> RuntimeSourceDestDir = new RuntimeOptionKey<>(null, RelevantForCompilationIsolates);
471-
472-
public static Path getRuntimeSourceDestDir() {
473-
String sourceDestDir = RuntimeSourceDestDir.getValue();
474-
if (sourceDestDir != null) {
475-
return Paths.get(sourceDestDir);
476-
}
477-
Path result = Paths.get("sources");
478-
Path exeDir = Paths.get(ProcessProperties.getExecutableName()).getParent();
479-
if (exeDir != null) {
480-
result = exeDir.resolve(result);
481-
}
482-
return result;
483-
}
484-
485468
@Option(help = "Provide debuginfo for runtime-compiled code.")//
486469
public static final HostedOptionKey<Boolean> RuntimeDebugInfo = new HostedOptionKey<>(false);
487470

@@ -1013,6 +996,17 @@ public static boolean useDebugInfoGeneration() {
1013996
return useLIRBackend() && GenerateDebugInfo.getValue() > 0;
1014997
}
1015998

999+
// TODO: change default to 0
1000+
@Option(help = "Number of threads used to generate debug info.", deprecated = true) //
1001+
public static final HostedOptionKey<Integer> DebugInfoGenerationThreadCount = new HostedOptionKey<>(256, SubstrateOptions::validateDebugInfoGenerationThreadCount);
1002+
1003+
private static void validateDebugInfoGenerationThreadCount(HostedOptionKey<Integer> optionKey) {
1004+
int value = optionKey.getValue();
1005+
if (value <= 0) {
1006+
throw UserError.invalidOptionValue(optionKey, value, "The value must be bigger than 0");
1007+
}
1008+
}
1009+
10161010
@Option(help = "Directory under which to create source file cache for Application or GraalVM classes")//
10171011
static final HostedOptionKey<String> DebugInfoSourceCacheRoot = new HostedOptionKey<>("sources");
10181012

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/InstalledCodeObserverSupport.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,10 @@
4545

4646
@AutomaticallyRegisteredImageSingleton
4747
public final class InstalledCodeObserverSupport {
48-
private static final InstalledCodeObserverHandleAction ACTION_ATTACH = (h, a, i) -> getAccessor(h).attachToCurrentIsolate(h);
49-
private static final InstalledCodeObserverHandleAction ACTION_DETACH = (h, a, i) -> getAccessor(h).detachFromCurrentIsolate(h);
50-
private static final InstalledCodeObserverHandleAction ACTION_RELEASE = (h, a, i) -> {
51-
getAccessor(h).release(h);
52-
NonmovableArrays.setWord(a, i, Word.nullPointer());
53-
};
54-
private static final InstalledCodeObserverHandleAction ACTION_ACTIVATE = (h, a, i) -> getAccessor(h).activate(h);
48+
private static final InstalledCodeObserverHandleAction ACTION_ATTACH = h -> getAccessor(h).attachToCurrentIsolate(h);
49+
private static final InstalledCodeObserverHandleAction ACTION_DETACH = h -> getAccessor(h).detachFromCurrentIsolate(h);
50+
private static final InstalledCodeObserverHandleAction ACTION_RELEASE = h -> getAccessor(h).release(h);
51+
private static final InstalledCodeObserverHandleAction ACTION_ACTIVATE = h -> getAccessor(h).activate(h);
5552

5653
private final List<InstalledCodeObserver.Factory> observerFactories = new ArrayList<>();
5754

@@ -106,10 +103,11 @@ public static void attachToCurrentIsolate(NonmovableArray<InstalledCodeObserverH
106103

107104
public static void removeObservers(NonmovableArray<InstalledCodeObserverHandle> observerHandles) {
108105
forEach(observerHandles, ACTION_RELEASE);
106+
clearObserverHandles(observerHandles);
109107
}
110108

111109
private interface InstalledCodeObserverHandleAction {
112-
void invoke(InstalledCodeObserverHandle handle, NonmovableArray<InstalledCodeObserverHandle> observerHandles, int index);
110+
void invoke(InstalledCodeObserverHandle handle);
113111
}
114112

115113
private static void forEach(NonmovableArray<InstalledCodeObserverHandle> array, InstalledCodeObserverHandleAction action) {
@@ -118,7 +116,19 @@ private static void forEach(NonmovableArray<InstalledCodeObserverHandle> array,
118116
for (int i = 0; i < length; i++) {
119117
InstalledCodeObserverHandle handle = NonmovableArrays.getWord(array, i);
120118
if (handle.isNonNull()) {
121-
action.invoke(handle, array, i);
119+
action.invoke(handle);
120+
}
121+
}
122+
}
123+
}
124+
125+
private static void clearObserverHandles(NonmovableArray<InstalledCodeObserverHandle> array) {
126+
if (array.isNonNull()) {
127+
int length = NonmovableArrays.lengthOf(array);
128+
for (int i = 0; i < length; i++) {
129+
InstalledCodeObserverHandle handle = NonmovableArrays.getWord(array, i);
130+
if (handle.isNonNull()) {
131+
NonmovableArrays.setWord(array, i, Word.nullPointer());
122132
}
123133
}
124134
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/debug/GDBJITInterface.java renamed to substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/debug/GdbJitInterface.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@
5050

5151
import jdk.graal.compiler.word.Word;
5252

53-
@CContext(GDBJITInterface.GDBJITInterfaceDirectives.class)
54-
public class GDBJITInterface {
53+
@CContext(GdbJitInterface.GdbJitInterfaceDirectives.class)
54+
public class GdbJitInterface {
5555

56-
public static class GDBJITInterfaceDirectives implements CContext.Directives {
56+
public static class GdbJitInterfaceDirectives implements CContext.Directives {
5757
@Override
5858
public boolean isInConfiguration() {
5959
return SubstrateOptions.RuntimeDebugInfo.getValue();

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/debug/SharedDebugInfoProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ protected long getTypeSignature(String typeName) {
788788
protected String getMethodName(SharedMethod method) {
789789
String name = method.getName();
790790
// replace <init> (method name of a constructor) with the class name
791-
if (name.equals("<init>")) {
791+
if (method.isConstructor()) {
792792
name = method.format("%h");
793793
if (name.indexOf('$') >= 0) {
794794
name = name.substring(name.lastIndexOf('$') + 1);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/debug/SubstrateDebugInfoFeature.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,6 @@ public void registerCodeObserver(RuntimeConfiguration runtimeConfig) {
5555
// This is called at image build-time -> the factory then creates a RuntimeDebugInfoProvider
5656
// at runtime
5757
ImageSingletons.lookup(InstalledCodeObserverSupport.class).addObserverFactory(new SubstrateDebugInfoInstaller.Factory(runtimeConfig.getProviders().getMetaAccess(), runtimeConfig));
58-
ImageSingletons.add(SubstrateDebugInfoInstaller.GDBJITAccessor.class, new SubstrateDebugInfoInstaller.GDBJITAccessor());
58+
ImageSingletons.add(SubstrateDebugInfoInstaller.GdbJitAccessor.class, new SubstrateDebugInfoInstaller.GdbJitAccessor());
5959
}
6060
}

0 commit comments

Comments
 (0)