Skip to content

Commit b05b63f

Browse files
Cleanup and changes based on reviews
1 parent d91e05c commit b05b63f

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
@@ -9,7 +9,7 @@ This changelog summarizes major changes to GraalVM Native Image.
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.
1010
* (GR-59135) Verify if hosted options passed to `native-image` exist prior to starting the builder. Provide suggestions how to fix unknown options early on.
1111
* (GR-61492) The experimental JDWP option is now present in standard GraalVM builds.
12-
* (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.
12+
* (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.
1313

1414
## GraalVM for JDK 24 (Internal Version 24.2.0)
1515
* (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
@@ -1146,7 +1146,7 @@ def run_debug_test(image_name: str, testfile: str, source_path: str, with_isolat
11461146
'-iex', f"set auto-load safe-path {join(build_dir, 'gdb-debughelpers.py')}",
11471147
'-x', testfile, join(build_dir, image_name)
11481148
]
1149-
mx.log(' '.join([(f"'{c}'" if ' ' in c else c) for c in gdb_command]))
1149+
log_gdb_command(gdb_command)
11501150
# unittest may result in different exit code, nonZeroIsFatal ensures that we can go on with other test
11511151
return mx.run(gdb_command, cwd=build_dir, nonZeroIsFatal=False)
11521152
return 0
@@ -1173,7 +1173,11 @@ def run_debug_test(image_name: str, testfile: str, source_path: str, with_isolat
11731173
mx.abort(status)
11741174

11751175

1176-
def _runtimedebuginfotest(native_image, output_path, with_isolates_only, args=None):
1176+
def log_gdb_command(gdb_command):
1177+
mx.log(' '.join([(f"'{c}'" if ' ' in c else c) for c in gdb_command]))
1178+
1179+
1180+
def _runtimedebuginfotest(native_image, output_path, args=None):
11771181
"""Build and run the runtimedebuginfotest"""
11781182

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

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

@@ -1855,14 +1859,12 @@ def runtimedebuginfotest(args, config=None):
18551859
all_args = ['--output-path', '--with-isolates-only']
18561860
masked_args = [_mask(arg, all_args) for arg in args]
18571861
parser.add_argument(all_args[0], metavar='<output-path>', nargs=1, help='Path of the generated image', default=[join(svmbuild_dir(), "runtimedebuginfotest")])
1858-
parser.add_argument(all_args[1], action='store_true', help='Only build and test the native image with isolates')
18591862
parser.add_argument('image_args', nargs='*', default=[])
18601863
parsed = parser.parse_args(masked_args)
18611864
output_path = unmask(parsed.output_path)[0]
1862-
with_isolates_only = parsed.with_isolates_only
18631865
native_image_context_run(
18641866
lambda native_image, a:
1865-
_runtimedebuginfotest(native_image, output_path, with_isolates_only, a), unmask(parsed.image_args),
1867+
_runtimedebuginfotest(native_image, output_path, a), unmask(parsed.image_args),
18661868
config=config
18671869
)
18681870

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;
@@ -476,22 +475,6 @@ public static void setImageLayerCreateEnabledHandler(OptionEnabledHandler<Boolea
476475
@Option(help = "Track NodeSourcePositions during runtime-compilation")//
477476
public static final HostedOptionKey<Boolean> IncludeNodeSourcePositions = new HostedOptionKey<>(false);
478477

479-
@Option(help = "Directory where Java source-files will be placed for the debugger")//
480-
public static final RuntimeOptionKey<String> RuntimeSourceDestDir = new RuntimeOptionKey<>(null, RelevantForCompilationIsolates);
481-
482-
public static Path getRuntimeSourceDestDir() {
483-
String sourceDestDir = RuntimeSourceDestDir.getValue();
484-
if (sourceDestDir != null) {
485-
return Paths.get(sourceDestDir);
486-
}
487-
Path result = Paths.get("sources");
488-
Path exeDir = Paths.get(ProcessProperties.getExecutableName()).getParent();
489-
if (exeDir != null) {
490-
result = exeDir.resolve(result);
491-
}
492-
return result;
493-
}
494-
495478
@Option(help = "Provide debuginfo for runtime-compiled code.")//
496479
public static final HostedOptionKey<Boolean> RuntimeDebugInfo = new HostedOptionKey<>(false);
497480

@@ -1023,6 +1006,17 @@ public static boolean useDebugInfoGeneration() {
10231006
return useLIRBackend() && GenerateDebugInfo.getValue() > 0;
10241007
}
10251008

1009+
// TODO: change default to 0
1010+
@Option(help = "Number of threads used to generate debug info.", deprecated = true) //
1011+
public static final HostedOptionKey<Integer> DebugInfoGenerationThreadCount = new HostedOptionKey<>(256, SubstrateOptions::validateDebugInfoGenerationThreadCount);
1012+
1013+
private static void validateDebugInfoGenerationThreadCount(HostedOptionKey<Integer> optionKey) {
1014+
int value = optionKey.getValue();
1015+
if (value <= 0) {
1016+
throw UserError.invalidOptionValue(optionKey, value, "The value must be bigger than 0");
1017+
}
1018+
}
1019+
10261020
@Option(help = "Directory under which to create source file cache for Application or GraalVM classes")//
10271021
static final HostedOptionKey<String> DebugInfoSourceCacheRoot = new HostedOptionKey<>("sources");
10281022

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)