44package hotspot // import "go.opentelemetry.io/ebpf-profiler/interpreter/hotspot"
55
66import (
7- "bytes"
87 "encoding/binary"
98 "errors"
109 "fmt"
@@ -18,6 +17,7 @@ import (
1817
1918 "go.opentelemetry.io/ebpf-profiler/interpreter"
2019 "go.opentelemetry.io/ebpf-profiler/libpf"
20+ "go.opentelemetry.io/ebpf-profiler/libpf/pfatbuf"
2121 "go.opentelemetry.io/ebpf-profiler/libpf/pfelf"
2222 "go.opentelemetry.io/ebpf-profiler/libpf/xsync"
2323 "go.opentelemetry.io/ebpf-profiler/lpm"
@@ -396,48 +396,38 @@ func (d *hotspotData) Unload(_ interpreter.EbpfHandler) {
396396//
397397//nolint:lll
398398func locateJvmciVMStructs (ef * pfelf.File ) (libpf.Address , error ) {
399- const maxDataReadSize = 1 * 1024 * 1024 // seen in practice: 192 KiB
400- const maxRodataReadSize = 4 * 1024 * 1024 // seen in practice: 753 KiB
401-
402- rodataSec := ef .Section (".rodata" )
403- if rodataSec == nil {
399+ rodata := ef .Section (".rodata" )
400+ if rodata == nil {
404401 return 0 , errors .New ("unable to find `.rodata` section" )
405402 }
403+ cache := pfatbuf.Cache {}
404+ cache .Init (rodata )
406405
407- rodata , err := rodataSec . Data ( maxRodataReadSize )
406+ offs , err := cache . Search ([] byte ( "Klass_vtable_start_offset" ) )
408407 if err != nil {
409- return 0 , err
410- }
411-
412- offs := bytes .Index (rodata , []byte ("Klass_vtable_start_offset" ))
413- if offs == - 1 {
414408 return 0 , errors .New ("unable to find string for heuristic" )
415409 }
416410
417- ptr := rodataSec .Addr + uint64 (offs )
411+ ptr := rodata .Addr + uint64 (offs )
418412 ptrEncoded := make ([]byte , 8 )
419413 binary .LittleEndian .PutUint64 (ptrEncoded , ptr )
420414
421- dataSec := ef .Section (".data" )
422- if dataSec == nil {
415+ data := ef .Section (".data" )
416+ if data == nil {
423417 return 0 , errors .New ("unable to find `.data` section" )
424418 }
419+ cache .Init (data )
425420
426- data , err := dataSec . Data ( maxDataReadSize )
421+ offs , err = cache . Search ( ptrEncoded )
427422 if err != nil {
428- return 0 , err
429- }
430-
431- offs = bytes .Index (data , ptrEncoded )
432- if offs == - 1 {
433423 return 0 , errors .New ("unable to find string pointer" )
434424 }
435425
436426 // 8 in the expression below is what we'd usually read from
437427 // gHotSpotVMStructEntryFieldNameOffset. This value unfortunately lives in
438428 // BSS, so we have no choice but to hard-code it. Fortunately enough this
439429 // offset hasn't changed since at least JDK 9.
440- return libpf .Address (dataSec .Addr + uint64 (offs ) - 8 ), nil
430+ return libpf .Address (data .Addr + uint64 (offs ) - 8 ), nil
441431}
442432
443433// forEachItem walks the given struct reflection fields recursively, and calls the visitor
0 commit comments