src/wam/constants.lisp @ 72bbdd515725
Rewrite the compiler A few days ago I found a bug in the compiler that I decided merited basically an entire rewrite of it. This was long overdue. The compiler kind of grew organically and unhealthily over time as I wrapped my head around how the whole WAM is structured, and now that I understand a lot more I can do things right. This new implementation is a lot "flatter" than the old one. It makes use of CLOS classes and generic methods to un-nest a lot of the crap that was previously happening in bigass `labels` blocks. This is a lot easier to read and understand because you can take things a piece at a time. Unfortunately, it's currently a lot slower than the old one. But at least it's *correct*, and now I can start taking a look at optimizing the performance with a cleaner base to start from. Notes/ideas for the near future: * Switch to structs instead of CLOS classes for all the bits and bobs in the compilation process. * Inline hot functions in the compilation process. * Type hint the fucking compiler already. I've put this off for far too long. * Move the compiler to its own package for easier profiling and to maintain my shreds of sanity. * Look into that generic-function-inlining library thing I saw on Reddit... * Remove the last vestiges of `match` and kill the dependency on optima.
| author | Steve Losh <steve@stevelosh.com> |
|---|---|
| date | Tue, 07 Jun 2016 14:49:20 +0000 |
| parents | e244881864f7 |
| children | 792dfa2f9120 |
(in-package #:bones.wam) (define-constant +cell-width+ 16 :documentation "Number of bits in each cell.") (define-constant +cell-tag-width+ 3 :documentation "Number of bits reserved for cell type tags.") (define-constant +cell-value-width+ (- +cell-width+ +cell-tag-width+) :documentation "Number of bits reserved for cell values.") (define-constant +cell-tag-bitmask+ #b111 :documentation "Bitmask for masking the cell type tags.") (define-constant +code-word-size+ 16 :documentation "Size (in bits) of each word in the code store.") (define-constant +code-limit+ (expt 2 +code-word-size+) :documentation "Maximum size of the WAM code store.") (define-constant +code-sentinel+ (1- +code-limit+) ; TODO: Should this sentinel value be 0 like everything else? :documentation "Sentinel value used in the PC and CP.") (define-constant +tag-null+ #b000 :documentation "An empty cell.") (define-constant +tag-structure+ #b001 :documentation "A structure cell.") (define-constant +tag-reference+ #b010 :documentation "A pointer to a cell.") (define-constant +tag-functor+ #b011 :documentation "A functor.") (define-constant +tag-constant+ #b100 :documentation "A constant (i.e. a 0-arity functor).") (define-constant +tag-list+ #b101 :documentation "A Prolog list.") (define-constant +register-count+ 2048 :documentation "The number of local registers the WAM has available.") (define-constant +maximum-arity+ 1024 :documentation "The maximum allowed arity of functors.") (define-constant +maximum-query-size+ 1024 :documentation "The maximum size (in bytes of bytecode) a query may compile to.") (define-constant +stack-limit+ 2048 :documentation "Maximum size of the WAM stack.") (define-constant +stack-frame-size-limit+ (+ 7 +register-count+) :documentation "The maximum size, in stack frame words, that a stack frame could be.") (define-constant +stack-start+ +register-count+ :documentation "The address in the store of the first cell of the stack.") (define-constant +stack-end+ (+ +stack-start+ +stack-limit+) :documentation "The address in the store one past the last cell in the stack.") (define-constant +heap-start+ +stack-end+ :documentation "The address in the store of the first cell of the heap.") (define-constant +trail-limit+ (expt 2 +cell-width+) ;; The trail's fill pointer is stored inside choice frames on the stack, so it ;; needs to be able to fit inside a stack word. We don't tag it, though, so ;; we can technically use all of the cell bits if we want. ;; ;; TODO: should probably limit this to something more reasonable :documentation "The maximum number of variables that may exist in the trail.") (define-constant +store-limit+ (expt 2 +cell-value-width+) ;; Reference cells need to be able to store a heap address in their value ;; bits, so that limits the amount of addressable space we've got to work ;; with. :documentation "Maximum size of the WAM store.") (define-constant +heap-limit+ (- +store-limit+ +register-count+ +stack-limit+) ;; The heap gets whatever's left over after the registers and stack have taken ;; their chunk of memory. :documentation "Maximum size of the WAM heap.") (define-constant +functor-limit+ (expt 2 +cell-value-width+) ;; Functors are referred to by their index into the functor array. This index ;; is stored in the value part of functor cells. :documentation "The maximum number of functors the WAM can keep track of.") ;;;; Opcodes (define-constant +opcode-noop+ 0) ;;; Program (define-constant +opcode-get-structure+ 1) (define-constant +opcode-unify-variable-local+ 2) (define-constant +opcode-unify-variable-stack+ 3) (define-constant +opcode-unify-value-local+ 4) (define-constant +opcode-unify-value-stack+ 5) (define-constant +opcode-get-variable-local+ 6) (define-constant +opcode-get-variable-stack+ 7) (define-constant +opcode-get-value-local+ 8) (define-constant +opcode-get-value-stack+ 9) ;;; Query (define-constant +opcode-put-structure+ 10) (define-constant +opcode-set-variable-local+ 11) (define-constant +opcode-set-variable-stack+ 12) (define-constant +opcode-set-value-local+ 13) (define-constant +opcode-set-value-stack+ 14) (define-constant +opcode-put-variable-local+ 15) (define-constant +opcode-put-variable-stack+ 16) (define-constant +opcode-put-value-local+ 17) (define-constant +opcode-put-value-stack+ 18) ;;; Control (define-constant +opcode-call+ 19) (define-constant +opcode-proceed+ 20) (define-constant +opcode-allocate+ 21) (define-constant +opcode-deallocate+ 22) (define-constant +opcode-done+ 23) (define-constant +opcode-try+ 24) (define-constant +opcode-retry+ 25) (define-constant +opcode-trust+ 26) (define-constant +opcode-cut+ 27) ;;; Constants (define-constant +opcode-get-constant+ 28) (define-constant +opcode-set-constant+ 29) (define-constant +opcode-put-constant+ 30) (define-constant +opcode-unify-constant+ 31) ;;; Lists (define-constant +opcode-get-list+ 32) (define-constant +opcode-put-list+ 33) ;;;; Debug Config (defparameter *off-by-one* nil)