From 26e79e2a89a0a63aba179176329f09f9c0412b5f Mon Sep 17 00:00:00 2001 From: Chris Hanson Date: Sat, 20 Jun 2009 01:02:11 -0700 Subject: [PATCH] Fix closure structure so that first entry is word-aligned. --- src/compiler/machines/svm/machine.scm | 72 +++------------------------ src/microcode/cmpintmd/svm1.c | 32 ++++++------ src/microcode/cmpintmd/svm1.h | 6 ++- 3 files changed, 29 insertions(+), 81 deletions(-) diff --git a/src/compiler/machines/svm/machine.scm b/src/compiler/machines/svm/machine.scm index 12488c188..10c51e873 100644 --- a/src/compiler/machines/svm/machine.scm +++ b/src/compiler/machines/svm/machine.scm @@ -147,16 +147,16 @@ USA. ;; See microcode/cmpintmd/svm1.c for a description of the layout. ;; Offset of the first object in the closure from the address of the -;; first closure entry point, in words. +;; first closure entry point, in words. In order to make this work, +;; we add padding to the closure-count field so that the first entry +;; is aligned on an object boundary. (define (closure-first-offset count entry) entry (if (= count 0) 1 - ;; This returns the offset in bytes, it isn't necessarily in words. - (receive (entries entries-size padding-size) (make-closure-entries count) - entries-size padding-size - (+ 2 (car (car entries)))))) + (+ (integer-ceiling (* count 3) address-units-per-object) + count))) ;; Offset of the first object in the closure from the address of the ;; manifest-closure header word, in words. @@ -164,71 +164,15 @@ USA. (define (closure-object-first-offset count) (if (= count 0) 1 - (receive (entries entries-size padding-size) (make-closure-entries count) - entries - (quotient (+ 2 entries-size padding-size) - address-units-per-object)))) + (+ 2 (closure-first-offset count 0)))) ;; Increment from one closure entry address to another, in bytes. (define (closure-entry-distance count entry entry*) - (* 10 (- entry* entry))) + (* 3 (- entry* entry))) ;; Increment from a given closure address to the first closure ;; address, in bytes. Usually negative. (define (closure-environment-adjustment count entry) - (closure-entry-distance count entry 0)) - - -;; This could get stuck toggling between two states. It's probably -;; not worth running the ITERATION loop more than a couple of times. -(define (make-closure-entries count) - (let ((last (- count 1)) - (initial-padding (padding-size (* count 9)))) - (let ((entries - (reverse! - (make-initialized-list count - (lambda (i) - (cons (+ (* (- last i) 9) - initial-padding - (* i 4)) - 9)))))) - (let iteration ((padding initial-padding)) - (let loop ((entries entries)) - (if (pair? entries) - (let ((entry (car entries)) - (entries (cdr entries))) - (let ((size* (offset->entry-size (car entry))) - (size (cdr entry))) - (if (not (= size* size)) - (begin - (set-cdr! entry size*) - (adjust-entries! entries (- size size*))))) - (loop entries)))) - (let ((entries-size (entries-size entries))) - (let ((padding* (padding-size entries-size))) - (if (not (= padding* padding)) - (begin - (adjust-entries! entries (- padding padding*)) - (iteration padding*)) - (values (map car (reverse! entries)) - entries-size - padding)))))))) - -(define (entries-size entries) - (reduce + 0 (map cdr entries))) - -(define (padding-size entries-size) - (let ((entries-size (+ entries-size 2))) - (- (* (integer-ceiling entries-size 4) 4) entries-size))) - -(define (offset->entry-size offset) - (cond ((< offset #x100) 6) - ((< offset #x10000) 7) - (else 9))) - -(define (adjust-entries! entries delta) - (for-each (lambda (entry) - (set-car! entry (- (car entry) delta))) - entries)) \ No newline at end of file + (closure-entry-distance count entry 0)) \ No newline at end of file diff --git a/src/microcode/cmpintmd/svm1.c b/src/microcode/cmpintmd/svm1.c index 5ec801c67..183370cc0 100644 --- a/src/microcode/cmpintmd/svm1.c +++ b/src/microcode/cmpintmd/svm1.c @@ -224,28 +224,30 @@ write_u16 (unsigned int n, insn_t * address) For example, on a 32-bit machine with count == 3 and 4 value cells: - 0x00 TC_MANIFEST_CLOSURE | n_words == 11 + 0x00 TC_MANIFEST_CLOSURE | n_words == 12 + 0x04 count == 3 + 0x06 2 padding bytes (next address must be word-aligned) - 0x06 SVM1_INST_ENTER_CLOSURE - 0x07 index == 0 + 0x08 SVM1_INST_ENTER_CLOSURE + 0x09 index == 0 - 0x09 SVM1_INST_ENTER_CLOSURE - 0x0A index == 1 + 0x0B SVM1_INST_ENTER_CLOSURE + 0x0C index == 1 - 0x0C SVM1_INST_ENTER_CLOSURE - 0x0D index == 2 + 0x0E SVM1_INST_ENTER_CLOSURE + 0x0F index == 2 - 0x0F 1 padding byte + 0x11 3 padding bytes (next address must be word-aligned) - 0x10 target 0 - 0x14 target 1 - 0x18 target 2 + 0x14 target 0 + 0x18 target 1 + 0x1C target 2 - 0x1C value cell 0 - 0x20 value cell 1 - 0x24 value cell 2 - 0x28 value cell 3 + 0x20 value cell 0 + 0x24 value cell 1 + 0x28 value cell 2 + 0x2C value cell 3 */ diff --git a/src/microcode/cmpintmd/svm1.h b/src/microcode/cmpintmd/svm1.h index 4ddf04cf7..732336c6f 100644 --- a/src/microcode/cmpintmd/svm1.h +++ b/src/microcode/cmpintmd/svm1.h @@ -46,8 +46,10 @@ typedef byte_t insn_t; instructions are stored. */ #define CC_ENTRY_GC_TRAP_SIZE 0 -/* Size of closure count in insn_t units. */ -#define CLOSURE_COUNT_SIZE 2 +/* Size of closure count in insn_t units. Only first two bytes + contain the count, but we must add padding to move the first entry + to a word boundary. */ +#define CLOSURE_COUNT_SIZE SIZEOF_SCHEME_OBJECT /* Size of closure entry in insn_t units. */ #define CLOSURE_ENTRY_SIZE 3 -- 2.25.1