-
Notifications
You must be signed in to change notification settings - Fork 7
/
.patch-chez-gc-handler
executable file
·58 lines (50 loc) · 2.26 KB
/
.patch-chez-gc-handler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/bin/sh
# TODO to manage all the arguments one by one in the same way as the first
SS="$1"
if [ ! -r "$SS" ] && ! SS="$(pack app-path "$SS")_app/$SS.ss" || [ ! -r "$SS" ]; then
echo "Neither can't find a file '$1', nor a program with that name" >&2
exit 2
fi
# It is important that we search and replace only places where the `collect-request-handler`
# is set, and not generated, so that patched compiler would produce code as the original one.
# That's why we use `^` at the beginning of the pattern.
ORIG_CRH="^(collect-request-handler (lambda () (collect) (blodwen-run-finalisers)))"
if ! grep -q "$ORIG_CRH" "$SS"; then
echo "File '$SS' does not contain a handler to patch"
exit 0
fi
CRH="(collect-request-handler
(let* ([gc-counter 1]
[log-radix 2]
[radix-mask (sub1 (bitwise-arithmetic-shift 1 log-radix))]
[major-gc-factor 2]
[trigger-major-gc-allocated (* major-gc-factor (bytes-allocated))])
(lambda ()
(cond
[(>= (bytes-allocated) trigger-major-gc-allocated)
;; Force a major collection if memory use has doubled
(collect (collect-maximum-generation))
(blodwen-run-finalisers)
(set! trigger-major-gc-allocated (* major-gc-factor (bytes-allocated)))]
[else
;; Imitate the built-in rule, but without ever going to a major collection
(let ([this-counter gc-counter])
(if (> (add1 this-counter)
(bitwise-arithmetic-shift-left 1 (* log-radix (sub1 (collect-maximum-generation)))))
(set! gc-counter 1)
(set! gc-counter (add1 this-counter)))
(collect
;; Find the minor generation implied by the counter
(let loop ([c this-counter] [gen 0])
(cond
[(zero? (bitwise-and c radix-mask))
(loop (bitwise-arithmetic-shift-right c log-radix)
(add1 gen))]
[else
gen]))))]))))"
CRH="$(echo "$CRH" | tr '\n' '|' | sed 's/|/\\n/g')"
set -e # Now each falling command stops the script
echo "Patching '$SS'..."
sed -i "s/$ORIG_CRH/$CRH/" "$SS"
printf "Compiling the patched version... "
(echo "(parameterize ([optimize-level 3] [compile-file-message #f]) (compile-program \"$SS\"))" | chezscheme -q | sed 's/()/done/')