Ticket #1089: resizableintegerarray.patch2

File resizableintegerarray.patch2, 3.8 KB (added by kurahaupo, 5 years ago)

Implement (and test) zero-fill on resizing

Line 
1Index: src/pmc/resizableintegerarray.pmc
2===================================================================
3--- src/pmc/resizableintegerarray.pmc   (revision 41731)
4+++ src/pmc/resizableintegerarray.pmc   (working copy)
5@@ -84,12 +84,14 @@
6     VTABLE void set_integer_native(INTVAL size) {
7 
8         INTVAL *int_array;
9+        INTVAL  cur_size;
10         INTVAL  resize_threshold;
11 
12         if (size < 0)
13             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
14                     "ResizableIntegerArray: Can't resize!");
15 
16+        GET_ATTR_size(INTERP, SELF, cur_size);
17         GET_ATTR_int_array(INTERP, SELF, int_array);
18         GET_ATTR_resize_threshold(INTERP, SELF, resize_threshold);
19         if (!int_array) {
20@@ -103,15 +105,14 @@
21                 SUPER(size);
22                 SET_ATTR_resize_threshold(INTERP, SELF, size);
23             }
24+            GET_ATTR_int_array(INTERP, SELF, int_array);
25         }
26         else if (size <= resize_threshold) {
27             /* we could shrink here if necessary */
28             SET_ATTR_size(INTERP, SELF, size);
29-            return;
30         }
31         else {
32             INTVAL  cur = resize_threshold;
33-            INTVAL *int_array;
34 
35             if (cur < 8192)
36                 cur = size < 2 * cur ? 2 * cur : size;
37@@ -121,12 +122,19 @@
38                 cur          &= ~0xfff;
39             }
40 
41-            GET_ATTR_int_array(INTERP, SELF, int_array);
42             int_array = (INTVAL*) mem_sys_realloc((void*) int_array, cur * sizeof (INTVAL));
43             SET_ATTR_int_array(INTERP, SELF, int_array);
44             SET_ATTR_size(INTERP, SELF, size);
45             SET_ATTR_resize_threshold(INTERP, SELF, cur);
46         }
47+
48+        if ( size > cur_size ) {
49+            if ( size == cur_size+1 )
50+                int_array[cur_size] = 0;    // optimize for most common case (push)
51+            else
52+                mem_sys_memset(int_array + cur_size, 0, (size - cur_size) * sizeof (INTVAL));
53+        }
54+
55     }
56 
57 /*
58Index: include/parrot/memory.h
59===================================================================
60--- include/parrot/memory.h     (revision 41731)
61+++ include/parrot/memory.h     (working copy)
62@@ -33,6 +33,7 @@
63 #define mem_allocate_new_stack() NULL
64 #define mem_sys_memcopy memcpy
65 #define mem_sys_memmove memmove
66+#define mem_sys_memset memset
67 
68 #define mem_allocate_typed(type)            (type *)mem_sys_allocate(sizeof (type))
69 #define mem_allocate_n_typed(n, type)       (type *)mem_sys_allocate((n) * sizeof(type))
70Index: t/pmc/resizableintegerarray.t
71===================================================================
72--- t/pmc/resizableintegerarray.t       (revision 41731)
73+++ t/pmc/resizableintegerarray.t       (working copy)
74@@ -1,6 +1,6 @@
75 #! parrot
76 # Copyright © 2001-2007, Parrot Foundation.
77-# $Id: resizableintegerarray.t 38718 2009-05-12 16:48:28Z kurahaupo $
78+# $Id$
79 
80 =head1 NAME
81 
82@@ -38,11 +38,13 @@
83      * Doesn't change array size
84      * Multiple concurrent iterators don't interfere
85 
86+ * Lengthening zeroes elements if previously allocated space
87+
88 =cut
89 
90 .sub main :main
91     .include 'test_more.pir'
92-    plan(41)
93+    plan(42)
94 
95     test_does_interfaces()       # 4 tests
96 
97@@ -54,6 +56,7 @@
98     test_cant_get_negative()     # 1 test
99     test_set_beyond_end()        # 2 test
100     test_get_beyond_end()        # 3 tests
101+    test_zero_after_resize()     # 1 test
102 
103     test_conversion()            # 6 tests
104     test_conversion_overflow()   # 1 test
105@@ -225,6 +228,16 @@
106     is( $I0, 1, '... and should not extend array' )
107 .end
108 
109+.sub test_zero_after_resize
110+    $P0 = new ['ResizableIntegerArray']
111+    $P0 = 10
112+    $P0[7] = 23
113+    $P0 = 5
114+    $P0[9] = 0
115+    $I0 = $P0[7]
116+    is( $I0, 0, 'Latent elements are zeroed when array is shrunk and re-stretched' )
117+.end
118+
119 .sub test_conversion
120     $P0 = new ['ResizableIntegerArray']
121     $P0 = 6