New procedure (bytevector-zero-explicit! <bv> [<start> [<end>]]).
authorTaylor R Campbell <campbell@mumble.net>
Wed, 7 Nov 2018 05:33:52 +0000 (05:33 +0000)
committerTaylor R Campbell <campbell@mumble.net>
Wed, 7 Nov 2018 05:33:52 +0000 (05:33 +0000)
Intended to zero the memory backing a bytevector even if the values
will never be used again and an aggressively optimizing compiler can
prove that.

Doesn't actually work (GC can move stuff without zeroing it) but it
may help to have it in order to tag where it _would_ be needed if we
could make it work in the future.

src/runtime/bytevector.scm
src/runtime/runtime.pkg
tests/runtime/test-bytevector.scm

index 6ab44e1fd286af668303492156c09064c3410be7..23080deb623eee7e4a2a7789376777edc91159ce 100644 (file)
@@ -79,6 +79,10 @@ USA.
    (if (default-object? start) 0 start)
    (if (default-object? end) (bytevector-length bytevector) end)))
 
+(define (bytevector-zero-explicit! bytevector #!optional start end)
+  ;; Don't let any compiler optimize this away.
+  ((identity-procedure bytevector-fill!) bytevector 0 start end))
+
 (define (bytevector-copy bytevector #!optional start end)
   ((ucode-primitive bytevector-copy 3)
    bytevector
index fdd05d79f33f4fcac5d54540fd3f0d3a820ef3e7..cd40c1ba0e3274b188472ee038b246a094a787c3 100644 (file)
@@ -1178,6 +1178,7 @@ USA.
          bytevector-u32le-set!
          bytevector-u8-ref
          bytevector-u8-set!
+         bytevector-zero-explicit!
          bytevector=?
          bytevector?
          exact-nonnegative-integer->bytevector
index 0226880f6fe2b2dcc2f128c2da4ecbd296d27441..e78c70c1c827c83145e8e9cb6a9c76a259170e26 100644 (file)
@@ -180,6 +180,27 @@ USA.
        (lambda ()
         (bytevector-fill! (make-bytevector n) 51 -1 n))))))
 
+(define-test 'bytevector-zero-explicit!
+  ;; Can't really test what we want here -- that the bytevector is
+  ;; zero'd in memory even if the compiler can prove its value is not
+  ;; used afterward.  Worse, we can't even really guarantee this,
+  ;; because the GC might have copied it already and we have no way to
+  ;; zero the original.
+  (lambda ()
+    (let ((bv (make-bytevector 3 #xff)))
+      (bytevector-zero-explicit! bv 1 2)
+      (assert-= (bytevector-u8-ref bv 0) #xff)
+      (assert-= (bytevector-u8-ref bv 1) 0)
+      (assert-= (bytevector-u8-ref bv 2) #xff)
+      (bytevector-zero-explicit! bv 1)
+      (assert-= (bytevector-u8-ref bv 0) #xff)
+      (assert-= (bytevector-u8-ref bv 1) 0)
+      (assert-= (bytevector-u8-ref bv 2) 0)
+      (bytevector-zero-explicit! bv 0)
+      (assert-= (bytevector-u8-ref bv 0) 0)
+      (assert-= (bytevector-u8-ref bv 1) 0)
+      (assert-= (bytevector-u8-ref bv 2) 0))))
+
 (define (test-bytevector-properties v bytes)
   (assert-true (bytevector? v))
   (assert-= (bytevector-length v) (length bytes))