devicescript icon indicating copy to clipboard operation
devicescript copied to clipboard

code compression ideas

Open mmoskal opened this issue 2 years ago • 1 comments

These should make the generated bytecode a little smaller.

Approximate size reductions are give here for "allcompile.ts" - 68k binary with 38k of function code (and 6k of fonts).

  • [ ] change ALLOC_* opcodes to expressions
  • [ ] drop code alignment requirement (no reason for function text to be aligned) (1k)
  • [ ] drop length field from function descriptor (just assume it runs until the next function) (2.3k)
  • [ ] load_local(0...3) -> single opcode each - (3.5k)
  • [ ] post-optimize JMP targets (right now they are 3 byte each, can be often 1 byte) (1.8k)
  • [ ] when post-optimizing - order ascii strings by usage (~1k)
  • [ ] add static_ascii_string_high(n) (== static_ascii_string(n+0xf8)) ? (~1k?)
  • [ ] similarly, ascii_field_high?
  • [ ] look for often-used strings (eg in allcompile.ts) and add them to bytecode.md
  • [ ] look for other common bytecode sequences (see script below)

mmoskal avatar Apr 11 '23 20:04 mmoskal

Utility script so it doesn't get lost:

devs build -F allFunctions -F allPrototypes devs/run-tests/allcompile.ts
devs disasm -d > all.dasm
node analyze-bytecode.ts all.dasm
import { readFileSync } from "node:fs"

const OP_PRINT_FMTS = [
    // from bytecode.ts
]

const seqs = {
    1: {},
    2: {},
    3: {},
}

let lines = 0
let size = 0

for (const line of readFileSync(process.argv[2], "utf8").split(/\n/)) {
    const m = /^\s*\d+:\s*.*\/\/ ([0-9a-f]+)/.exec(line)
    if (m) {
        lines++
        const buf = Buffer.from(m[1], "hex")
        size += buf.length
        for (let i = 0; i < buf.length; i++) {
            for (const lens of Object.keys(seqs)) {
                const len = +lens
                const seq = buf.slice(i, i + len)
                if (seq.length == len) {
                    const s = seq.toString("hex")
                    if (!seqs[lens][s]) seqs[lens][s] = 0
                    seqs[lens][s]++
                }
            }
        }
    }
}

function show(map) {
    for (const [k, v] of Object.entries(map)
        .sort((a, b) => a[1] - b[1])
        .slice(-100)) {
        const buf = Buffer.from(k, "hex")
        const op = OP_PRINT_FMTS[buf[0]]
        console.log(k, v, op)
    }
}

show(seqs[2])
console.log({ lines, size })

mmoskal avatar Jul 17 '23 18:07 mmoskal