Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 17 additions & 11 deletions interpreter/hotspot/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,18 @@ type hotspotVMData struct {
ConstMethod uint `name:"_constMethod"`
} `name:"Method,methodOopDesc"`
Nmethod struct { // .Sizeof >256
Sizeof uint
CompileID uint `name:"_compile_id"`
MetadataOffset uint `name:"_metadata_offset,_oops_offset"`
ScopesPcsOffset uint `name:"_scopes_pcs_offset"`
DependenciesOffset uint `name:"_dependencies_offset"` // JDK -22 only
ImmutableData uint `name:"_immutable_data"` // JDK 23+ only
ImmutableDataSize uint `name:"_immutable_data_size"` // JDK 23+ only
OrigPcOffset uint `name:"_orig_pc_offset"`
DeoptimizeOffset uint `name:"_deoptimize_offset,_deopt_handler_offset,_deopt_handler_begin"`
Method uint `name:"_method"`
ScopesDataOffset uint `name:"_scopes_data_offset,_scopes_data_begin"`
Sizeof uint
CompileID uint `name:"_compile_id"`
MetadataOffset uint `name:"_metadata_offset,_oops_offset"`
ScopesPcsOffset uint `name:"_scopes_pcs_offset"`
DependenciesOffset uint `name:"_dependencies_offset"` // JDK -22 only
ImmutableData uint `name:"_immutable_data"` // JDK 23+ only
ImmutableDataSize uint `name:"_immutable_data_size"` // JDK 23+ only
ImmutableDataRefCountOff uint `name:"_immutable_data_ref_count_offset"` // JDK 26+ only
OrigPcOffset uint `name:"_orig_pc_offset"`
DeoptimizeOffset uint `name:"_deoptimize_offset,_deopt_handler_offset,_deopt_handler_begin,_deopt_handler_entry_offset"`
Method uint `name:"_method"`
ScopesDataOffset uint `name:"_scopes_data_offset,_scopes_data_begin"`
} `name:"nmethod,CompiledMethod"`
OopDesc struct {
Sizeof uint
Expand Down Expand Up @@ -601,6 +602,11 @@ func (d *hotspotData) newVMData(rm remotememory.RemoteMemory, bias libpf.Address
vms.CodeBlob.RelocationSize = 0
}

// JDK26+: immutable data has a ref count trailer; not present prior to JDK26
if vms.Nmethod.ImmutableDataRefCountOff == ^uint(0) {
vms.Nmethod.ImmutableDataRefCountOff = 0
}

// Check that all symbols got loaded from JVM introspection data
err := forEachItem("", reflect.ValueOf(&vmd.vmStructs).Elem(),
func(item reflect.Value, name string) error {
Expand Down
3 changes: 3 additions & 0 deletions interpreter/hotspot/hotspot.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ package hotspot // import "go.opentelemetry.io/ebpf-profiler/interpreter/hotspot
// JDK24 - Tested ok
// - nmethod metadata moved to codeblob mutable data area
// JDK25 - Tested ok
// JDK26 - Tested ok
// - nmethod._deopt_handler_offset renamed to _deopt_handler_entry_offset
// - immutable_data now has ref count trailer (_immutable_data_ref_count_offset)
//
// NOTE: Ahead-Of-Time compilation (AOT) is NOT SUPPORTED. The main complication is that, the AOT
// ELF files are mapped directly to the program virtual space, and contain the code to execute.
Expand Down
12 changes: 11 additions & 1 deletion interpreter/hotspot/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,8 @@ func (d *hotspotInstance) getJITInfo(addr libpf.Address, addrCheck uint32) (
// [scopes_data] @ _immutable_data + nmethod._scopes_data_begin \ arrays we need
// [scopes_pcs] @ _immutable_data + nmethod._scopes_pcs_offset / for inlining info
// [speculations] @ _immutable_data + nmethod._speculations_offset
// [end] @ _immutable_Data + nmethod._immutable_data_size
// [end] @ _immutable_data + nmethod._immutable_data_size
// [end] @ _immutable_data + min(_immutable_data_size, _immutable_data_ref_count_offset) (JDK 26+)
// ...
// speculations presence depends on JDK build, and is not used. Instead the scopes
// end is determined from immutable data size.
Expand All @@ -535,6 +536,15 @@ func (d *hotspotInstance) getJITInfo(addr libpf.Address, addrCheck uint32) (
scopesDataOff := npsr.PtrDiff32(nmethod, vms.Nmethod.ScopesDataOffset)
immutableDataPtr := npsr.Ptr(nmethod, vms.Nmethod.ImmutableData)
immutableDataSize := npsr.Uint32(nmethod, vms.Nmethod.ImmutableDataSize)

// JDK26+: immutable data ends at ref_count offset, not at immutable_data_size
if vms.Nmethod.ImmutableDataRefCountOff != 0 {
immutableDataRefCountOff := npsr.Uint32(nmethod, vms.Nmethod.ImmutableDataRefCountOff)
if immutableDataRefCountOff < immutableDataSize {
immutableDataSize = immutableDataRefCountOff
}
}

if immutableDataSize >= maxMetadataSize {
return nil, fmt.Errorf("unreasonably large immutable data region: %d bytes",
immutableDataSize)
Expand Down
Loading