Replace std/gif's use of since_mark

name                                        old speed      new speed      delta

wuffs_gif_decode_1k_bw/clang5                380MB/s ± 1%   407MB/s ± 1%  +7.09%  (p=0.000 n=10+10)
wuffs_gif_decode_1k_color_full_init/clang5   137MB/s ± 0%   140MB/s ± 1%  +1.87%  (p=0.000 n=10+10)
wuffs_gif_decode_1k_color_part_init/clang5   182MB/s ± 1%   185MB/s ± 1%  +1.50%  (p=0.000 n=10+10)
wuffs_gif_decode_10k_bgra/clang5             736MB/s ± 1%   736MB/s ± 0%    ~     (p=0.696 n=10+8)
wuffs_gif_decode_10k_indexed/clang5          199MB/s ± 1%   198MB/s ± 0%  -0.45%  (p=0.021 n=10+8)
wuffs_gif_decode_20k/clang5                  246MB/s ± 0%   244MB/s ± 1%  -0.61%  (p=0.011 n=10+10)
wuffs_gif_decode_100k_artificial/clang5      541MB/s ± 1%   540MB/s ± 1%    ~     (p=0.579 n=10+10)
wuffs_gif_decode_100k_realistic/clang5       222MB/s ± 0%   222MB/s ± 0%    ~     (p=0.481 n=10+10)
wuffs_gif_decode_1000k_full_init/clang5      226MB/s ± 1%   225MB/s ± 0%  -0.40%  (p=0.035 n=10+10)
wuffs_gif_decode_1000k_part_init/clang5      226MB/s ± 0%   226MB/s ± 0%  -0.23%  (p=0.013 n=10+9)
wuffs_gif_decode_anim_screencap/clang5      1.07GB/s ± 1%  1.07GB/s ± 0%    ~     (p=0.089 n=10+10)

