1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-07-04 16:50:25 +02:00

align programs on 8-byte boundaries

* module/language/assembly.scm (addr+): New helper.
  (align-program): New function, aligns a (load-program) form, currently
  to 8-byte boundaries.

* module/language/glil/compile-assembly.scm (<subprogram>): Record the
  object table and the program code separately, so that we can align the
  program after the object table has been written.
  (glil->assembly): Use addr+.
  (dump-object): Rework to fold `addr' through dumping of compound
  objects, so that procedures can be aligned properly.
This commit is contained in:
Andy Wingo 2009-02-14 19:50:44 +01:00
parent 194566b0ec
commit 2cf1705c72
2 changed files with 71 additions and 48 deletions

View file

@ -22,7 +22,9 @@
(define-module (language assembly) (define-module (language assembly)
#:use-module (system base pmatch) #:use-module (system base pmatch)
#:use-module (system vm instruction) #:use-module (system vm instruction)
#:use-module ((srfi srfi-1) #:select (fold))
#:export (byte-length #:export (byte-length
addr+ align-program
assembly-pack assembly-unpack assembly-pack assembly-unpack
object->assembly assembly->object)) object->assembly assembly->object))
@ -54,6 +56,21 @@
(+ 1 (instruction-length inst))) (+ 1 (instruction-length inst)))
(else (error "unknown instruction" assembly)))) (else (error "unknown instruction" assembly))))
(define *program-alignment* 8)
(define (addr+ addr code)
(fold (lambda (x len) (+ (byte-length x) len))
addr
code))
(define (align-program prog addr)
`(,@(make-list (modulo (- *program-alignment*
(modulo addr *program-alignment*))
*program-alignment*)
'(nop))
,prog))
;;; ;;;
;;; Code compress/decompression ;;; Code compress/decompression
;;; ;;;

View file

@ -39,9 +39,10 @@
(define-record <variable-cache-cell> key) (define-record <variable-cache-cell> key)
;; Subprograms can be loaded into an object table as well. We need a ;; Subprograms can be loaded into an object table as well. We need a
;; disjoint type here too. ;; disjoint type here too. (Subprograms have their own object tables --
;; though probably we should just make one table per compilation unit.)
(define-record <subprogram> code) (define-record <subprogram> table prog)
(define (limn-sources sources) (define (limn-sources sources)
@ -162,8 +163,7 @@
source-alist label-alist object-alist addr) source-alist label-alist object-alist addr)
(lp (cdr body) (append (reverse subcode) code) (lp (cdr body) (append (reverse subcode) code)
bindings source-alist label-alist object-alist bindings source-alist label-alist object-alist
(fold (lambda (x len) (+ (byte-length x) len)) (addr+ addr subcode))))))))
addr subcode))))))))
(receive (code bindings sources labels objects len) (receive (code bindings sources labels objects len)
(process-body) (process-body)
@ -185,7 +185,7 @@
;; if we are being compiled from something with an object ;; if we are being compiled from something with an object
;; table, cache the program there ;; table, cache the program there
(receive (i object-alist) (receive (i object-alist)
(object-index-and-alist (make-subprogram `(,@table ,prog)) (object-index-and-alist (make-subprogram table prog)
object-alist) object-alist)
(emit-code/object `((object-ref ,i) ,@closure) (emit-code/object `((object-ref ,i) ,@closure)
object-alist))) object-alist)))
@ -326,17 +326,17 @@
((<glil-mv-call> nargs ra) ((<glil-mv-call> nargs ra)
(emit-code `((mv-call ,nargs ,ra)))))) (emit-code `((mv-call ,nargs ,ra))))))
;; addr is currently unused, but could be used to align data in the
;; instruction stream.
(define (dump-object x addr) (define (dump-object x addr)
(define (too-long x) (define (too-long x)
(error (string-append x " too long"))) (error (string-append x " too long")))
(let dump ((x x))
(cond (cond
((object->assembly x) => list) ((object->assembly x) => list)
((variable-cache-cell? x) (dump (variable-cache-cell-key x))) ((variable-cache-cell? x) (dump-object (variable-cache-cell-key x) addr))
((subprogram? x) (subprogram-code x)) ((subprogram? x)
`(,@(subprogram-table x)
,@(align-program (subprogram-prog x)
(addr+ addr (subprogram-table x)))))
((and (integer? x) (exact? x)) ((and (integer? x) (exact? x))
(let ((str (do ((n x (quotient n 256)) (let ((str (do ((n x (quotient n 256))
(l '() (cons (modulo n 256) l))) (l '() (cons (modulo n 256) l)))
@ -352,25 +352,31 @@
((keyword? x) ((keyword? x)
`((load-keyword ,(symbol->string (keyword->symbol x))))) `((load-keyword ,(symbol->string (keyword->symbol x)))))
((list? x) ((list? x)
(fold append (let ((tail (let ((len (length x)))
(let ((len (length x)))
(if (>= len 65536) (too-long "list")) (if (>= len 65536) (too-long "list"))
`((list ,(quotient len 256) ,(modulo len 256)))) `((list ,(quotient len 256) ,(modulo len 256))))))
(fold (lambda (x y) (cons (dump x) y)) (let dump-objects ((objects x) (codes '()) (addr addr))
'() (if (null? objects)
x))) (fold append tail codes)
(let ((code (dump-object (car objects) addr)))
(dump-objects (cdr objects) (cons code codes)
(addr+ addr code)))))))
((pair? x) ((pair? x)
`(,@(dump (car x)) (let ((kar (dump-object (car x) addr)))
,@(dump (cdr x)) `(,@kar
(cons))) ,@(dump-object (cdr x) (addr+ addr kar))
(cons))))
((vector? x) ((vector? x)
(fold append (let* ((len (vector-length x))
(let ((len (vector-length x))) (tail (if (>= len 65536)
(if (>= len 65536) (too-long "vector")) (too-long "vector")
`((vector ,(quotient len 256) ,(modulo len 256)))) `((vector ,(quotient len 256) ,(modulo len 256))))))
(fold (lambda (x y) (cons (dump x) y)) (let dump-objects ((i 0) (codes '()) (addr addr))
'() (if (>= i len)
(vector->list x)))) (fold append tail codes)
(let ((code (dump-object (vector-ref x i) addr)))
(dump-objects (1+ i) (cons code codes)
(addr+ addr code)))))))
(else (else
(error "assemble: unrecognized object" x))))) (error "assemble: unrecognized object" x))))