TurboVM

TurboVM is a 64-byte fixed-format bytecode VM for parsing structured log lines. Two ISA-specific dispatchers (SSE 4.2 on x86-64, NEON on aarch64) share one bytecode contract. It runs inside liblognorm and powers the parsing stage of our rsyslog port.

Why

liblognorm’s scalar parser is adequate until the collector also runs WAKE. TurboVM compiles a rulebase ahead of time into a frozen instruction stream and executes it with SIMD literal matching, so parse cost is no longer the bottleneck.

Fixed 64-byte instruction
Every opcode is the same size, cache-line sized, with a 60-byte payload carried inline rather than through a separate literal pool: one fetch, no second indirection. Control flow is a relative jump plus a fork stack for alternatives. The bytecode contract is frozen so the userland compiler and the VM stay in sync.
Dual ISA code paths
One interpreter, with SIMD leaf helpers built per target: SSE 4.2 on x86-64, NEON on aarch64, and a scalar fallback. PCMPESTRI and its NEON equivalent do character-class and whitespace scanning; literal comparison is memcmp. Selection is at compile time, so a binary built without -msse4.2 stays on the scalar path whatever the CPU supports. Same bytecode either way.
Where the time goes
The bottleneck moves off parsing onto I/O, entity scoring, and downstream emission.

Instruction format

/* 64 bytes, cache-line sized. Payload is inline, not a pool offset. */
typedef struct {
    uint8_t  op;              /* Opcode */
    uint8_t  flags;           /* Flags */
    uint16_t aux;             /* Auxiliary (length, etc.) */
    union {
        char     str[60];        /* Inline literal or name */
        uint8_t  bytes[60];

        struct {                /* Jump / fork target */
            int32_t  offset;     /* Relative instruction offset */
            int32_t  _pad[14];
        } jump;

        struct {                /* Field with delimiter */
            char     name[56];
            uint8_t  delim;
            uint8_t  ass;        /* name-value-list assignator */
            uint8_t  ignore_ws;
            uint8_t  _pad[1];
        } char_to;
    } data;
} ln_instr_t;

_Static_assert(sizeof(ln_instr_t) == LN_INSTR_SIZE,
               "Instruction must be 64 bytes");

Upstream

TurboVM isn’t a fork. It ships as patches against the canonical upstream projects, integrated into MarlinOS’s devel/liblognorm and sysutils/rsyslog8 ports. The pieces that fit upstream go upstream.

WhereStatus
liblognorm PR #400Merged upstream.
liblognorm PR #403Merged upstream.
rsyslog follow-on workOngoing.
rsyslog PR #6667Merged upstream.