Skip to content

Commit 3da0c31

Browse files
committed
moved expose-allocation to before flatten
1 parent ef013b4 commit 3da0c31

File tree

12 files changed

+251
-171
lines changed

12 files changed

+251
-171
lines changed

conditionals.rkt

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
(define tmp (gensym 'if))
153153
(define thn-ret `(assign ,tmp ,new-thn))
154154
(define els-ret `(assign ,tmp ,new-els))
155-
(values `(has-type ,tmp ,t)
155+
(values tmp
156156
(append e1-ss e2-ss
157157
`((if (,cmp ,new-e1 ,new-e2)
158158
,(append thn-ss (list thn-ret))
@@ -165,9 +165,9 @@
165165
(define tmp (gensym 'if))
166166
(define thn-ret `(assign ,tmp ,new-thn))
167167
(define els-ret `(assign ,tmp ,new-els))
168-
(values `(has-type ,tmp ,t)
168+
(values tmp
169169
(append cnd-ss
170-
`((if (eq? (has-type #t Boolean) ,new-cnd)
170+
`((if (eq? #t ,new-cnd)
171171
,(append thn-ss (list thn-ret))
172172
,(append els-ss (list els-ret)))))
173173
(cons tmp (append xs1 xs))
@@ -178,51 +178,53 @@
178178
(lambda (e)
179179
(verbose "flatten" e)
180180
(match e
181-
;; For atomic stuff, we keep the has-type annotation. -Jeremy
182-
[`(has-type (void) ,t)
183-
(values `(has-type (void) ,t) '() '())]
184-
[`(has-type ,e1 ,t)
185-
#:when (or (symbol? e1) (integer? e1) (boolean? e1))
186-
(values `(has-type ,e1 ,t) '() '())]
181+
;; [`(has-type (void) ,t)
182+
;; (values `(void) '() '())]
183+
;; [`(has-type ,e1 ,t)
184+
;; #:when (or (symbol? e1) (integer? e1) (boolean? e1))
185+
;; (values e1 '() '())]
186+
187+
[(? boolean?) (values e '() '())]
187188

188-
;; We override 'and' to place has-type's around the #t and #f
189-
;; in the generated code. -Jeremy
190-
[`(has-type (and ,e1 ,e2) ,t)
189+
[`(and ,e1 ,e2)
191190
(define-values (new-e1 e1-ss xs1) ((flatten #t) e1))
192191
(define-values (new-e2 e2-ss xs2) ((flatten #f) e2))
193192
(define tmp (gensym 'and))
194-
(values `(has-type ,tmp ,t)
193+
(values tmp
195194
(append e1-ss
196-
`((if (eq? (has-type #t Boolean) ,new-e1)
195+
`((if (eq? #t ,new-e1)
197196
,(append e2-ss `((assign ,tmp ,new-e2)))
198-
((assign ,tmp (has-type #f Boolean))))))
197+
((assign ,tmp #f)))))
199198
(cons tmp (append xs1 xs2))
200199
)]
201-
200+
202201
;; We override flattening for op's because we
203202
;; need to put a has-type on the LHS of the assign. -Jeremy
204-
[`(has-type (,op ,es ...) ,t) #:when (set-member? (primitives) op)
205-
(define-values (new-es sss xss) (map3 (flatten #t) es))
206-
(define ss (append* sss))
207-
(define xs (append* xss))
208-
(define prim-apply `(,op ,@new-es))
209-
(cond
210-
[need-atomic
211-
(define tmp (gensym 'tmp))
212-
(values `(has-type ,tmp ,t)
213-
(append ss `((assign ,tmp (has-type ,prim-apply ,t))))
214-
(cons tmp xs) )]
215-
[else (values `(has-type ,prim-apply ,t) ss xs)])]
203+
;; [`(has-type (,op ,es ...) ,t) #:when (set-member? (primitives) op)
204+
;; (define-values (new-es sss xss) (map3 (flatten #t) es))
205+
;; (define ss (append* sss))
206+
;; (define xs (append* xss))
207+
;; (define prim-apply `(,op ,@new-es))
208+
;; (cond
209+
;; [need-atomic
210+
;; (define tmp (gensym 'tmp))
211+
;; (values tmp
212+
;; (append ss `((assign ,tmp ,prim-apply)))
213+
;; (cons tmp xs) )]
214+
;; [else (values prim-apply ss xs)])]
216215

217216
;; For 'let' we just need to strip the enclosing has-type. -Jeremy
218-
[`(has-type (let ([,x ,rhs]) ,body) ,t)
219-
((flatten need-atomic) `(let ([,x ,rhs]) ,body))]
217+
;; [`(has-type (let ([,x ,rhs]) ,body) ,t)
218+
;; ((flatten need-atomic) `(let ([,x ,rhs]) ,body))]
220219

221-
[`(has-type (if ,cnd ,thn ,els) ,t)
220+
[`(if ,cnd ,thn ,els)
222221
(define-values (new-thn thn-ss xs1) ((flatten #t) thn))
223222
(define-values (new-els els-ss xs2) ((flatten #t) els))
224223
((flatten-if new-thn thn-ss new-els els-ss (append xs1 xs2)) cnd)]
225224

225+
[`(has-type ,e1 ,t)
226+
((flatten need-atomic) e1)]
227+
226228
[`(program ,body)
227229
(define-values (new-body ss xs) ((flatten #t) body))
228230
`(program ,xs ,@(append ss `((return ,new-body))))]
@@ -265,7 +267,6 @@
265267
(define/override (select-instructions)
266268
(lambda (e)
267269
(match e
268-
[`(has-type ,e ,t) ((select-instructions) e)]
269270
[#t `(int 1)]
270271
[#f `(int 0)]
271272
[`(assign ,lhs (has-type ,rhs ,t))
@@ -284,8 +285,9 @@
284285
[`(assign ,lhs (,cmp ,e1 ,e2))
285286
#:when (set-member? (comparison-ops) cmp)
286287
(define new-lhs ((select-instructions) lhs))
287-
(define new-e1 ((select-instructions) e1))
288-
(define new-e2 ((select-instructions) e2))
288+
;; swap operands because the ordering for x86 cmpq is weird -Jeremy
289+
(define new-e1 ((select-instructions) e2))
290+
(define new-e2 ((select-instructions) e1))
289291
;; second operand of cmpq can't be an immediate
290292
(define comparison
291293
(cond [(and (immediate? new-e1) (immediate? new-e2))
@@ -439,7 +441,8 @@
439441
[els-ss (append* (map (lower-conditionals) els-ss))]
440442
[thn-label (gensym 'then)]
441443
[end-label (gensym 'if_end)])
442-
(append `((cmpq ,a1 ,a2))
444+
;; Switch ordering because x86 cmpq instruction is wierd -Jeremy
445+
(append `((cmpq ,a2 ,a1))
443446
`((jmp-if ,(compare->cc cmp) ,thn-label))
444447
els-ss `((jmp ,end-label))
445448
`((label ,thn-label)) thn-ss `((label ,end-label))

functions.rkt

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,26 +177,25 @@
177177
;; This pass has to thread a new environment through that isn't extended
178178
;; This could be overcome with pointers or we could use
179179

180-
(inherit expose-allocation-seq)
180+
; (inherit expose-allocation-seq)
181181
(define/override (expose-allocation)
182182
(lambda (prog)
183183
(match prog
184184
[`(program (,xs ...) (type ,ty)
185185
(defines ,(app expose-allocation-def ds) ...)
186-
,ss ...)
187-
(let ([ss (expose-allocation-seq ss)])
186+
,e)
187+
(let ([new-e (expose-allocation e)])
188188
`(program ,(append (reset-vars) xs)
189189
(type ,ty)
190190
(defines ,@ds)
191-
(initialize ,(rootstack-size) ,(heap-size))
192-
,@ss))]
191+
,new-e))]
193192
[else (error 'expose-allocation "unmatched ~a" prog)])))
194193

195194
(define/public (expose-allocation-def def)
196195
(match def
197196
[`(define (,f ,p:t* ...) : ,t (,l* ...)
198-
. ,(app expose-allocation-seq ss))
199-
`(define (,f ,@p:t*) : ,t ,(append (reset-vars) l*) ,@ss)]
197+
. ,(app expose-allocation e))
198+
`(define (,f ,@p:t*) : ,t ,(append (reset-vars) l*) ,e)]
200199
[else (error 'expose-allocation-def "unmatched ~a" def)]))
201200

202201
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -564,10 +563,10 @@
564563
,(send interp interp-scheme '()))
565564
("reveal-functions" ,(send compiler reveal-functions '())
566565
,(send interp interp-F '()))
567-
("flatten" ,(send compiler flatten #f)
568-
,(send interp interp-C '()))
569566
("expose allocation"
570567
,(send compiler expose-allocation)
568+
,(send interp interp-F '()))
569+
("flatten" ,(send compiler flatten #f)
571570
,(send interp interp-C '()))
572571
("uncover call live roots"
573572
,(send compiler uncover-call-live-roots)

interp.rkt

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,17 @@
177177

178178
(define/override (primitives)
179179
(set-union (super primitives)
180-
(set 'eq? 'and 'or 'not)))
180+
(set 'eq? 'and 'not '< '<= '> '>=)))
181181

182182
(define/override (interp-op op)
183183
(match op
184184
['eq? (lambda (v1 v2)
185185
(cond [(and (fixnum? v1) (fixnum? v2)) (eq? v1 v2)]
186186
[(and (boolean? v1) (boolean? v2)) (eq? v1 v2)]))]
187+
['and (lambda (v1 v2)
188+
(cond [(and (boolean? v1) (boolean? v2))
189+
(and v1 v2)]))]
190+
['not (lambda (v) (match v [#t #f] [#f #t]))]
187191
['< (lambda (v1 v2)
188192
(cond [(and (fixnum? v1) (fixnum? v2)) (< v1 v2)]))]
189193
['<= (lambda (v1 v2)
@@ -192,10 +196,6 @@
192196
(cond [(and (fixnum? v1) (fixnum? v2)) (> v1 v2)]))]
193197
['>= (lambda (v1 v2)
194198
(cond [(and (fixnum? v1) (fixnum? v2)) (>= v1 v2)]))]
195-
['not (lambda (v) (match v [#t #f] [#f #t]))]
196-
['and (lambda (v1 v2)
197-
(cond [(and (boolean? v1) (boolean? v2))
198-
(and v1 v2)]))]
199199
[else (super interp-op op)]))
200200

201201
(define/override (interp-scheme env)
@@ -311,11 +311,15 @@
311311
(define sign (bitwise-and eflags #b000010000000))
312312
(if (= overflow sign) 1 0)]
313313
['le
314-
(or (eflags-status env 'e) (eflags-status env 'l))]
314+
(if (or (eq? 1 (eflags-status env 'e))
315+
(eq? 1 (eflags-status env 'l)))
316+
1 0)]
315317
['g
316-
(not (eflags-status env 'le))]
318+
(if (not (eq? 1 (eflags-status env 'le)))
319+
1 0)]
317320
['ge
318-
(not (eflags-status env 'l))]))
321+
(if (not (eq? 1 (eflags-status env 'l)))
322+
1 0)]))
319323

320324
(define/override (interp-x86 env)
321325
(lambda (ast)
@@ -325,6 +329,7 @@
325329
[`((set ,cc ,d) . ,ss)
326330
(define name (get-name d))
327331
(define val (eflags-status env cc))
332+
(verbose "set" cc val)
328333
((interp-x86 (cons (cons name val) env)) ss)]
329334
;; if's are present before patch-instructions
330335
[(or `((if ,cnd ,thn ,els) . ,ss)
@@ -335,11 +340,22 @@
335340

336341
[`((label ,l) . ,ss)
337342
((interp-x86 env) ss)]
338-
[`((cmpq ,s1 ,s2) . ,ss)
343+
344+
;; cmpq performs a subq operation and examimines the state
345+
;; of the result, this is done without overwriting the second
346+
;; register. -andre
347+
;; Notice that the syntax is very confusing
348+
;; (cmpq ,s2 ,s1) (jl then) (jmp else) ...
349+
;; (if (< s1 s2) then else)
350+
[`((cmpq ,s2 ,s1) . ,ss)
339351
(let* ([v1 ((interp-x86-exp env) s1)]
340-
[v2 ((interp-x86-exp env) s2)]
341-
[zero (arithmetic-shift (b2i (eq? v1 v2)) 6)]
342-
[eflags (bitwise-ior zero)])
352+
[v2 ((interp-x86-exp env) s2)]
353+
[v3 (- v2 v1)]
354+
[zero (arithmetic-shift (b2i (eq? v3 0)) 6)]
355+
[sign (arithmetic-shift (b2i (< v3 0)) 7)]
356+
;; Our numbers do not overflow so this bit is always 0
357+
[overflow (arithmetic-shift 0 11)]
358+
[eflags (bitwise-ior overflow sign zero)])
343359
((interp-x86 (cons (cons '__flag eflags) env)) ss))]
344360
[`((movzbq ,s ,d) . ,ss)
345361
(define x (get-name d))
@@ -390,6 +406,8 @@
390406
tys (range (length tys))))]
391407
[else (super display-by-type ty val)]))
392408

409+
;; Andre, please write a paragraph or so explaining this
410+
;; design for representing the heap. -Jeremy
393411

394412
;; The simulated global state of the program
395413
;; define produces private fields
@@ -428,33 +446,36 @@
428446

429447
(define/public (collect!)
430448
(lambda (rootset bytes-requested)
449+
(verbose "collect!" bytes-requested)
431450
;; after a call to collect we must guarantee there is enough
432451
;; memory to allocate the requested block of memory
433452
(let double-heap ([hs heap-size])
434453
(if (< hs bytes-requested)
435454
(double-heap (* 2 hs))
436-
(let ((h-begin (allocate! 'fromspace hs)))
455+
(let ((h-begin (allocate-page! 'fromspace hs)))
437456
;; I am only advancing the end of the heap because we
438457
;; are not reclaiming memory
439458
(set-box! fromspace_end (+ h-begin hs))
440459
(set-box! free_ptr h-begin))))))
441460

442461
(define/public (initialize!)
443462
(lambda (stack-length heap_length)
463+
(verbose "initialize!")
444464
(set-box! memory '())
445-
(let* ([s-begin (allocate! 'rootstack stack-size)]
446-
[h-begin (allocate! 'fromspace heap-size)])
465+
(let* ([s-begin (allocate-page! 'rootstack stack-size)]
466+
[h-begin (allocate-page! 'fromspace heap-size)])
447467
(set-box! rootstack_begin s-begin)
448468
(set-box! rootstack_end (+ s-begin stack-size))
449469
(set-box! fromspace_begin h-begin)
450470
(set-box! fromspace_end (+ h-begin heap-size))
451471
(set-box! free_ptr h-begin))))
452472

453-
(define (allocate! name size)
473+
(define (allocate-page! name size)
474+
(verbose "allocate-page!" name size)
454475
(unless (and (fixnum? size)
455476
(positive? size)
456477
(= 0 (modulo size 8)))
457-
(error 'allocate! "expected non-negative fixnum in ~a" size))
478+
(error 'allocate-page! "expected non-negative fixnum in ~a" size))
458479
;; Find the last address
459480
(define max-addr
460481
(for/fold ([next 8])
@@ -463,12 +484,13 @@
463484
(max next stop))))
464485
;; Allocate with a small pad 100 words so that it isn't likely to
465486
;; accidentally use another region.
466-
;; The randomness is to dispell any reliance on interp always allocating the
467-
;; same way. -Andre
487+
;; The randomness is to dispell any reliance on interp always allocating
488+
;; the same way. -Andre
468489
(define start-addr (+ max-addr 800))
469490
;; The range is of valid addresses in memory are [start, stop)
470491
(define stop-addr (+ start-addr size))
471492
(define vect (make-vector (arithmetic-shift size -3) uninitialized))
493+
(verbose "allocated" name start-addr stop-addr)
472494
(set-box! memory (cons `(page ,start-addr ,stop-addr ,name ,vect)
473495
(unbox memory)))
474496
start-addr)
@@ -529,6 +551,20 @@
529551
(verbose "R2/interp-scheme" ast)
530552
(match ast
531553
[`(void) (void)]
554+
[`(global-value free_ptr)
555+
(unbox free_ptr)]
556+
[`(global-value fromspace_end)
557+
(unbox fromspace_end)]
558+
[`(allocate ,l ,ty) (build-vector l (lambda a uninitialized))]
559+
[`(collect ,size)
560+
(unless (exact-nonnegative-integer? ((interp-scheme env) size))
561+
(error 'interp-C "invalid argument to collect in ~a" ast))
562+
(void)]
563+
[`(program (type ,ty) ,e)
564+
((interp-scheme '()) e)]
565+
[`(initialize ,stack-size ,heap-size)
566+
((initialize!) stack-size heap-size)
567+
(void)]
532568
[else ((super interp-scheme env) ast)]
533569
)))
534570

@@ -559,6 +595,10 @@
559595
(vomit "R2/interp-C" ast)
560596
(match ast
561597
[`(void) (void)]
598+
[`(global-value free_ptr)
599+
(unbox free_ptr)]
600+
[`(global-value fromspace_end)
601+
(unbox fromspace_end)]
562602
;; I should do better than make these noops - andre
563603
[`(initialize ,s ,h)
564604
(unless (and (exact-nonnegative-integer? s)
@@ -641,12 +681,12 @@
641681
(vomit "R2/interp-x86" (car ast)))
642682
(match ast
643683
;; cmpq performs a subq operation and examimines the state
644-
;; of the result, this is done without overiting the second
684+
;; of the result, this is done without overwriting the second
645685
;; register. -andre
646686
;; Notice that the syntax is very confusing
647687
;; (cmpq ,s2 ,s1) (jl then) (jmp else) ...
648688
;; (if (< s1 s2) then else)
649-
[`((cmpq ,s2 ,s1) . ,ss)
689+
#;[`((cmpq ,s2 ,s1) . ,ss)
650690
(let* ([v1 ((interp-x86-exp env) s1)]
651691
[v2 ((interp-x86-exp env) s2)]
652692
[v3 (- v2 v1)]
@@ -660,14 +700,16 @@
660700
[`((callq initialize) . ,ss)
661701
(define stack-size ((interp-x86-exp env) '(reg rdi)))
662702
(define heap-size ((interp-x86-exp env) '(reg rsi)))
663-
((initialize!) stack-size heap-size)
703+
((initialize!) stack-size heap-size)
664704
((interp-x86 env) ss)]
665705
[`((callq malloc) . ,ss)
666706
(define num-bytes ((interp-x86-exp env) '(reg rdi)))
667-
((interp-x86 `((rax . ,(allocate! 'malloc num-bytes)) . ,env)) ss)]
707+
((interp-x86 `((rax . ,(allocate-page! 'malloc num-bytes)) . ,env))
708+
ss)]
668709
[`((callq alloc) . ,ss)
669710
(define num-bytes ((interp-x86-exp env) '(reg rdi)))
670-
((interp-x86 `((rax . ,(allocate! 'alloc num-bytes)) . ,env)) ss)]
711+
((interp-x86 `((rax . ,(allocate-page! 'alloc num-bytes)) . ,env))
712+
ss)]
671713
[`((callq collect) . ,ss)
672714
(define rootstack ((interp-x86-exp env) '(reg rdi)))
673715
(define bytes-requested ((interp-x86-exp env) '(reg rsi)))

0 commit comments

Comments
 (0)