wuffs_gif_decode_1k_bw/gcc7                  438MB/s ± 1%   459MB/s ± 0%  +4.67%  (p=0.000 n=10+9)
wuffs_gif_decode_1k_color_full_init/gcc7     136MB/s ± 1%   139MB/s ± 0%  +2.25%  (p=0.000 n=10+9)
wuffs_gif_decode_1k_color_part_init/gcc7     177MB/s ± 1%   180MB/s ± 1%  +1.66%  (p=0.000 n=10+10)
wuffs_gif_decode_10k_bgra/gcc7               612MB/s ± 1%   615MB/s ± 1%  +0.57%  (p=0.022 n=10+9)
wuffs_gif_decode_10k_indexed/gcc7            192MB/s ± 0%   193MB/s ± 1%  +0.38%  (p=0.022 n=10+9)
wuffs_gif_decode_20k/gcc7                    234MB/s ± 0%   234MB/s ± 1%    ~     (p=0.631 n=10+10)
wuffs_gif_decode_100k_artificial/gcc7        499MB/s ± 1%   497MB/s ± 1%  -0.48%  (p=0.011 n=10+10)
wuffs_gif_decode_100k_realistic/gcc7         203MB/s ± 0%   203MB/s ± 0%    ~     (p=0.489 n=9+9)
wuffs_gif_decode_1000k_full_init/gcc7        207MB/s ± 0%   206MB/s ± 0%  -0.27%  (p=0.010 n=8+8)
wuffs_gif_decode_1000k_part_init/gcc7        207MB/s ± 1%   207MB/s ± 1%    ~     (p=0.604 n=10+9)
wuffs_gif_decode_anim_screencap/gcc7        1.03GB/s ± 1%  1.03GB/s ± 1%    ~     (p=0.968 n=10+9)
diff --git a/internal/cgen/builtin.go b/internal/cgen/builtin.go
index 40848b7..9b43902 100644
--- a/internal/cgen/builtin.go
+++ b/internal/cgen/builtin.go
@@ -135,6 +135,11 @@
 
 func (g *gen) writeBuiltinIOReader(b *buffer, recv *a.Expr, method t.ID, args []*a.Node, depth uint32) error {
 	// TODO: don't hard-code the recv being a_src.
+	prefix, name := aPrefix, "src"
+	if recv.Operator() == 0 {
+		prefix, name = vPrefix, recv.Ident().Str(g.tm)
+	}
+
 	switch method {
 	case t.IDUndoByte:
 		b.writes("(iop_a_src--, wuffs_base__make_empty_struct())")
@@ -145,15 +150,16 @@
 		return nil
 
 	case t.IDCountSince:
-		b.printf("(a_src.private_impl.buf ? wuffs_base__io__count_since(")
+		b.printf("(%s%s.private_impl.buf ? wuffs_base__io__count_since(", prefix, name)
 		if err := g.writeExpr(b, args[0].AsArg().Value(), depth); err != nil {
 			return err
 		}
-		b.printf(", iop_a_src - a_src.private_impl.buf->data.ptr) : 0)")
+		b.printf(", iop_%s%s - %s%s.private_impl.buf->data.ptr) : 0)", prefix, name, prefix, name)
 		return nil
 
 	case t.IDMark:
-		b.printf("(a_src.private_impl.buf ? ((uint64_t)(iop_a_src - a_src.private_impl.buf->data.ptr)) : 0)")
+		b.printf("(%s%s.private_impl.buf ? ((uint64_t)(iop_%s%s - %s%s.private_impl.buf->data.ptr)) : 0)",
+			prefix, name, prefix, name, prefix, name)
 		return nil
 
 	case t.IDPosition:
@@ -171,19 +177,16 @@
 		return nil
 
 	case t.IDSince:
-		b.printf("(a_src.private_impl.buf ? wuffs_base__io__since(")
+		b.printf("(%s%s.private_impl.buf ? wuffs_base__io__since(", prefix, name)
 		if err := g.writeExpr(b, args[0].AsArg().Value(), depth); err != nil {
 			return err
 		}
-		b.printf(", iop_a_src - a_src.private_impl.buf->data.ptr, a_src.private_impl.buf->data.ptr) : wuffs_base__make_slice_u8(NULL, 0))")
+		b.printf(", iop_%s%s - %s%s.private_impl.buf->data.ptr, %s%s.private_impl.buf->data.ptr)"+
+			": wuffs_base__make_slice_u8(NULL, 0))",
+			prefix, name, prefix, name, prefix, name)
 		return nil
 
 	case t.IDSinceMark, t.IDSinceMarkLength:
-		prefix, name := aPrefix, "src"
-		if recv.Operator() == 0 {
-			prefix, name = vPrefix, recv.Ident().Str(g.tm)
-		}
-
 		if method == t.IDSinceMark {
 			b.printf("wuffs_base__make_slice_u8(%s%s.private_impl.mark, (size_t)(", prefix, name)
 		}
@@ -230,6 +233,11 @@
 
 func (g *gen) writeBuiltinIOWriter(b *buffer, recv *a.Expr, method t.ID, args []*a.Node, depth uint32) error {
 	// TODO: don't hard-code the recv being a_dst or w.
+	prefix, name := aPrefix, "dst"
+	if recv.Operator() == 0 {
+		prefix, name = vPrefix, recv.Ident().Str(g.tm)
+	}
+
 	switch method {
 	case t.IDCopyNFromHistory, t.IDCopyNFromHistoryFast:
 		suffix := ""
@@ -299,11 +307,6 @@
 		return nil
 
 	case t.IDSinceMark, t.IDSinceMarkLength:
-		prefix, name := aPrefix, "dst"
-		if recv.Operator() == 0 {
-			prefix, name = vPrefix, recv.Ident().Str(g.tm)
-		}
-
 		if method == t.IDSinceMark {
 			b.printf("wuffs_base__make_slice_u8(%s%s.private_impl.mark, (size_t)(", prefix, name)
 		}
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index b07b06f..c5e9a9b 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -11087,6 +11087,7 @@
       wuffs_base__null_io_buffer();
   uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
   uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+  uint64_t v_mark = 0;
   wuffs_base__status v_lzw_status = NULL;
   wuffs_base__status v_copy_status = NULL;
   wuffs_base__slice_u8 v_uncompressed = {0};
@@ -11194,6 +11195,9 @@
                                             4096),
                   self->private_impl.f_compressed_ri,
                   self->private_impl.f_compressed_wi));
+          v_mark = (v_r.private_impl.buf
+                        ? ((uint64_t)(iop_v_r - v_r.private_impl.buf->data.ptr))
+                        : 0);
           {
             u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr));
             wuffs_base__status t_1 = wuffs_lzw__decoder__decode_io_writer(
@@ -11205,7 +11209,10 @@
           }
           wuffs_base__u64__sat_add_indirect(
               &self->private_impl.f_compressed_ri,
-              ((uint64_t)(iop_v_r - v_r.private_impl.mark)));
+              (v_r.private_impl.buf
+                   ? wuffs_base__io__count_since(
+                         v_mark, iop_v_r - v_r.private_impl.buf->data.ptr)
+                   : 0));
           v_r = o_0_v_r;
           iop_v_r = o_0_iop_v_r;
           io1_v_r = o_0_io1_v_r;
diff --git a/std/gif/decode_gif.wuffs b/std/gif/decode_gif.wuffs
index b96ccee..203f3e0 100644
--- a/std/gif/decode_gif.wuffs
+++ b/std/gif/decode_gif.wuffs
@@ -988,6 +988,7 @@
 	var n_compressed    base.u64
 	var compressed      slice base.u8
 	var r               base.io_reader
+	var mark            base.u64
 	var lzw_status      base.status
 	var copy_status     base.status
 	var uncompressed    slice base.u8
@@ -1038,9 +1039,10 @@
 				return "#internal error: inconsistent ri/wi"
 			}
 			io_bind (io:r, data:this.compressed[this.compressed_ri:this.compressed_wi]) {
+				mark = r.mark()
 				lzw_status =? this.lzw.decode_io_writer?(
 					dst:this.util.null_io_writer(), src:r, workbuf:this.util.null_slice_u8())
-				this.compressed_ri ~sat+= r.since_mark().length()
+				this.compressed_ri ~sat+= r.count_since(mark:mark)
 			}
 
 			uncompressed = this.lzw.flush!()