Act nowcan affect a running systemThe raw payload contains two merge commits and 19 non-merge commits; every non-merge commit is covered below. It contains no superseded_by marker and no deprecation notice. The avoid window follows directly from the later build 16942 repair in the embedded sequence.
Per-writer logging locks land with required fallback repairs
TSynLog replaces its process-wide write lock with one lock per writer, reducing contention but also exposing failure paths repaired later in the same batch. Direct users of TX64CpuFeatures must remove cpuSSSE3 references, while supported x86-64 targets now select the SSSE3 JSON-number parser automatically. Log viewers, diagnostics tooling and callers of AppendShortByteHex also receive concrete correctness and API improvements.
TL;DR
- Land on build 2.4.16943 at 0b26918230d72e33b79365a79c1bc444ec3029b1; avoid the incomplete TSynLog sequence in builds 2.4.16937–2.4.16941.
- TSynLog now serializes writes per logger instead of through one global write lock, reducing contention between independent logs.
- Build 2.4.16942 repairs failed Enter, EnterLocal and ManualEnter paths introduced by the locking refactor.
- TX64CpuFeatures.cpuSSSE3 is removed; use cfSSSE3 in CpuFeatures when feature detection is needed.
- Supported non-PIC x86-64 Delphi and FPC targets now select GetNumericVariantSsse3 automatically for JSON numbers.
- Plain-text TSynLogFile search works again, and AppendShortByteHex safely accepts PtrUInt values above 255.
Upgrade advice
Take build 2.4.16943 at the current head and do not stop on builds 2.4.16937–2.4.16941, whose new per-writer locking still has failed Enter and recursion-accounting paths repaired in 16942. Search application code for cpuSSSE3 and replace it with cfSSSE3 in CpuFeatures. Rebuild every Delphi/FPC target, then test logger startup and rotation failures, nested log-writer callbacks, concurrent independent loggers, plain-text log search, and JSON numeric parsing on SSSE3 and non-SSSE3 machines.
19 of 19 entries · 21 commits upstream
1
High
The duplicate cpuSSSE3 feature flag is removed
mormot.core.base removes cpuSSSE3 from the public TX64CpuFeatures enumeration. Internal users now test cfSSSE3 in the general CpuFeatures set, and paranoid detection clears cfSSSE3 when cfSSE3 is absent.
Breaking changes
mormot.core.base+2
5f7b6d39+7-8
core: removed cpuSSSE3 from X64CpuFeatures
Impact
Delphi or FPC code that directly refers to cpuSSSE3 or expects it in X64CpuFeatures will no longer compile. General CPU-feature consumers should use cfSSSE3 in CpuFeatures instead.
Migration required
Search for cpuSSSE3 and X64CpuFeatures; replace the former with cfSSSE3 in CpuFeatures, then rebuild every x86-64 target.
Public API
TX64CpuFeatures.cpuSSSE3removed — Use cfSSSE3 in the general CpuFeatures set.
2
High
Failed log entry no longer masquerades as success
TSynLog LogEnter and LogEnterFmt now report whether writer preparation succeeded. Enter and EnterLocal return nil on failure, ManualEnter records a zero recursion marker, ManualLeave consumes it, and _Release always balances EndWrite.
Fixes
mormot.core.log
c3462904+72-52
core: fixed TSynLog.Enter* fallback on failure
Impact
Logger startup, rotation or nested writer failures no longer yield a false ISynLog scope or mismatched write recursion. This is the required correctness fix for applications taking the earlier per-writer locking commits.
Upgrade recommended
Land on build 2.4.16942 or later and test failed file creation, rotation and custom CreateLogWriter callbacks before production rollout.
Units
3
High
The logging-lock rewrite compiles again on Delphi
mormot.core.log introduces TSynLogFamilyDynArray and uses it for the global logger-family array and its local snapshot, resolving Delphi E2008 type incompatibility after the lock refactor.
Compiler & platform
mormot.core.log
f8937aeb+3-2
core: fix Delphi E2008 in SynLogException - Delphi treats each inline 'array of TSynLogFamily' declaration as a distinct type, so 'families := copy(SynLogFamily)' failed to compile. Use a named TSynLogFamilyDynArray for both.
Impact
The preceding refactor state could not compile on affected Delphi versions. This commit restores Delphi builds; FPC behavior and runtime logging semantics are unchanged.
Upgrade recommended
Do not consume the locking rewrite without this compatibility fix; rebuild all supported Delphi versions.
Public API
TSynLogFamilyDynArrayadded — Named dynamic-array type used by the logger-family registry.
Units
4
High
Each TSynLog writer gets its own write lock
The main TSynLog rewrite replaces the global write lock with fWriteSafe on each logger, separates exception and logger-list locks, tracks active writes in thread flags, and introduces BeginWrite, EndWrite and LockAndPrepareWrite helpers.
Under the hood
mormot.core.log
001b4c2d+9347-9020
core: huge refactoring of TSynLog locking
Impact
Independent loggers can write concurrently instead of contending on one process-wide lock, but the rewrite changes sensitive initialization, rotation and reentrancy paths. Builds before the later 16942 repair should not be deployed.
Worth a look
Take this only with the later 16942 repair, then stress multiple TSynLog instances, rotation, exception logging and custom writer callbacks under concurrency.
Units
5
Medium
Plain-text log search works again
TSynLogFile.LineContains now delegates to TMemoryMapText.LineContains when no parsed log levels exist, instead of returning false for every line in a plain-text file.
Fixes
mormot.core.log
638616f1+28-4
core: fixed TSynLogFile.LineContains() on plain text files
Impact
TSynLogFileView SearchNext and SearchPrevious can find text in non-SynLog files again. Structured SynLog search behavior remains unchanged for Delphi and FPC applications.
Upgrade recommended
Upgrade log-viewer deployments that open arbitrary text files and verify forward and backward search against a plain-text fixture.
Public API
TSynLogFile.LineContainsbehaviour-changed — Plain-text files now use the inherited text-search implementation.
Units
6
Medium
Log elapsed time starts when TSynLog is created
The TSynLog constructor now initializes its high-resolution start timestamp and UTC start date immediately. LogFileInit uses that stored UTC value and converts it to local time only when writing the header.
Fixes
mormot.core.log
71e8dc08+12-13
core: set TSynLog timestamp at startup
Impact
Elapsed timestamps and log headers are anchored consistently even when file initialization is delayed. Existing logging calls and Delphi/FPC public signatures do not change.
Upgrade recommended
Upgrade when elapsed log timing is used for startup diagnostics, and verify header time zones plus the first recorded duration.
Units
7
Medium
Hex appends no longer index past the digit table
AppendShortByteHex in mormot.core.base now masks the high nibble as well as the low nibble before indexing HexCharsUpper, so a PtrUInt value above 255 cannot read beyond that table.
Fixes
mormot.core.base
ae5a3b33+5-4
core: fixed AppendShortByteHex() overflow
Impact
Existing Delphi and FPC callers passing byte-sized values see no change. Callers passing a wider PtrUInt now get the low byte as two hexadecimal digits instead of an out-of-range table read.
Upgrade recommended
Upgrade if AppendShortByteHex can receive unmasked identifiers or offsets wider than one byte, and add a regression case above 255.
Public API
AppendShortByteHexbehaviour-changed — Values wider than one byte are now reduced to their low byte safely.
Units
8
Medium
Debug-file symbol lookup becomes public
TDebugFile exposes FindSymbol, both FindBlock overloads and FindBlockByName publicly, and adds Lookup(aRva), which combines source-file, line and symbol information for an address.
New features
mormot.core.log
5a3e5210+49-22
core: new TDebugFile public methods
Impact
Delphi and FPC diagnostic tools can query loaded debug metadata directly without subclassing TDebugFile. Existing callers keep the same behavior.
Public API
TDebugFile.FindSymbol / FindBlock / FindBlockByNamebehaviour-changed — These existing methods move from protected to public visibility.TDebugFile.Lookupadded — Returns formatted source and symbol information for an RVA.
Units
9
Medium
Raw log text is prepared before taking the writer lock
TSynLog.LogInternalText now truncates and validates UTF-8 before locking, then chooses a direct no-escape write when HasControlChars is false and falls back to escaped output for invalid UTF-8.
Performance
mormot.core.log
5fc4a796+35-29
core: optimized TSynLog.LogInternalText() process
Impact
Concurrent Delphi and FPC services spend less time inside the logger write lock for raw text. Valid output semantics are preserved, while malformed UTF-8 continues through the escaping path.
Units
10
Medium
SSSE3 becomes the default JSON-number parser on eligible x86-64 targets
GetNumericVariantFromJson now assigns GetNumericVariantStub to GetNumericVariantSsse3 during initialization when cpuSSSE3 is present on ASMX64NOTPIC builds. The former FORCE_SSSE3_JSON opt-in is removed.
Performance
mormot.core.text+1
4d78fdfe+7-11
core: enable GetNumericVariantSsse3() by default
Impact
Public signatures and numeric results stay the same, but supported Delphi Win64 and FPC x86-64 non-PIC backends use the SIMD path automatically. Other CPUs and PIC builds remain on the Pascal implementation.
Worth a look
Run representative JSON numeric workloads on each x86-64 compiler target and retain boundary-value tests for integers, fractions and exponents.
Public API
GetNumericVariantFromJsonbehaviour-changed — Eligible x86-64 builds now dispatch to GetNumericVariantSsse3 by default.
11
Low
UTF-8 buffers gain a direct control-character check
mormot.core.unicode adds the public HasControlChars(P, Len) helper, which reports bytes from zero through 31 and returns false for a nil or empty buffer.
New features
mormot.core.unicode
6f1bd299+21-2
core: new HasControlChars() function
Impact
Existing applications are unchanged. Delphi and FPC code can reuse the helper when deciding whether UTF-8 text requires escaping or line-aware handling.
Public API
HasControlCharsadded — Checks a UTF-8 byte range for ASCII control characters.
Units
12
Low
ShortString gains formatted variant appends
mormot.core.text adds the public AppendShortVar procedure, which formats an array of const through TFormatUtf8 and appends the result within a ShortString capacity.
New features
mormot.core.text
7565759e+15-2
core: new AppendShortVar() function
Impact
Application code is unaffected unless it adopts the helper; both Delphi and FPC callers can now append heterogeneous values without first creating a temporary UTF-8 string.
Public API
AppendShortVaradded — Formats array-of-const values directly into an existing ShortString.
Units
13
Low
Numeric bounds use direct 53-bit tests
The Pascal and x86-64 paths in GetNumericVariantFromJson replace MAX_SAFE_JS_INTEGER comparisons with shifts that directly test whether an unsigned value exceeds 53 bits, and simplify the Clinger fast-path guard.
Performance
mormot.core.base.asmx64+1
ba4b5c99+11-12
core: minor GetNumericVariantFromJson() optimization
Impact
JSON number results and public signatures are unchanged; Delphi and FPC builds only receive a smaller internal bounds check on these parsing paths.
14
Low
Integer variants convert to Double without a generic fallback
VariantToDouble in mormot.core.base adds direct cases for varInteger and varInt64 before falling back to the general Variant conversion machinery for other types.
Performance
mormot.core.base
25e283ab+8-4
core: optimized VariantToDouble()
Impact
Common integer variants convert with less overhead on Delphi and FPC. The public signature and expected numeric value are unchanged.
Units
15
Low
Numeric benchmarks use stable contiguous input
BenchmarkNumbers now pre-generates deterministic zero-terminated number tokens in one buffer, measures the Pascal and SSSE3 parsers independently, and verifies that parsing leaves the source buffer unchanged.
Tests
7e251513+123-108
tests: rewritten BenchmarkNumbers process
Impact
There is no application-code impact. The test suite gets more repeatable parser comparisons and can catch accidental writes into read-only JSON input.
16
Low
Slow core tests can run in parallel
The core test runner marks additional slow TTestCoreBase components for parallel execution under the multithread option, while retaining the event test on the main thread.
Tests
c772c201+61-47
tests: parallelize TTestCoreBase for /multithread
Impact
There is no runtime or application-code impact. Maintainers may see shorter multithreaded test runs without changing the production units.
17
Low
Logging tests cover nested writer creation
TestLogFileInit is updated for per-writer locking and verifies that a log attempt made from CreateLogWriter neither recurses into a second writer creation nor changes the exception state.
Tests
de95ebb6+18-12
tests: fixed TestLogFileInit after huge TSynLog refactoring
Impact
There is no direct application-code impact. The regression test protects custom logging-family implementations against recursive initialization after the lock rewrite.
18
Low
Parser benchmarks cross-check Pascal and SSSE3 results
BenchmarkNumbers expands correctness checks between GetExtended and GetNumericVariantFromJson and between their Pascal and SSSE3 implementations, while recording more consistent timing output.
Tests
63edb4c2+26-3
tests: BenchmarkNumbers check values consistency
Impact
There is no application-code impact. Numeric-parser regressions across Delphi/FPC and SIMD/non-SIMD paths become easier to detect in the test suite.
19
Low
Compiler-warning cleanup follows the logging rewrite
The logging unit removes an unnecessary local nil assignment, and tests assign string literals to typed variables before overload calls to avoid compiler warnings.
Housekeeping
mormot.core.log
d4bbc57f+8-6
core: fixed some Delphi compiler warnings
Impact
There is no application-code or runtime impact on Delphi or FPC; this only keeps the updated code and tests warning-clean.