-------------------------------------------------------------------------------- Profile data file 'bin/callgrind.out' (creator: callgrind-3.25.1) -------------------------------------------------------------------------------- I1 cache: D1 cache: LL cache: Timerange: Basic block 0 - 8925766420 Trigger: Program termination Profiled target: bin/test (PID 300730, part 1) Events recorded: Ir Events shown: Ir Event sort order: Ir Thresholds: 99 Include dirs: User annotated: Auto-annotation: on -------------------------------------------------------------------------------- Ir -------------------------------------------------------------------------------- 46,140,953,603 (100.0%) PROGRAM TOTALS -------------------------------------------------------------------------------- Ir file:function -------------------------------------------------------------------------------- 32,323,278,849 (70.05%) src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_HAS$LONGWORD$$BOOLEAN [/home/ianh/hixie.ch/software/fun/isd/test-2024/servers/bin/test] 2,997,832,032 ( 6.50%) src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_REMOVE$LONGWORD [/home/ianh/hixie.ch/software/fun/isd/test-2024/servers/bin/test] 2,494,035,091 ( 5.41%) src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_INTERNALADD$h_cYmKE7NdsA [/home/ianh/hixie.ch/software/fun/isd/test-2024/servers/bin/test] 1,900,000,019 ( 4.12%) src//lib/random.pas:RANDOM$_$TRANDOMNUMBERGENERATOR_$__$$_GETCARDINAL$LONGWORD$LONGWORD$$LONGWORD [/home/ianh/hixie.ch/software/fun/isd/test-2024/servers/bin/test] 1,850,000,346 ( 4.01%) src//test.pas:main [/home/ianh/hixie.ch/software/fun/isd/test-2024/servers/bin/test] 1,450,007,585 ( 3.14%) src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_ADD$LONGWORD [/home/ianh/hixie.ch/software/fun/isd/test-2024/servers/bin/test] 1,400,000,014 ( 3.03%) src//lib/random.pas:RANDOM$_$TRANDOMNUMBERGENERATOR_$__$$_GETUINT32$$LONGWORD [/home/ianh/hixie.ch/software/fun/isd/test-2024/servers/bin/test] 1,011,557,018 ( 2.19%) src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_REMOVEAT$LONGWORD [/home/ianh/hixie.ch/software/fun/isd/test-2024/servers/bin/test] 714,040,423 ( 1.55%) /home/ianh/dev/fpc/source/rtl/linux//../x86_64/x86_64.inc:SYSTEM_$$_FILLDWORD$formal$INT64$LONGWORD [/home/ianh/hixie.ch/software/fun/isd/test-2024/servers/bin/test] -------------------------------------------------------------------------------- -- Auto-annotated source: /home/ianh/dev/fpc/source/rtl/linux//../x86_64/x86_64.inc -------------------------------------------------------------------------------- Ir -- line 92 ---------------------------------------- . const . NtThreshold = 256 * 1024; { this limit must be processor-specific (1/2 L2 cache size) } . PrefetchDistance = 512; . {$ifdef move_use_fast_repmovstos} . ErmsThreshold = 1536; . {$endif} . asm . {$if not defined(win64)} 55 ( 0.00%) mov %rdx, %r8 55 ( 0.00%) mov %rsi, %rdx 55 ( 0.00%) mov %rdi, %rcx . {$elseif defined(move_use_fast_repmovstos)} . push %rsi . .seh_pushreg %rsi . push %rdi . .seh_pushreg %rdi . .seh_endprologue . {$endif} . . {$ifdef move_use_fast_repmovstos} . .LRe: . {$endif} 55 ( 0.00%) cmp $3, %r8 55 ( 0.00%) jle .L3OrLess 36 ( 0.00%) cmp $8, %r8 36 ( 0.00%) jle .L4to8 20 ( 0.00%) cmp $16, %r8 20 ( 0.00%) jle .L9to16 16 ( 0.00%) movups (%rcx), %xmm4 { First and last 16 bytes, used both in .L33OrMore and 17–32 branch. } 16 ( 0.00%) movups -16(%rcx,%r8), %xmm5 16 ( 0.00%) cmp $32, %r8 16 ( 0.00%) jg .L33OrMore 2 ( 0.00%) movups %xmm4, (%rdx) { 17–32 bytes } 2 ( 0.00%) movups %xmm5, -16(%rdx,%r8) . {$if defined(win64) and defined(move_use_fast_repmovstos)} . pop %rdi . pop %rsi . {$endif} 2 ( 0.00%) ret . . .balign 16 . .L3OrLess: 19 ( 0.00%) cmp $1, %r8 19 ( 0.00%) jl .LZero 12 ( 0.00%) movzbl (%rcx), %eax 12 ( 0.00%) je .LOne 4 ( 0.00%) movzwl -2(%rcx,%r8), %r9d 4 ( 0.00%) mov %r9w, -2(%rdx,%r8) . .LOne: 12 ( 0.00%) mov %al, (%rdx) . .LZero: . {$if defined(win64) and defined(move_use_fast_repmovstos)} . pop %rdi . pop %rsi . {$endif} 19 ( 0.00%) ret . . .L4to8: 16 ( 0.00%) mov (%rcx), %eax 16 ( 0.00%) mov -4(%rcx,%r8), %r9d 16 ( 0.00%) mov %eax, (%rdx) 16 ( 0.00%) mov %r9d, -4(%rdx,%r8) . {$if defined(win64) and defined(move_use_fast_repmovstos)} . pop %rdi . pop %rsi . {$endif} 16 ( 0.00%) ret . . .L9to16: 4 ( 0.00%) mov (%rcx), %rax 4 ( 0.00%) mov -8(%rcx,%r8), %r9 4 ( 0.00%) mov %rax, (%rdx) 4 ( 0.00%) mov %r9, -8(%rdx,%r8) . .Lquit: . {$if defined(win64) and defined(move_use_fast_repmovstos)} . pop %rdi . pop %rsi . {$endif} 4 ( 0.00%) ret . {$if defined(win64) and defined(move_use_fast_repmovstos)} . .byte 102,102,102,102,102,144 . {$else} . .byte 102,102,102,102,102,102,102,102,102,102,102,144 . {$endif} { Turns .balign 16 before .Lloop32f into a no-op. } . . .L33OrMore: 14 ( 0.00%) movups -32(%rcx,%r8), %xmm3 { Second vector from the end. Wasted read if .Lback branch is taken (it uses second vector from the start instead), } . { but -32(%rcx,%r8) is about to become not accessible so easily, .Lback is rare, and small .Lback is even rarer / matters even less. } . 14 ( 0.00%) sub %rdx, %rcx { rcx = src - dest } 14 ( 0.00%) jz .Lquit { exit if src=dest } . 14 ( 0.00%) mov %rcx, %rax 14 ( 0.00%) neg %rax 14 ( 0.00%) cmp %rax, %r8 14 ( 0.00%) ja .Lback { count (r8) > unsigned(dest - src) (rax) if regions overlap } . 14 ( 0.00%) mov %rdx, %r9 { remember original dest to write first 16 bytes } 14 ( 0.00%) add %rdx, %r8 { Move dest to the next 16-byte boundary. +16 if already aligned, as first 16 bytes will be writen separately anyway. } 14 ( 0.00%) add $16, %rdx 14 ( 0.00%) and $-16, %rdx 14 ( 0.00%) sub %rdx, %r8 . . .LRestAfterNTf: 14 ( 0.00%) sub $32, %r8 { During the N× loop, r8 is N bytes less than actually remained to allow sub N+jae .LLoop instead of sub N+cmp N+jae .LLoop. } 14 ( 0.00%) jbe .LPost32f . {$ifdef move_use_fast_repmovstos} 14 ( 0.00%) cmp $ErmsThreshold-32, %r8 14 ( 0.00%) jae .LRepMovsOrNtF . .LRepMovsIsNotBetterF: . {$else} . cmp $NtThreshold-32, %r8 . jae .Lntf { might jump back right away after more checks, but the branch is taken only on huge moves so it's better to take these checks out of here... } . .LNtIsNotBetterF: . {$endif} . . .balign 16 { no-op } . .Lloop32f: 120 ( 0.00%) movups (%rcx,%rdx), %xmm0 120 ( 0.00%) movaps %xmm0, (%rdx) 120 ( 0.00%) movups 16(%rcx,%rdx), %xmm0 120 ( 0.00%) movaps %xmm0, 16(%rdx) 120 ( 0.00%) add $32, %rdx 120 ( 0.00%) sub $32, %r8 120 ( 0.00%) ja .Lloop32f . . .LPost32f: { +32 fixup not applied after 32× loop, r8 = remaining - 32 here. } 14 ( 0.00%) movups %xmm3, (%rdx, %r8) 14 ( 0.00%) movups %xmm5, 16(%rdx,%r8) { Write first and last 16 bytes after everything else. } 14 ( 0.00%) movups %xmm4, (%r9) { Important for <16-byte step between src and dest. } . {$if defined(win64) and defined(move_use_fast_repmovstos)} . pop %rdi . pop %rsi . {$endif} 14 ( 0.00%) ret . . {$ifdef move_use_fast_repmovstos} . .LRepMovsOrNtF: . cmp $NtThreshold-32, %r8 . jae .Lntf . .LNtIsNotBetterF: . {$ifdef FPC_PIC} . movq fast_large_repmovstosb@GOTPCREL(%rip), %rax -- line 234 ---------------------------------------- -- line 429 ---------------------------------------- . At least 1 of its bytes is exclusive to it, i.e. if x is already aligned, H1 starts at byte 16. . . H1 and so on are called “aligned heads” or just “heads”. . T1 and so on are called “aligned tails” or just “tails”. . . UT (“unaligned tail”) is written by the caller as well. . At least 1 of its bytes is exclusive to it as well, that’s why 65 is subtracted below instead of 64. } . 73 ( 0.00%) lea -65(%rcx,%rdx), %rax 73 ( 0.00%) and $-16, %rax { rax = “T4” (possibly fictive). } 73 ( 0.00%) mov %rax, %rdx { Remember T4 to rdx. } 73 ( 0.00%) and $-16, %rcx { rcx = H1 − 16. } 73 ( 0.00%) sub %rcx, %rax { rax = aligned byte count − 48. } 73 ( 0.00%) movdqa %xmm0, 16(%rcx) { Write H1. } 73 ( 0.00%) cmp $32-48, %rax 73 ( 0.00%) jle .LOneAlignedTailWrite 58 ( 0.00%) movdqa %xmm0, 32(%rcx) { Write H2. } 58 ( 0.00%) cmp $64-48, %rax 58 ( 0.00%) jle .LTwoAlignedTailWrites 56 ( 0.00%) sub $48, %rax { rax = aligned byte count − 96 (32 bytes already written + 64 bytes written after loop). } 56 ( 0.00%) jle .LFourAlignedTailWrites . 55 ( 0.00%) add $48, %rcx { rcx = H3. } . {$ifdef fillxxxx_use_fast_repmovstos} 55 ( 0.00%) cmp $ErmsThreshold-64, %rax { Need to write aligned byte count − 32 bytes already written. rax = aligned byte count − 96, so compare rax + 64 to ErmsThreshold, or rax to ErmsThreshold − 64. } 106 ( 0.00%) jae .LRepStos . {$else} . cmp $NtThreshold, %rax . jae .L64xNT_Body . {$endif} . . .balign 16 . .L64x_Body: 412 ( 0.00%) movdqa %xmm0, (%rcx) 412 ( 0.00%) movdqa %xmm0, 16(%rcx) 412 ( 0.00%) movdqa %xmm0, 32(%rcx) 412 ( 0.00%) movdqa %xmm0, 48(%rcx) 412 ( 0.00%) add $64, %rcx 412 ( 0.00%) sub $64, %rax 412 ( 0.00%) ja .L64x_Body . . .LFourAlignedTailWrites: 52 ( 0.00%) movdqa %xmm0, (%rdx) { T4 } 52 ( 0.00%) movdqa %xmm0, 16(%rdx) { T3 } . .LTwoAlignedTailWrites: 54 ( 0.00%) movdqa %xmm0, 32(%rdx) { T2 } . .LOneAlignedTailWrite: 69 ( 0.00%) movdqa %xmm0, 48(%rdx) { T1 } 69 ( 0.00%) ret . . {$ifdef fillxxxx_use_fast_repmovstos} . .LRepStos: . {$ifdef FPC_PIC} 4 ( 0.00%) movq fast_large_repmovstosb@GOTPCREL(%rip), %r8 4 ( 0.00%) cmpb $1, (%r8) . {$else FPC_PIC} . cmpb $1, fast_large_repmovstosb(%rip) . {$endif FPC_PIC} 4 ( 0.00%) jne .LRepStosIsNotBetter . {$ifdef win64} . push %rdi { For tests on Windows; however this is SEH incompliant so the entire fillxxxx_use_fast_repmovstos branch is disabled by default! } . {$endif} 4 ( 0.00%) mov %rcx, %rdi { rdi = REP STOS destination. } 4 ( 0.00%) lea 64(%rax), %rcx 4 ( 0.00%) shr $3, %rcx { rcx = count of REP STOSQ blocks up to T1 (might be 1 more than strictly required if T1 and UT overlap is 8 or more, don’t care). } 4 ( 0.00%) movq %xmm0, %rax { recover pattern for aligned writes back to GPR :) } 1,358 ( 0.00%) rep stosq . {$ifdef win64} . pop %rdi . {$endif} 4 ( 0.00%) ret . {$endif} . . .LRepStosIsNotBetter: . cmp $NtThreshold-64, %rax . jb .L64x_Body . . .balign 16 . .L64xNT_Body: -- line 507 ---------------------------------------- -- line 518 ---------------------------------------- . {$endif FPC_SYSTEM_HAS_FILLxxxx} . . {$ifndef FPC_SYSTEM_HAS_FILLCHAR} . {$define FPC_SYSTEM_HAS_FILLCHAR} . Procedure FillChar(var x;count:SizeInt;value:byte);assembler;nostackframe; . asm . { win64: rcx dest, rdx count, r8b value . linux: rdi dest, rsi count, rdx value } 77 ( 0.00%) movzbl {$ifdef win64} %r8b {$else} %dl {$endif}, %eax 77 ( 0.00%) imul $0x01010101, %eax . {$ifndef win64} 77 ( 0.00%) mov %rsi, %rdx 77 ( 0.00%) mov %rdi, %rcx . {$endif win64} . 77 ( 0.00%) cmp $3, %rdx 77 ( 0.00%) jle .L3OrLess 77 ( 0.00%) cmp $16, %rdx 77 ( 0.00%) jl .L4to15 . 77 ( 0.00%) movd %eax, %xmm0 77 ( 0.00%) pshufd $0, %xmm0, %xmm0 77 ( 0.00%) movdqu %xmm0, (%rcx) 77 ( 0.00%) movdqu %xmm0, -16(%rcx,%rdx) 77 ( 0.00%) cmp $32, %rdx 77 ( 0.00%) jg FillXxxx_MoreThanTwoXmms 4,606 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../x86_64/x86_64.inc:SYSTEM_$$_FILLXXXX_MORETHANTWOXMMS (66x) 11 ( 0.00%) ret . . .L4to15: . mov %eax, (%rcx) . cmp $8, %edx . jle .LLast4 . mov %eax, 4(%rcx) . mov %eax, -8(%rcx,%rdx) . .LLast4: -- line 552 ---------------------------------------- -- line 624 ---------------------------------------- . . {$ifndef FPC_SYSTEM_HAS_FILLDWORD} . {$define FPC_SYSTEM_HAS_FILLDWORD} . procedure FillDWord(var x;count:SizeInt;value:DWord);assembler;nostackframe; . asm . {$ifdef win64} . mov %r8d, %eax . {$else} 59,503,364 ( 0.13%) mov %edx, %eax 59,503,364 ( 0.13%) mov %rsi, %rdx 59,503,364 ( 0.13%) mov %rdi, %rcx . {$endif win64} . 59,503,364 ( 0.13%) cmp $3, %rdx 59,503,364 ( 0.13%) jle .L3OrLess 9 ( 0.00%) cmp $8, %rdx 9 ( 0.00%) jle .L4to8 . 7 ( 0.00%) movd %eax, %xmm0 7 ( 0.00%) pshufd $0, %xmm0, %xmm0 { xmm0 = pattern for unaligned writes } 7 ( 0.00%) movdqu %xmm0, (%rcx) 7 ( 0.00%) movdqu %xmm0, -16(%rcx,%rdx,4) . 7 ( 0.00%) shl $2, %rdx { rdx = byte count } 7 ( 0.00%) mov %rcx, %r8 7 ( 0.00%) shl $3, %ecx 7 ( 0.00%) rol %cl, %eax { misalign the pattern by the misalignment of x } 7 ( 0.00%) mov %r8, %rcx 7 ( 0.00%) movd %eax, %xmm0 7 ( 0.00%) pshufd $0, %xmm0, %xmm0 { xmm0 = pattern for aligned writes } 7 ( 0.00%) jmp FillXxxx_MoreThanTwoXmms 1,050 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../x86_64/x86_64.inc:SYSTEM_$$_FILLXXXX_MORETHANTWOXMMS (7x) . . .L4to8: . {$ifndef win64} { on win64, eax = r8d already. } 2 ( 0.00%) mov %eax, %r8d . {$endif} 2 ( 0.00%) shl $32, %r8 2 ( 0.00%) or %r8, %rax 2 ( 0.00%) mov %rax, (%rcx) 2 ( 0.00%) mov %rax, 8(%rcx) 2 ( 0.00%) mov %rax, -16(%rcx,%rdx,4) 2 ( 0.00%) mov %rax, -8(%rcx,%rdx,4) 2 ( 0.00%) ret . . .L3OrLess: 59,503,355 ( 0.13%) test %rdx, %rdx 59,503,355 ( 0.13%) jle .LQuit 59,503,355 ( 0.13%) mov %eax, (%rcx) 59,503,355 ( 0.13%) mov %eax, -4(%rcx,%rdx,4) 59,503,355 ( 0.13%) shr $1, %edx 59,503,355 ( 0.13%) mov %eax, (%rcx,%rdx,4) . .LQuit: 59,503,355 ( 0.13%) end; . {$endif FPC_SYSTEM_HAS_FILLDWORD} . . {$ifndef FPC_SYSTEM_HAS_FILLQWORD} . {$define FPC_SYSTEM_HAS_FILLQWORD} . procedure FillQWord(var x;count:SizeInt;value:QWord);assembler;nostackframe; . asm . {$ifdef win64} . mov %r8, %rax -- line 684 ---------------------------------------- -- line 726 ---------------------------------------- . {$endif FPC_SYSTEM_HAS_FILLQWORD} . . {$ifndef FPC_SYSTEM_HAS_INDEXBYTE} . {$define FPC_SYSTEM_HAS_INDEXBYTE} . function IndexByte(Const buf;len:SizeInt;b:byte):SizeInt; assembler; nostackframe; . { win64: rcx buf, rdx len, r8b word . linux: rdi buf, rsi len, rdx word } . asm 3 ( 0.00%) test len, len 3 ( 0.00%) jz .Lnotfound { exit if len=0 } . 3 ( 0.00%) movd {$ifdef win64} %r8d {$else} %edx {$endif}, %xmm1 3 ( 0.00%) mov {$ifdef win64} %ecx {$else} %edi {$endif}, %eax 3 ( 0.00%) punpcklbw %xmm1, %xmm1 3 ( 0.00%) punpcklbw %xmm1, %xmm1 3 ( 0.00%) and $4095, %eax 3 ( 0.00%) pshufd $0, %xmm1, %xmm1 . 3 ( 0.00%) cmp $4080, %eax 3 ( 0.00%) ja .LCrossPage . 3 ( 0.00%) movdqu ({$ifdef win64} %rcx {$else} %rdi {$endif}), %xmm0 { Analyze first 16 bytes, unaligned. } 3 ( 0.00%) pcmpeqb %xmm1, %xmm0 3 ( 0.00%) pmovmskb %xmm0, %eax 3 ( 0.00%) test %eax, %eax 3 ( 0.00%) jz .LContinueAligned . 3 ( 0.00%) bsf %eax, %eax 3 ( 0.00%) cmp len, %rax 3 ( 0.00%) jae .Lnotfound 3 ( 0.00%) ret . . .byte {$ifndef win64}102,102,102,102,{$endif}102,102,102,102,102,102,102,102,102,144 { Make .balign 16 before .Lloop a no-op. } . .LContinueAligned: . cmp $16, len { Length might be explicitly set to 16 or less; if so, skip a bit of work. } . jbe .Lnotfound { (Or rather, this check is *required* unless jumping to .Lcontinue instead of going directly to .Lloop) } . . {$ifdef win64} . mov %rcx, %r8 { r8 = original ptr, rcx = buf + 16 for aligning & shifts. } -- line 764 ---------------------------------------- -- line 1487 ---------------------------------------- . . {$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT} . { does a thread save inc/dec } . function declocked(var l : longint) : boolean;assembler; nostackframe; . asm . { this check should be done because a lock takes a lot } . { of time! } . {$ifdef FPC_PIC} 4 ( 0.00%) movq IsMultithread@GOTPCREL(%rip),%rax 4 ( 0.00%) cmpl $0,(%rax) . {$else FPC_PIC} . cmpl $0,IsMultithread(%rip) . {$endif FPC_PIC} 4 ( 0.00%) jz .Ldeclockedskiplock . .byte 0xF0 // LOCK prefix. . .Ldeclockedskiplock: 4 ( 0.00%) decl {$ifdef win64} (%rcx) {$else} (%rdi) {$endif} 4 ( 0.00%) setzb %al 4 ( 0.00%) end; . . . {$define FPC_SYSTEM_HAS_DECLOCKED_INT64} . function declocked(var l : int64) : boolean;assembler; nostackframe; . asm . { this check should be done because a lock takes a lot } . { of time! } . {$ifdef FPC_PIC} -- line 1513 ---------------------------------------- -- line 1526 ---------------------------------------- . . {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT} . procedure inclocked(var l : longint);assembler; nostackframe; . . asm . { this check should be done because a lock takes a lot } . { of time! } . {$ifdef FPC_PIC} 4 ( 0.00%) movq IsMultithread@GOTPCREL(%rip),%rax 4 ( 0.00%) cmpl $0,(%rax) . {$else FPC_PIC} . cmpl $0,IsMultithread(%rip) . {$endif FPC_PIC} 4 ( 0.00%) jz .Linclockedskiplock . .byte 0xF0 // LOCK prefix. . .Linclockedskiplock: 4 ( 0.00%) incl {$ifdef win64} (%rcx) {$else} (%rdi) {$endif} 4 ( 0.00%) end; . . . {$define FPC_SYSTEM_HAS_INCLOCKED_INT64} . procedure inclocked(var l : int64);assembler; nostackframe; . . asm . { this check should be done because a lock takes a lot } . { of time! } -- line 1551 ---------------------------------------- -- line 1641 ---------------------------------------- . . {$ifdef VER3_2} . function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; assembler; nostackframe; . {$else VER3_2} . {$define FPC_SYSTEM_HAS_ATOMIC_ADD_32} . function fpc_atomic_add_32 (var Target: longint;Value : longint) : longint; assembler; nostackframe; . {$endif VER3_2} . asm 3 ( 0.00%) lock . xaddl {$ifdef VER3_2} Source {$else} Value {$endif},({$ifdef win64} %rcx {$else} %rdi {$endif}) 3 ( 0.00%) movl {$ifdef VER3_2} Source {$else} Value {$endif},%eax 3 ( 0.00%) end; . . . {$ifdef VER3_2} . function InterLockedCompareExchange(var Target: longint; NewValue, Comperand : longint): longint; assembler; nostackframe; . {$else VER3_2} . {$define FPC_SYSTEM_HAS_ATOMIC_CMP_XCHG_32} . function fpc_atomic_cmp_xchg_32 (var Target: longint; NewValue, Comparand : longint) : longint; assembler; nostackframe; . {$endif VER3_2} -- line 1660 ---------------------------------------- -- line 1695 ---------------------------------------- . . {$ifdef VER3_2} . function InterLockedExchange64 (var Target: int64;Source : int64) : int64; assembler; nostackframe; . {$else VER3_2} . {$define FPC_SYSTEM_HAS_ATOMIC_XCHG_64} . function fpc_atomic_xchg_64 (var Target: int64;Source: int64) : int64; assembler; nostackframe; . {$endif VER3_2} . asm 1 ( 0.00%) xchgq ({$ifdef win64} %rcx {$else} %rdi {$endif}),Source 1 ( 0.00%) movq Source,%rax 1 ( 0.00%) end; . . . {$ifdef VER3_2} . function InterLockedExchangeAdd64 (var Target: int64;Source : int64) : int64; assembler; nostackframe; . {$else VER3_2} . {$define FPC_SYSTEM_HAS_ATOMIC_ADD_64} . function fpc_atomic_add_64 (var Target: int64;Value: int64) : int64; assembler; nostackframe; . {$endif VER3_2} -- line 1713 ---------------------------------------- -- line 1760 ---------------------------------------- . MM_MaskOverflow = %0000010000000000; . MM_MaskUnderflow = %0000100000000000; . MM_MaskPrecision = %0001000000000000; . . {$define FPC_SYSTEM_HAS_FPC_CPUINIT} . procedure fpc_cpuinit; . var . _eax,cpuid7_ebx,cpuid1_ecx : dword; 7 ( 0.00%) begin . { don't let libraries influence the FPU cw set by the host program } 4 ( 0.00%) if IsLibrary then . begin . Default8087CW:=Get8087CW; . DefaultMXCSR:=GetMXCSR; . end; 1 ( 0.00%) SysResetFPU; 7 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../x86_64/x86_64.inc:SYSTEM_$$_SYSRESETFPU (1x) . asm 1 ( 0.00%) xorl %eax,%eax 1 ( 0.00%) cpuid 1 ( 0.00%) movl %eax,_eax 1 ( 0.00%) movl $1,%eax 1 ( 0.00%) xorl %ecx,%ecx 1 ( 0.00%) cpuid 1 ( 0.00%) movl %ecx,cpuid1_ecx . end ['eax', 'ebx', 'ecx', 'edx']; 5 ( 0.00%) has_sse41_support:=boolean(cpuid1_ecx shr 19 and 1); 2 ( 0.00%) if _eax>=7 then . begin . asm 1 ( 0.00%) movl $7,%eax 1 ( 0.00%) xorl %ecx,%ecx 1 ( 0.00%) cpuid 1 ( 0.00%) movl %ebx,cpuid7_ebx . end ['eax', 'ebx', 'ecx', 'edx']; . {$if defined(move_use_fast_repmovstos) or defined(fillxxxx_use_fast_repmovstos)} 5 ( 0.00%) fast_large_repmovstosb:=cpuid7_ebx and (1 shl 9)<>0; . {$endif} . { XGETBV support? } 4 ( 0.00%) if (cpuid1_ecx and $8000000)<>0 then . begin . asm 2 ( 0.00%) xorl %ecx,%ecx . .byte 0x0f,0x01,0xd0 { xgetbv } 1 ( 0.00%) movl %eax,_eax . end ['eax', 'rcx', 'edx']; 4 ( 0.00%) if (_eax and 6)=6 then . begin 5 ( 0.00%) has_avx_support:=(cpuid1_ecx and $10000000)<>0; 5 ( 0.00%) has_avx2_support:=(cpuid7_ebx and $20)<>0; . end; . end; . end; 2 ( 0.00%) fpc_cpuinit_performed:=true; 4 ( 0.00%) end; . . {$define FPC_SYSTEM_HAS_SYSINITFPU} . Procedure SysInitFPU; . begin . end; . . . {$define FPC_SYSTEM_HAS_SYSRESETFPU} . Procedure SysResetFPU;assembler;nostackframe; . asm 1 ( 0.00%) fninit 1 ( 0.00%) fwait . {$ifdef FPC_PIC} 1 ( 0.00%) movq Default8087CW@GOTPCREL(%rip),%rax 1 ( 0.00%) fldcw (%rax) 1 ( 0.00%) movq DefaultMXCSR@GOTPCREL(%rip),%rax 1 ( 0.00%) ldmxcsr (%rax) . {$else FPC_PIC} . fldcw Default8087CW(%rip) . ldmxcsr DefaultMXCSR(%rip) . {$endif FPC_PIC} 1 ( 0.00%) end; . . . {$ifndef FPC_SYSTEM_HAS_MEM_BARRIER} . {$define FPC_SYSTEM_HAS_MEM_BARRIER} . . procedure ReadBarrier;assembler;nostackframe; . asm . lfence -- line 1843 ---------------------------------------- -- line 1883 ---------------------------------------- . end; . . . function SwapEndian(const AValue: LongInt): LongInt; assembler; nostackframe; . asm . {$ifdef win64} . movl %ecx, %eax . {$else win64} 13 ( 0.00%) movl %edi, %eax . {$endif win64} 13 ( 0.00%) bswap %eax 13 ( 0.00%) end; . . . function SwapEndian(const AValue: DWord): DWord; assembler; nostackframe; . asm . {$ifdef win64} . movl %ecx, %eax . {$else win64} . movl %edi, %eax -- line 1902 ---------------------------------------- -------------------------------------------------------------------------------- -- Auto-annotated source: src//lib/random.pas -------------------------------------------------------------------------------- Ir -- line 39 ---------------------------------------- . ProbabilityRandomize: 0.0; . RandomizeMin: 0.0; . RandomizeMax: 0.0 . ); . . implementation . . constructor TRandomNumberGenerator.Create(ASeed: UInt64); 22 ( 0.00%) begin 334 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_NEWINSTANCE$$TOBJECT (1x) 36 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/except.inc:fpc_pushexceptaddr (1x) 12 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../x86_64/setjump.inc:fpc_setjmp (1x) 3 ( 0.00%) inherited Create(); 107 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_CREATE$$TOBJECT (1x) . {$PUSH} . {$OVERFLOWCHECKS-} . {$RANGECHECKS-} 4 ( 0.00%) FIncrement := (ASeed << 1) + 1; // must be an odd number // $R- (we drop the high bit) . {$POP} 3 ( 0.00%) FState := FIncrement; 13 ( 0.00%) end; 7 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_AFTERCONSTRUCTION (1x) . . function TRandomNumberGenerator.GetSeed(): UInt64; . begin . Result := FIncrement >> 1; . end; . . procedure TRandomNumberGenerator.Reset(NewState: UInt64); . begin . FState := NewState; . end; . . function TRandomNumberGenerator.GetUInt32(): UInt32; 100,000,001 ( 0.22%) begin . {$PUSH} . {$OVERFLOWCHECKS-} . {$RANGECHECKS-} 400,000,004 ( 0.87%) FState := FState * FMultiplier + FIncrement; 800,000,008 ( 1.73%) Result := RoRDWord((FState xor (FState >> 18)) >> 27, FState >> 59); // $R- // first argument intentionally drops some high bits . {$POP} 100,000,001 ( 0.22%) end; . . function TRandomNumberGenerator.GetCardinal(Min, Max: Cardinal): Cardinal; 400,000,004 ( 0.87%) begin 1,100,000,011 ( 2.38%) Result := Min + Trunc((Max - Min) * GetUInt32() / (High(UInt32) + 1)); // $R- 1,400,000,014 ( 3.03%) => src//lib/random.pas:RANDOM$_$TRANDOMNUMBERGENERATOR_$__$$_GETUINT32$$LONGWORD (100,000,001x) 400,000,004 ( 0.87%) end; . . function TRandomNumberGenerator.GetDouble(Min, Max: Double): Double; . begin . Result := Min + (Max - Min) * GetUInt32() / (High(UInt32) + 1.0); . end; . . function TRandomNumberGenerator.GetBoolean(Probability: Double): Boolean; . begin -- line 88 ---------------------------------------- 3 ( 0.00%) -------------------------------------------------------------------------------- -- Auto-annotated source: src//test.pas -------------------------------------------------------------------------------- Ir -- line 7 ---------------------------------------- . TA = specialize THashSet; . TB = specialize TTightHashSet; . . var . A: TA; . B: TB; . RNG: TRandomNumberGenerator; . I, V: Cardinal; 3 ( 0.00%) begin 30,016 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/system.inc:fpc_initializeunits (1x) 6 ( 0.00%) A := TA.Create(@Integer32Hash32); 1,665 ( 0.00%) => /home/ianh/hixie.ch/software/fun/isd/test-2024/servers/src//lib/hashset.pas:P$PROGRAM$_$THASHSET$2$CRC1928F2AA_CRC806D4624_$__$$_CREATE$htWWYHEzZBKB (1x) 5 ( 0.00%) B := TB.Create(); 563 ( 0.00%) => /home/ianh/hixie.ch/software/fun/isd/test-2024/servers/src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_CREATE$hxUQCXGA5rFK (1x) 5 ( 0.00%) RNG := TRandomNumberGenerator.Create(0); 568 ( 0.00%) => /home/ianh/hixie.ch/software/fun/isd/test-2024/servers/src//lib/random.pas:RANDOM$_$TRANDOMNUMBERGENERATOR_$__$$_CREATE$QWORD$$TRANDOMNUMBERGENERATOR (1x) . 9 ( 0.00%) try 36 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/except.inc:fpc_pushexceptaddr (1x) 12 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../x86_64/setjump.inc:fpc_setjmp (1x) 300,000,005 ( 0.65%) for I := 0 to 100000000 do . begin 500,000,005 ( 1.08%) V := RNG.GetCardinal(1, 1024-1); 3,300,000,033 ( 7.15%) => /home/ianh/hixie.ch/software/fun/isd/test-2024/servers/src//lib/random.pas:RANDOM$_$TRANDOMNUMBERGENERATOR_$__$$_GETCARDINAL$LONGWORD$LONGWORD$$LONGWORD (100,000,001x) 200,000,002 ( 0.43%) if (V > 0) then . begin . // if (not A.Has(V)) then . // begin . // A.Add(V); . // end . // else . // begin . // A.Reset(); . // //A.Remove(V); . // end; 500,000,005 ( 1.08%) if (not B.Has(V)) then 32,598,883,655 (70.65%) => /home/ianh/hixie.ch/software/fun/isd/test-2024/servers/src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_HAS$LONGWORD$$BOOLEAN (100,000,001x) . begin 200,001,044 ( 0.43%) B.Add(V); 3,944,063,247 ( 8.55%) => /home/ianh/hixie.ch/software/fun/isd/test-2024/servers/src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_ADD$LONGWORD (50,000,261x) . end . else . begin 149,999,220 ( 0.33%) B.Remove(V); 4,447,824,492 ( 9.64%) => /home/ianh/hixie.ch/software/fun/isd/test-2024/servers/src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_REMOVE$LONGWORD (49,999,740x) . end; . end; . end; . except . Writeln('failed at I=', I); . ReportCurrentException(); . end; 27 ( 0.00%) Writeln('Result: ', A.Count, ' ', B.Count); 728 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/text.inc:fpc_write_text_uint (2x) 193 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/text.inc:fpc_writeln_end (1x) 100 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/system.inc:fpc_iocheck (5x) 92 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/text.inc:fpc_write_text_shortstr (1x) 39 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/text.inc:fpc_write_text_char (1x) 16 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/text.inc:fpc_get_output (1x) . 2 ( 0.00%) A.Free(); 640 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_FREE (1x) 2 ( 0.00%) B.Free(); 467 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_FREE (1x) 2 ( 0.00%) RNG.Free(); 228 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_FREE (1x) 1 ( 0.00%) end. 16,258 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/system.inc:fpc_do_exit (1x) 3 ( 0.00%) -------------------------------------------------------------------------------- -- Auto-annotated source: src//lib/hashsettight.pas -------------------------------------------------------------------------------- Ir -- line 269 ---------------------------------------- . end; . . . constructor TTightHashSet.Create(const PredictedCount: TSizeInt = 0); . const . LoadFactorLimit = 1/kMaxLoad; . var . AllocCount: TSizeInt; 22 ( 0.00%) begin 334 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_NEWINSTANCE$$TOBJECT (1x) 36 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/except.inc:fpc_pushexceptaddr (1x) 12 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../x86_64/setjump.inc:fpc_setjmp (1x) 3 ( 0.00%) inherited Create(); 107 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_CREATE$$TOBJECT (1x) 2 ( 0.00%) if (PredictedCount > 0) then . begin . if (PredictedCount * LoadFactorLimit < High(TSizeInt)) then . AllocCount := Trunc(PredictedCount * LoadFactorLimit) // $R- . else . AllocCount := High(TSizeInt); . FTable := GetMem(AllocCount * SizeOf(T)); // $R- . FAllocated := AllocCount; . Utils.Clear(FTable^, AllocCount); . end; 13 ( 0.00%) end; 7 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_AFTERCONSTRUCTION (1x) . . destructor TTightHashSet.Destroy(); 9 ( 0.00%) begin 7 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_BEFOREDESTRUCTION (1x) 2 ( 0.00%) Reset(); 218 ( 0.00%) => src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_RESET (1x) 3 ( 0.00%) inherited; 16 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_DESTROY (1x) 13 ( 0.00%) end; 185 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/objpas.inc:SYSTEM$_$TOBJECT_$__$$_FREEINSTANCE (1x) . . procedure TTightHashSet.Reset(); 2 ( 0.00%) begin 2 ( 0.00%) if (Assigned(FTable)) then . begin 3 ( 0.00%) FreeMem(FTable); 206 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/cmem.pp:CMEM_$$_CFREEMEM$POINTER$$QWORD (1x) 1 ( 0.00%) FTable := nil; 1 ( 0.00%) FAllocated := 0; 1 ( 0.00%) FCount := 0; . end; 2 ( 0.00%) end; . . procedure TTightHashSet.DoubleSize(); 18 ( 0.00%) begin . Assert(FAllocated > 0); 45 ( 0.00%) if (FAllocated * 2 < High(TSizeInt)) then 36 ( 0.00%) Resize(FAllocated * 2) // $R- 48,391 ( 0.00%) => src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_RESIZE$LONGWORD (9x) . else . if (FAllocated < High(TSizeInt)) then . Resize(High(TSizeInt)); 18 ( 0.00%) end; . . procedure TTightHashSet.Resize(const NewSize: TSizeInt); . var . NewSet: PArray; . Index: TSizeInt; . Item: T; 72 ( 0.00%) begin . {$IFDEF VERBOSE} Writeln('Resize ', NewSize); {$ENDIF} . Assert(NewSize > 0); . Assert(FAllocated > 0); 18 ( 0.00%) if (NewSize <> FAllocated) then . begin 36 ( 0.00%) NewSet := GetMem(NewSize * SizeOf(T)); // $R- 1,800 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/cmem.pp:CMEM_$$_CGETMEM$QWORD$$POINTER (9x) 36 ( 0.00%) Utils.Clear(NewSet^, NewSize); 1,213 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../x86_64/x86_64.inc:SYSTEM_$$_FILLDWORD$formal$INT64$LONGWORD (9x) 3,102 ( 0.00%) for Index := 0 to FAllocated - 1 do // $R- . begin 3,066 ( 0.00%) Item := FTable^[Index]; 6,132 ( 0.00%) if (Utils.IsOccupied(Item)) then 3,555 ( 0.00%) InternalAdd(NewSet, NewSize, Item); 28,157 ( 0.00%) => src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_INTERNALADD$h_cYmKE7NdsA (711x) . end; 27 ( 0.00%) FreeMem(FTable); 1,087 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/cmem.pp:CMEM_$$_CFREEMEM$POINTER$$QWORD (9x) 18 ( 0.00%) FTable := NewSet; 9 ( 0.00%) FAllocated := NewSize; . end; 63 ( 0.00%) end; . . procedure TTightHashSet.InternalAdd(var Table: PArray; const Allocated: TSizeInt; const Value: T); . var . Hash: TSizeInt; 50,000,972 ( 0.11%) begin . Assert(Allocated > 0); . Assert(Assigned(Table)); . Assert(Utils.IsOccupied(Value), 'tried to add nil value to tight hash set'); 1,050,020,412 ( 2.28%) Hash := Utils.Hash(Value) mod Allocated; // $R- 980,471,327 ( 2.12%) while (Utils.IsOccupied(Table^[Hash])) do . begin 53,384,623 ( 0.12%) Inc(Hash); 106,769,246 ( 0.23%) if (Hash = Allocated) then 53,384,623 ( 0.12%) Hash := 0; . end; . Assert(not Utils.IsOccupied(Table^[Hash])); 150,002,916 ( 0.33%) Table^[Hash] := Value; 50,000,972 ( 0.11%) end; . . procedure TTightHashSet.Add(const Value: T); 250,001,305 ( 0.54%) begin . {$IFDEF VERBOSE} Writeln('Add ', Value); {$ENDIF} . Assert(not Has(Value), 'TTightHashSet.Add must not be called with a value that is already in the set.'); . Assert(Utils.IsOccupied(Value), 'tried to add nil value to tight hash set'); 50,000,261 ( 0.11%) Inc(FCount); 100,000,522 ( 0.22%) if (FAllocated = 0) then . begin . Assert(not Assigned(FTable)); . Assert(FCount = 1); 2 ( 0.00%) FAllocated := 2; 3 ( 0.00%) FTable := GetMem(FAllocated * SizeOf(T)); // $R- 208 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../inc/cmem.pp:CMEM_$$_CGETMEM$QWORD$$POINTER (1x) 5 ( 0.00%) Utils.Clear(FTable^, FAllocated); 12 ( 0.00%) => /home/ianh/dev/fpc/source/rtl/linux//../x86_64/x86_64.inc:SYSTEM_$$_FILLDWORD$formal$INT64$LONGWORD (1x) . end . else 600,003,120 ( 1.30%) if (FCount / FAllocated > kMaxLoad) then 18 ( 0.00%) DoubleSize(); 48,508 ( 0.00%) => src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_DOUBLESIZE (9x) . Assert(FCount < FAllocated); 250,001,305 ( 0.54%) InternalAdd(FTable, FAllocated, Value); 2,494,006,934 ( 5.41%) => src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_INTERNALADD$h_cYmKE7NdsA (50,000,261x) 200,001,044 ( 0.43%) end; . . function TTightHashSet.Intern(const Value: T): T; . var . Hash: TSizeInt; . begin . Assert(Utils.IsOccupied(Value), 'tried to intern nil value to tight hash set'); . if (FCount > 0) then . begin -- line 388 ---------------------------------------- -- line 448 ---------------------------------------- . if (Index = FAllocated) then . Index := 0; . end; . end; . {$POP} . . var . Index: TSizeInt; 297,516,770 ( 0.64%) begin . {$IFDEF VERBOSE} Writeln('Remove at ', Hash); {$ENDIF} 416,523,478 ( 0.90%) Utils.Delete(FTable^[Hash], 1); 714,040,248 ( 1.55%) => /home/ianh/dev/fpc/source/rtl/linux//../x86_64/x86_64.inc:SYSTEM_$$_FILLDWORD$formal$INT64$LONGWORD (59,503,354x) 59,503,354 ( 0.13%) exit; . // We could try to fix the table as follows: . // Utils.Clear(FTable^[Hash], 1); . // Refill(Hash); . // But that's slow because of all the rehashing we have to . // continually do. So instead we just leave a sentinel value. . // However before doing that, let's just quickly check if the . // previous values are also deleted; if they are, we can remove . // the lot of them all at once to speed things up. -- line 467 ---------------------------------------- -- line 489 ---------------------------------------- . Utils.Clear(FTable^[Index], Hash - Index + 1); // $R- . end . else . begin . Utils.Clear(FTable^[Index], FAllocated - Index); // $R- . Utils.Clear(FTable^[0], Hash + 1); // $R- . end; . end; 238,013,416 ( 0.52%) end; . . procedure TTightHashSet.Remove(const Value: T); . var . Hash: TSizeInt; 249,998,700 ( 0.54%) begin . {$IFDEF VERBOSE} Writeln('Remove ', Value); {$ENDIF} . Assert(Utils.IsOccupied(Value), 'tried to remove nil value from tight hash set'); 99,999,480 ( 0.22%) if (FCount > 0) then . begin 1,299,993,240 ( 2.82%) Hash := Utils.Hash(Value) mod FAllocated; // $R- 365,947,304 ( 0.79%) while (Utils.IsNotEmpty(FTable^[Hash])) do . begin 315,947,564 ( 0.68%) if (Utils.Equals(FTable^[Hash], Value)) then . begin 49,999,740 ( 0.11%) Dec(FCount); 99,999,480 ( 0.22%) if (FCount > 0) then . begin 199,998,960 ( 0.43%) RemoveAt(Hash); 1,449,992,460 ( 3.14%) => src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_REMOVEAT$LONGWORD (49,999,740x) . end . else . begin . Reset(); . end; . exit; . end; 28,987,151 ( 0.06%) Inc(Hash); 57,974,302 ( 0.13%) if (Hash = FAllocated) then 28,987,151 ( 0.06%) Hash := 0; . end; . end; 199,998,960 ( 0.43%) end; . . {$PUSH} . //{$DEFINE VERBOSE} . function TTightHashSet.Has(const Value: T): Boolean; . var . Hash: TSizeIntIndex; // TODO: change this to TSizeInt when https://gitlab.com/freepascal.org/fpc/source/-/issues/41317 is fixed . NewPosition: TSizeIntIndex; 709,503,621 ( 1.54%) begin . {$IFDEF VERBOSE} Writeln('Has ', Value); {$ENDIF} . Assert(Utils.IsOccupied(Value), 'tried to check for nil value in tight hash set'); 200,000,002 ( 0.43%) if (FCount > 0) then . begin 2,700,000,000 ( 5.85%) Hash := Utils.Hash(Value) mod FAllocated; // $R- . {$IFDEF VERBOSE} Writeln(' starting at ', Hash); {$ENDIF} 100,000,000 ( 0.22%) NewPosition := -1; 6,547,838,926 (14.19%) while (Utils.IsNotEmpty(FTable^[Hash])) do . begin . {$IFDEF VERBOSE} Writeln(' not empty at ', Hash, '; deleted=', Utils.IsDeleted(FTable^[Hash])); {$ENDIF} 6,297,838,146 (13.65%) if (Utils.Equals(FTable^[Hash], Value)) then . begin . {$IFDEF VERBOSE} Writeln(' found at ', Hash); {$ENDIF} 99,999,480 ( 0.22%) if (NewPosition >= 0) then . begin . {$IFDEF VERBOSE} Writeln(' moving ', Hash, ' up to ', NewPosition); {$ENDIF} 19,007,228 ( 0.04%) FTable^[NewPosition] := FTable^[Hash]; . {$IFDEF VERBOSE} Writeln(' clearing at ', Hash); {$ENDIF} 28,510,842 ( 0.06%) RemoveAt(Hash); // $R- // TODO: remove when Hash is a TSizeInt again 275,604,806 ( 0.60%) => src//lib/hashsettight.pas:P$PROGRAM$_$TTIGHTHASHSET$2$CRC74731A2A_CRC3D6C0C19_$__$$_REMOVEAT$LONGWORD (9,503,614x) . end; 49,999,740 ( 0.11%) Result := True; 49,999,740 ( 0.11%) exit; . end; 4,382,308,192 ( 9.50%) if ((NewPosition < 0) and Utils.IsDeleted(FTable^[Hash])) then . begin . {$IFDEF VERBOSE} Writeln(' found deleted spot at ', Hash); {$ENDIF} 141,874,454 ( 0.31%) NewPosition := Hash; . end; 2,049,279,642 ( 4.44%) Inc(Hash); 6,147,838,926 (13.32%) if (Hash = FAllocated) then 2,049,279,642 ( 4.44%) Hash := 0; . end; . end; . {$IFDEF VERBOSE} Writeln(' nope'); {$ENDIF} 50,000,261 ( 0.11%) Result := False; 700,000,007 ( 1.52%) end; . {$POP} . . constructor TTightHashSet.TEnumerator.Create(const Owner: TTightHashSet); . begin . FOwner := Owner; . FIndex := -1; . end; . -- line 580 ---------------------------------------- 3 ( 0.00%) -------------------------------------------------------------------------------- Ir -------------------------------------------------------------------------------- 46,140,776,493 (100.0%) events annotated