Exemple #1
0
    def test_bag_remove_index(self):
        b = lib.qcgc_arena_bag_create(10)
        for i in range(10):
            b = lib.qcgc_arena_bag_add(b, ffi.cast("void *", i))

        # Remove last
        b = lib.qcgc_arena_bag_remove_index(b, b.count - 1)
        self.assertEqual(b.count, 9)

        # Remove other
        b = lib.qcgc_arena_bag_remove_index(b, 0)
        self.assertEqual(b.count, 8)

        for i in range(1, 9):
            has = False
            for j in range(8):
                has = has | (b.items[j] != ffi.cast("void *", i))
            self.assertTrue(has)

        # Bag with size 1
        b = lib.qcgc_arena_bag_create(1)
        b = lib.qcgc_arena_bag_add(b, ffi.NULL)

        b = lib.qcgc_arena_bag_remove_index(b, 0)
        self.assertEqual(b.count, 0)
Exemple #2
0
    def test_grow_shrink(self):
        """Test automatic growing/shrinking"""
        stack = lib.qcgc_object_stack_create(10)
        pythonstack = list()

        for i in range(1000):
            stack = lib.qcgc_object_stack_push(stack,
                                               ffi.cast("object_t *", i))
            pythonstack.append(ffi.cast("object_t *", i))

        self.assertEqual(stack.count, 1000)

        while pythonstack:
            p = lib.qcgc_object_stack_top(stack)
            self.assertEqual(p, pythonstack.pop())
            stack = lib.qcgc_object_stack_pop(stack)

        self.assertEqual(stack.count, 0)

        for i in range(1000):
            stack = lib.qcgc_object_stack_push(stack,
                                               ffi.cast("object_t *", i))
            pythonstack.append(ffi.cast("object_t *", i))

        self.assertEqual(stack.count, 1000)

        while pythonstack:
            p = lib.qcgc_object_stack_top(stack)
            self.assertEqual(p, pythonstack.pop())
            stack = lib.qcgc_object_stack_pop(stack)

        self.assertEqual(stack.count, 0)
Exemple #3
0
    def test_bag_remove_index(self):
        b = lib.qcgc_arena_bag_create(10)
        for i in range(10):
            b = lib.qcgc_arena_bag_add(b, ffi.cast("void *", i))

        # Remove last
        b = lib.qcgc_arena_bag_remove_index(b, b.count - 1)
        self.assertEqual(b.count, 9)

        # Remove other
        b = lib.qcgc_arena_bag_remove_index(b, 0)
        self.assertEqual(b.count, 8)

        for i in range(1,9):
            has = False
            for j in range(8):
                has = has | (b.items[j] != ffi.cast("void *", i))
            self.assertTrue(has)

        # Bag with size 1
        b = lib.qcgc_arena_bag_create(1)
        b = lib.qcgc_arena_bag_add(b, ffi.NULL)

        b = lib.qcgc_arena_bag_remove_index(b, 0)
        self.assertEqual(b.count, 0)
Exemple #4
0
 def test_bag_add(self):
     b = lib.qcgc_arena_bag_create(100)
     for i in range(100):
         b = lib.qcgc_arena_bag_add(b, ffi.cast("void *", i))
         self.assertEqual(b.size, 100)
         self.assertEqual(b.count, i + 1)
         self.assertEqual(b.items[i], ffi.cast("void *", i))
Exemple #5
0
 def test_incremental(self):
     o = self.allocate_prebuilt_ref(2)
     p = self.allocate(1)
     q = self.allocate(2)
     self.set_ref(o, 0, p)
     #
     lib.qcgc_incmark()
     #
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)),
                      lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", q)),
                      lib.BLOCK_WHITE)
     #
     self.set_ref(o, 1, q)
     #
     lib.qcgc_incmark()
     #
     r = self.allocate_prebuilt_ref(1)
     s = self.allocate(2)
     self.set_ref(r, 0, s)
     #
     lib.qcgc_incmark()
     #
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)),
                      lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", q)),
                      lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", s)),
                      lib.BLOCK_BLACK)
Exemple #6
0
    def test_ref_1(self):
        """Tree shaped reference struct"""

        # Generate reachable objects
        reachable = list()
        for _ in range(10):
            p, objs = self.gen_structure_1()
            self.push_root(p)
            reachable.extend(objs)

        # Generate unreachable objects
        unreachable = list()
        for _ in range(10):
            p, objs = self.gen_structure_1()
            unreachable.extend(objs)

        lib.qcgc_mark()

        for p in reachable:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)),
                             lib.BLOCK_BLACK)

        for p in unreachable:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)),
                             lib.BLOCK_WHITE)
Exemple #7
0
    def test_root_changes_while_marking(self):
        reachable = list()
        for _ in range(10):
            p, objs = self.gen_structure_1()
            self.push_root(p)
            reachable.extend(objs)
        #
        unreachable = list()
        for _ in range(10):
            p, objs = self.gen_structure_1()
            unreachable.extend(objs)
        #
        lib.qcgc_incmark()
        #
        # Generate new roots
        objects = self.gen_circular_structure(100)
        self.push_root(objects[0])
        reachable.extend(objects)

        mark_all_inc()

        for p in reachable:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_BLACK)

        for p in unreachable:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_WHITE)
Exemple #8
0
    def test_arena_sweep_no_bump_ptr_coalescing(self):
        p = self.bump_allocate(16)
        arena = lib.qcgc_arena_addr(ffi.cast("cell_t *", p))

        lib.qcgc_arena_sweep(arena)

        self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", lib.bump_ptr())), lib.BLOCK_FREE)
Exemple #9
0
 def test_bag_add(self):
     b = lib.qcgc_arena_bag_create(100)
     for i in range(100):
         b = lib.qcgc_arena_bag_add(b, ffi.cast("void *", i))
         self.assertEqual(b.size, 100)
         self.assertEqual(b.count, i + 1)
         self.assertEqual(b.items[i], ffi.cast("void *", i))
Exemple #10
0
    def test_grow_shrink(self):
        """Test automatic growing/shrinking"""
        stack = lib.qcgc_object_stack_create(10)
        pythonstack = list()

        for i in range(1000):
            stack = lib.qcgc_object_stack_push(stack, ffi.cast("object_t *", i))
            pythonstack.append(ffi.cast("object_t *", i))

        self.assertEqual(stack.count, 1000)

        while pythonstack:
            p = lib.qcgc_object_stack_top(stack);
            self.assertEqual(p, pythonstack.pop())
            stack = lib.qcgc_object_stack_pop(stack);

        self.assertEqual(stack.count, 0)

        for i in range(1000):
            stack = lib.qcgc_object_stack_push(stack, ffi.cast("object_t *", i))
            pythonstack.append(ffi.cast("object_t *", i))

        self.assertEqual(stack.count, 1000)

        while pythonstack:
            p = lib.qcgc_object_stack_top(stack);
            self.assertEqual(p, pythonstack.pop())
            stack = lib.qcgc_object_stack_pop(stack);

        self.assertEqual(stack.count, 0)
Exemple #11
0
 def allocate_weakref(self, to):
     o = lib.qcgc_allocate(self.header_size + ffi.sizeof("myobject_t *"))
     self.assertNotEqual(o, ffi.NULL)
     lib._set_type_id(o, 0)  # Prevent from tracing
     ffi.cast("myobject_t *", o).refs[0] = ffi.cast("myobject_t *", to) # Ref has to be valid before registering
     lib.qcgc_register_weakref(o, ffi.cast("object_t **",
         ffi.cast("myobject_t *", o).refs)) # XXX: ffi.addressof .refs[0] does not work
     lib.qcgc_write(o)
     return o
Exemple #12
0
 def test_arena_create(self):
     p = lib.qcgc_arena_create()
     self.assertEqual(p, lib.qcgc_arena_addr(lib.arena_cells(p)))
     self.assertEqual(p, lib.qcgc_arena_addr(ffi.addressof(lib.arena_cells(p)[lib.qcgc_arena_cells_count - 1])))
     self.assertEqual(0, lib.qcgc_arena_cell_index(lib.arena_cells(p)))
     self.assertEqual(int(ffi.cast("uint64_t", p)),
             int(ffi.cast("uint64_t", p))
                 << lib.QCGC_ARENA_SIZE_EXP
                 >> lib.QCGC_ARENA_SIZE_EXP)
     self.assertEqual(lib.BLOCK_FREE, self.get_blocktype(ffi.addressof(lib.arena_cells(p)[lib.qcgc_arena_first_cell_index])))
Exemple #13
0
    def test_bag_shrink(self):
        b = lib.qcgc_arena_bag_create(12)
        for i in range(3):
            b = lib.qcgc_arena_bag_add(b, ffi.cast("void *", i))

        self.assertEqual(b.size, 12)
        b = lib.qcgc_arena_bag_remove_index(b, 2)

        self.assertEqual(b.size, 6)
        for i in range(2):
            self.assertEqual(b.items[i], ffi.cast("void *", i))
Exemple #14
0
    def test_bag_shrink(self):
        b = lib.qcgc_arena_bag_create(12)
        for i in range(3):
            b = lib.qcgc_arena_bag_add(b, ffi.cast("void *", i))

        self.assertEqual(b.size, 12)
        b = lib.qcgc_arena_bag_remove_index(b, 2)

        self.assertEqual(b.size, 6)
        for i in range(2):
            self.assertEqual(b.items[i], ffi.cast("void *", i))
Exemple #15
0
    def test_bag_grow(self):
        b = lib.qcgc_arena_bag_create(10)
        for i in range(10):
            b = lib.qcgc_arena_bag_add(b, ffi.cast("void *", i))

        self.assertEqual(b.count, b.size)
        b = lib.qcgc_arena_bag_add(b, ffi.cast("void *", 10))
        self.assertEqual(b.size, 20)
        self.assertEqual(b.count, 11)

        for i in range(11):
            self.assertEqual(b.items[i], ffi.cast("void *", i))
Exemple #16
0
    def test_bag_grow(self):
        b = lib.qcgc_arena_bag_create(10)
        for i in range(10):
            b = lib.qcgc_arena_bag_add(b, ffi.cast("void *", i))

        self.assertEqual(b.count, b.size)
        b = lib.qcgc_arena_bag_add(b, ffi.cast("void *", 10))
        self.assertEqual(b.size, 20)
        self.assertEqual(b.count, 11)

        for i in range(11):
            self.assertEqual(b.items[i], ffi.cast("void *", i))
Exemple #17
0
 def allocate_weakref(self, to):
     o = lib.qcgc_allocate(self.header_size + ffi.sizeof("myobject_t *"))
     self.assertNotEqual(o, ffi.NULL)
     lib._set_type_id(o, 0)  # Prevent from tracing
     ffi.cast("myobject_t *", o).refs[0] = ffi.cast(
         "myobject_t *", to)  # Ref has to be valid before registering
     lib.qcgc_register_weakref(
         o, ffi.cast(
             "object_t **",
             ffi.cast("myobject_t *",
                      o).refs))  # XXX: ffi.addressof .refs[0] does not work
     lib.qcgc_write(o)
     return o
Exemple #18
0
    def test_many_small_allocations(self):
        objects = set()
        p = self.bump_allocate(16)
        arena = lib.qcgc_arena_addr(ffi.cast("cell_t *", p))
        objects.add(p)

        for _ in range(1000):
            p = self.bump_allocate(16)
            objects.add(p)
            self.assertEqual(arena, lib.qcgc_arena_addr(ffi.cast("cell_t *", p)))

        self.assertFalse(ffi.NULL in objects)
        self.assertEqual(len(objects), 1001)
Exemple #19
0
    def test_many_small_allocations(self):
        objects = set()
        p = self.bump_allocate(16)
        arena = lib.qcgc_arena_addr(ffi.cast("cell_t *", p))
        objects.add(p)

        for _ in range(1000):
            p = self.bump_allocate(16)
            objects.add(p)
            self.assertEqual(arena,
                             lib.qcgc_arena_addr(ffi.cast("cell_t *", p)))

        self.assertFalse(ffi.NULL in objects)
        self.assertEqual(len(objects), 1001)
Exemple #20
0
 def allocate_prebuilt_ref(self, size):
     o = lib.allocate_prebuilt(self.header_size +
                               size * ffi.sizeof("myobject_t *"))
     self.assertNotEqual(o, ffi.NULL)
     lib._set_type_id(o, size)
     lib.qcgc_write(o)  # Register object
     return ffi.cast("myobject_t *", o)
Exemple #21
0
    def test_push_pop(self):
        """Test push/pop"""
        stack = lib.qcgc_object_stack_create(1000)
        pythonstack = list()

        for i in range(1000):
            stack = lib.qcgc_object_stack_push(stack, ffi.cast("object_t *", i))
            pythonstack.append(ffi.cast("object_t *", i))

        self.assertEqual(stack.count, 1000)

        while pythonstack:
            p = lib.qcgc_object_stack_top(stack);
            self.assertEqual(p, pythonstack.pop())
            stack = lib.qcgc_object_stack_pop(stack);

        self.assertEqual(stack.count, 0)
Exemple #22
0
 def test_incremenatal(self):
     o = ffi.cast("object_t *", self.allocate_ref(lib.qcgc_arena_size // ffi.sizeof("myobject_t *")))
     self.push_root(o)
     p = ffi.cast("object_t *", self.allocate(1))
     self.push_root(p)
     q = ffi.cast("object_t *", self.allocate(1))
     self.set_ref(o, 0, p)
     #
     self.pop_root()
     lib.qcgc_incmark()
     #
     self.assertTrue(self.hbtable_has(o))
     self.assertTrue(self.hbtable_marked(o))
     self.assertFalse(self.gp_gray_stack_has(o))
     #
     self.assertEqual(self.get_blocktype(
         ffi.cast("cell_t *", p)), lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(
         ffi.cast("cell_t *", q)), lib.BLOCK_WHITE)
     #
     self.set_ref(o, 1, q)
     self.assertTrue(self.gp_gray_stack_has(o))
     #
     lib.qcgc_incmark()
     #
     self.assertTrue(self.hbtable_has(o))
     self.assertTrue(self.hbtable_marked(o))
     self.assertFalse(self.gp_gray_stack_has(o))
     #
     self.assertEqual(self.get_blocktype(
         ffi.cast("cell_t *", p)), lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(
         ffi.cast("cell_t *", q)), lib.BLOCK_BLACK)
Exemple #23
0
    def test_color_transitions(self):
        """Test all possible color transitions"""
        reachable = list()
        unreachable = list()

        for i in range(2 * lib.QCGC_INC_MARK_MIN):
            o = self.allocate_ref(1)
            self.push_root(o)
            reachable.append(o)
            self.assertEqual(lib.qcgc_get_mark_color(ffi.cast("object_t *",o)), lib.MARK_COLOR_LIGHT_GRAY)


        lib.qcgc_incmark() # Marks ALL root objects
        self.assertEqual(lib.qcgc_state.phase, lib.GC_MARK)

        for o in reachable:
            self.assertIn(lib.qcgc_get_mark_color(ffi.cast("object_t *", o)), [lib.MARK_COLOR_DARK_GRAY, lib.MARK_COLOR_BLACK])
            if (lib.qcgc_get_mark_color(ffi.cast("object_t *", o)) == lib.MARK_COLOR_BLACK):
                # Trigger write barrier and add object
                lib.qcgc_write(ffi.cast("object_t *", o))
                self.assertEqual(lib.qcgc_get_mark_color(ffi.cast("object_t *", o)), lib.MARK_COLOR_DARK_GRAY)

        lib.qcgc_mark()

        for o in reachable:
            self.assertEqual(lib.qcgc_get_mark_color(ffi.cast("object_t *", o)), lib.MARK_COLOR_BLACK)

        lib.bump_ptr_reset()
        lib.qcgc_sweep()

        for o in reachable:
            self.assertEqual(lib.qcgc_get_mark_color(ffi.cast("object_t *", o)), lib.MARK_COLOR_WHITE)
Exemple #24
0
    def test_push_pop(self):
        """Test push/pop"""
        stack = lib.qcgc_object_stack_create(1000)
        pythonstack = list()

        for i in range(1000):
            stack = lib.qcgc_object_stack_push(stack,
                                               ffi.cast("object_t *", i))
            pythonstack.append(ffi.cast("object_t *", i))

        self.assertEqual(stack.count, 1000)

        while pythonstack:
            p = lib.qcgc_object_stack_top(stack)
            self.assertEqual(p, pythonstack.pop())
            stack = lib.qcgc_object_stack_pop(stack)

        self.assertEqual(stack.count, 0)
Exemple #25
0
    def test_prebuilt(self):
        p = self.allocate_prebuilt(1)
        q = self.allocate_prebuilt_ref(4)
        r = self.allocate(1)
        s = self.allocate_ref(4)
        self.set_ref(q, 0, p)
        self.set_ref(q, 1, q)
        self.set_ref(q, 2, r)
        self.set_ref(q, 3, s)

        self.set_ref(s, 0, p)
        self.set_ref(s, 1, q)
        self.set_ref(s, 2, r)
        self.set_ref(s, 3, s)

        lib.bump_ptr_reset()
        lib.qcgc_collect()
        self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", r)), lib.BLOCK_WHITE)
        self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", s)), lib.BLOCK_WHITE)
Exemple #26
0
    def test_no_references(self):
        """No references"""
        roots = list()
        garbage = list()

        for _ in range(100):
            p = self.allocate(10)
            self.push_root(p)
            roots.append(p)

            p = self.allocate(3)
            garbage.append(p)

        lib.qcgc_mark()

        for p in roots:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_BLACK)

        for p in garbage:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_WHITE)
Exemple #27
0
    def test_no_references(self):
        """No references"""
        roots = list()
        garbage = list()

        for _ in range(100):
            p = self.allocate(10)
            self.push_root(p)
            roots.append(p)

            p = self.allocate(3)
            garbage.append(p)

        mark_all_inc()

        for p in roots:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_BLACK)

        for p in garbage:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_WHITE)
Exemple #28
0
    def test_circular(self):
        """Circular references"""
        reachable = list()
        unreachable = list()

        for i in range(10):
            objects = self.gen_circular_structure(i + 1)
            self.push_root(objects[0])
            reachable.extend(objects)

        for i in range(10):
            objects = self.gen_circular_structure(i + 1)
            unreachable.extend(objects)

        mark_all_inc()

        for p in reachable:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_BLACK)

        for p in unreachable:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_WHITE)
Exemple #29
0
    def test_prebuilt(self):
        p = self.allocate_prebuilt(1)
        q = self.allocate_prebuilt_ref(4)
        r = self.allocate(1)
        s = self.allocate_ref(4)
        self.set_ref(q, 0, p)
        self.set_ref(q, 1, q)
        self.set_ref(q, 2, r)
        self.set_ref(q, 3, s)

        self.set_ref(s, 0, p)
        self.set_ref(s, 1, q)
        self.set_ref(s, 2, r)
        self.set_ref(s, 3, s)

        lib.bump_ptr_reset()
        lib.qcgc_collect()
        self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", r)),
                         lib.BLOCK_WHITE)
        self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", s)),
                         lib.BLOCK_WHITE)
Exemple #30
0
    def test_circular(self):
        """Circular references"""
        reachable = list()
        unreachable = list()

        for i in range(10):
            objects = self.gen_circular_structure(i + 1)
            self.push_root(objects[0])
            reachable.extend(objects)

        for i in range(10):
            objects = self.gen_circular_structure(i + 1)
            unreachable.extend(objects)

        lib.qcgc_mark()

        for p in reachable:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_BLACK)

        for p in unreachable:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_WHITE)
Exemple #31
0
 def test_write_barrier_after_sweep(self):
     o = self.allocate_ref(1)
     self.push_root(o)
     #
     lib.qcgc_collect()
     #
     p = self.allocate(1)
     self.set_ref(o, 0, p)
     #
     lib.bump_ptr_reset()
     lib.qcgc_collect()
     #
     self.assertIn(self.get_blocktype(ffi.cast("cell_t *", p)), [lib.BLOCK_WHITE, lib.BLOCK_BLACK])
Exemple #32
0
    def test_ref_1(self):
        """Tree shaped reference struct"""

        # Generate reachable objects
        reachable = list()
        for _ in range(10):
            p, objs = self.gen_structure_1()
            self.push_root(p)
            reachable.extend(objs)

        # Generate unreachable objects
        unreachable = list()
        for _ in range(10):
            p, objs = self.gen_structure_1()
            unreachable.extend(objs)

        lib.qcgc_mark()

        for p in reachable:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_BLACK)

        for p in unreachable:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_WHITE)
Exemple #33
0
 def to_dot(self, filename, edges):
     from pygraphviz import AGraph
     dot = AGraph(directed=True)
     for n in edges.keys():
         dot.add_node(str(n))
         if lib.qcgc_arena_get_blocktype(ffi.cast("cell_t *", n)) not in [
                 lib.BLOCK_BLACK, lib.BLOCK_WHITE]:
             node = dot.get_node(str(n))
             node.attr['color'] = 'red'
     for n in edges.keys():
         if edges[n] is not None:
             dot.add_edge(str(n), str(edges[n]))
     dot.layout(prog='dot')
     dot.draw(filename)
Exemple #34
0
 def to_dot(self, filename, edges):
     from pygraphviz import AGraph
     dot = AGraph(directed=True)
     for n in edges.keys():
         dot.add_node(str(n))
         if lib.qcgc_arena_get_blocktype(ffi.cast(
                 "cell_t *", n)) not in [lib.BLOCK_BLACK, lib.BLOCK_WHITE]:
             node = dot.get_node(str(n))
             node.attr['color'] = 'red'
     for n in edges.keys():
         if edges[n] is not None:
             dot.add_edge(str(n), str(edges[n]))
     dot.layout(prog='dot')
     dot.draw(filename)
Exemple #35
0
 def test_incremental(self):
     o = self.allocate_prebuilt_ref(2)
     p = self.allocate(1)
     q = self.allocate(2)
     self.set_ref(o, 0, p)
     #
     lib.qcgc_incmark()
     #
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", q)), lib.BLOCK_WHITE)
     #
     self.set_ref(o, 1, q)
     #
     lib.qcgc_incmark()
     #
     r = self.allocate_prebuilt_ref(1)
     s = self.allocate(2)
     self.set_ref(r, 0, s)
     #
     lib.qcgc_incmark()
     #
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)), lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", q)), lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", s)), lib.BLOCK_BLACK)
Exemple #36
0
    def test_write_barrier(self):
        o = self.allocate(16)
        self.push_root(o)
        arena = lib.qcgc_arena_addr(ffi.cast("cell_t *", o))
        o.hdr.flags = o.hdr.flags & ~lib.QCGC_GRAY_FLAG
        self.assertEqual(ffi.cast("object_t *", o).flags & lib.QCGC_GRAY_FLAG, 0)
        lib.qcgc_write(ffi.cast("object_t *", o))
        self.assertEqual(ffi.cast("object_t *", o).flags & lib.QCGC_GRAY_FLAG, lib.QCGC_GRAY_FLAG)

        lib.qcgc_state.phase = lib.GC_MARK
        o = self.allocate(16)
        self.push_root(o)
        arena = lib.qcgc_arena_addr(ffi.cast("cell_t *", o))
        o.hdr.flags = o.hdr.flags & ~lib.QCGC_GRAY_FLAG
        self.assertEqual(ffi.cast("object_t *", o).flags & lib.QCGC_GRAY_FLAG, 0)
        self.set_blocktype(ffi.cast("cell_t *", o), lib.BLOCK_BLACK)
        lib.qcgc_state.phase = lib.GC_MARK
        lib.qcgc_write(ffi.cast("object_t *", o))
        self.assertEqual(ffi.cast("object_t *", o).flags & lib.QCGC_GRAY_FLAG, lib.QCGC_GRAY_FLAG)
        self.assertEqual(lib.arena_gray_stack(arena).count, 1)
        self.assertEqual(lib.arena_gray_stack(arena).items[0], o)
    def test_simple_switch(self):
        objs = list()
        for _ in range(lib.qcgc_arena_cells_count - lib.qcgc_arena_first_cell_index - 1):
            o = self.allocate(1)
            self.push_root(o)
            objs.append(o)
        #
        for o in objs:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *",o)), lib.BLOCK_WHITE)

        lib.qcgc_reset_bump_ptr()
        lib.qcgc_collect()
        self.assertEqual(lib._qcgc_bump_allocator.ptr, ffi.NULL)
        self.assertEqual(lib._qcgc_bump_allocator.end, ffi.NULL)
        self.allocate(1)
        self.assertEqual(lib._qcgc_bump_allocator.ptr, ffi.NULL)
        self.assertEqual(lib._qcgc_bump_allocator.end, ffi.NULL)
    def test_simple_switch(self):
        objs = list()
        for _ in range(lib.qcgc_arena_cells_count -
                       lib.qcgc_arena_first_cell_index - 1):
            o = self.allocate(1)
            self.push_root(o)
            objs.append(o)
        #
        for o in objs:
            self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", o)),
                             lib.BLOCK_WHITE)

        lib.qcgc_reset_bump_ptr()
        lib.qcgc_collect()
        self.assertEqual(lib._qcgc_bump_allocator.ptr, ffi.NULL)
        self.assertEqual(lib._qcgc_bump_allocator.end, ffi.NULL)
        self.allocate(1)
        self.assertEqual(lib._qcgc_bump_allocator.ptr, ffi.NULL)
        self.assertEqual(lib._qcgc_bump_allocator.end, ffi.NULL)
Exemple #39
0
 def test_incremenatal(self):
     o = ffi.cast(
         "object_t *",
         self.allocate_ref(lib.qcgc_arena_size //
                           ffi.sizeof("myobject_t *")))
     self.push_root(o)
     p = ffi.cast("object_t *", self.allocate(1))
     self.push_root(p)
     q = ffi.cast("object_t *", self.allocate(1))
     self.set_ref(o, 0, p)
     #
     self.pop_root()
     lib.qcgc_incmark()
     #
     self.assertTrue(self.hbtable_has(o))
     self.assertTrue(self.hbtable_marked(o))
     self.assertFalse(self.gp_gray_stack_has(o))
     #
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)),
                      lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", q)),
                      lib.BLOCK_WHITE)
     #
     self.set_ref(o, 1, q)
     self.assertTrue(self.gp_gray_stack_has(o))
     #
     lib.qcgc_incmark()
     #
     self.assertTrue(self.hbtable_has(o))
     self.assertTrue(self.hbtable_marked(o))
     self.assertFalse(self.gp_gray_stack_has(o))
     #
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", p)),
                      lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", q)),
                      lib.BLOCK_BLACK)
Exemple #40
0
 def set_ref(self, obj, index, ref):
     lib.qcgc_write(ffi.cast("object_t *", obj)) # Trigger write barrier
     assert index >= 0
     assert ffi.cast("myobject_t *", obj).type_id > index
     ffi.cast("myobject_t *", obj).refs[index] = ffi.cast("myobject_t *", ref)
Exemple #41
0
 def test_mark_large(self):
     o = ffi.cast("object_t *", self.allocate(lib.qcgc_arena_size))
     self.push_root(o)
     p = ffi.cast(
         "object_t *",
         self.allocate_ref(lib.qcgc_arena_size //
                           ffi.sizeof("myobject_t *")))
     self.push_root(p)
     q = ffi.cast("object_t *", self.allocate(lib.qcgc_arena_size))
     self.push_root(q)
     r = ffi.cast("object_t *", self.allocate(1))
     self.push_root(r)
     s = ffi.cast("object_t *", self.allocate_ref(1))
     self.push_root(s)
     t = ffi.cast("object_t *", self.allocate(lib.qcgc_arena_size))
     self.push_root(t)
     self.set_ref(p, 0, q)
     self.set_ref(p, 1, r)
     self.set_ref(p, 2, s)
     self.set_ref(s, 0, p)
     #
     for _ in range(6):
         self.pop_root()
     self.push_root(o)
     self.push_root(s)
     #
     lib.qcgc_mark()
     #
     self.assertTrue(self.hbtable_has(o))
     self.assertTrue(self.hbtable_marked(o))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertTrue(self.hbtable_has(p))
     self.assertTrue(self.hbtable_marked(p))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertTrue(self.hbtable_has(q))
     self.assertTrue(self.hbtable_marked(q))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertTrue(self.hbtable_has(t))
     self.assertFalse(self.hbtable_marked(t))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", s)),
                      lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", r)),
                      lib.BLOCK_BLACK)
     #
     lib.bump_ptr_reset()
     lib.qcgc_sweep()
     #
     self.assertTrue(self.hbtable_has(o))
     self.assertFalse(self.hbtable_marked(o))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertTrue(self.hbtable_has(p))
     self.assertFalse(self.hbtable_marked(p))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertTrue(self.hbtable_has(q))
     self.assertFalse(self.hbtable_marked(q))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertFalse(self.hbtable_has(t))
     self.assertFalse(self.hbtable_marked(t))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", s)),
                      lib.BLOCK_WHITE)
     self.assertEqual(self.get_blocktype(ffi.cast("cell_t *", r)),
                      lib.BLOCK_WHITE)
Exemple #42
0
 def get_ref(self, obj, index):
     return ffi.cast("myobject_t *", obj).refs[index]
Exemple #43
0
 def assert_valid_gc_object(self, obj):
     self.assertIn(self.get_blocktype(ffi.cast("cell_t *", obj)), [
             lib.BLOCK_BLACK, lib.BLOCK_WHITE ])
Exemple #44
0
 def test_self_allocate(self):
     p = self.allocate(1)
     self.assertEqual(lib._get_type_id(ffi.cast("object_t *", p)), 0)
     p = self.allocate_ref(1)
     self.assertEqual(lib._get_type_id(ffi.cast("object_t *", p)), 1)
Exemple #45
0
 def bump_allocate_cells(self, cells):
     p = self.bump_allocate(cells * 16)
     self.bump_allocate(16)  # Prevent non-coalseced arena
     return ffi.cast("cell_t *", p)
Exemple #46
0
 def set_ref(self, obj, index, ref):
     lib.qcgc_write(ffi.cast("object_t *", obj))  # Trigger write barrier
     assert index >= 0
     assert ffi.cast("myobject_t *", obj).type_id > index
     ffi.cast("myobject_t *",
              obj).refs[index] = ffi.cast("myobject_t *", ref)
Exemple #47
0
 def get_ref(self, obj, index):
     return ffi.cast("myobject_t *", obj).refs[index]
Exemple #48
0
    def test_allocate_coalesced_block(self):
        "Test allocation when there are invalid blocks in the free lists"
        # Small block
        # coalesced area no 1
        # ATOMIC! Invalidates internal invariant for short time
        x = self.bump_allocate(16)
        y = self.bump_allocate(16)
        self.bump_allocate(16) # Prevent non-coalesced arena
        lib.qcgc_arena_mark_free(ffi.cast("cell_t *",x))
        lib.qcgc_arena_mark_free(ffi.cast("cell_t *",y))
        lib.qcgc_fit_allocator_add(ffi.cast("cell_t *", x), 1)
        lib.qcgc_fit_allocator_add(ffi.cast("cell_t *", y), 1)
        self.set_blocktype(ffi.cast("cell_t *", y), lib.BLOCK_EXTENT)

        # only valid block
        p = self.bump_allocate_cells(1)
        lib.qcgc_arena_mark_free(p)
        lib.qcgc_fit_allocator_add(p, 1)

        # coalesced area no 2
        # ATOMIC! Invalidates internal invariant for short time
        x = self.bump_allocate(16)
        y = self.bump_allocate(16)
        self.bump_allocate(16) # Prevent non-coalesced arena
        lib.qcgc_arena_mark_free(ffi.cast("cell_t *",x))
        lib.qcgc_arena_mark_free(ffi.cast("cell_t *",y))
        lib.qcgc_fit_allocator_add(ffi.cast("cell_t *", x), 1)
        lib.qcgc_fit_allocator_add(ffi.cast("cell_t *", y), 1)
        self.set_blocktype(ffi.cast("cell_t *", y), lib.BLOCK_EXTENT)

        q = self.fit_allocate(1)
        self.assertEqual(p, q)

        # Large block
        # coalesced area no 1
        # ATOMIC! Invalidates internal invariant for short time
        x = self.bump_allocate(16 * 2**lib.QCGC_LARGE_FREE_LIST_FIRST_EXP)
        y = self.bump_allocate(16 * 2**lib.QCGC_LARGE_FREE_LIST_FIRST_EXP)
        self.bump_allocate(16) # Prevent non-coalesced arena
        lib.qcgc_arena_mark_free(ffi.cast("cell_t *",x))
        lib.qcgc_arena_mark_free(ffi.cast("cell_t *",y))
        lib.qcgc_fit_allocator_add(ffi.cast("cell_t *", x), 2**lib.QCGC_LARGE_FREE_LIST_FIRST_EXP)
        lib.qcgc_fit_allocator_add(ffi.cast("cell_t *", y), 2**lib.QCGC_LARGE_FREE_LIST_FIRST_EXP)
        self.set_blocktype(ffi.cast("cell_t *", y), lib.BLOCK_EXTENT)

        # only valid block
        p = self.bump_allocate_cells(2**lib.QCGC_LARGE_FREE_LIST_FIRST_EXP)
        lib.qcgc_arena_mark_free(p)
        lib.qcgc_fit_allocator_add(p, 2**lib.QCGC_LARGE_FREE_LIST_FIRST_EXP)

        # coalesced area no 2
        # ATOMIC! Invalidates internal invariant for short time
        x = self.bump_allocate(16 * 2**lib.QCGC_LARGE_FREE_LIST_FIRST_EXP)
        y = self.bump_allocate(16 * 2**lib.QCGC_LARGE_FREE_LIST_FIRST_EXP)
        self.bump_allocate(16) # Prevent non-coalesced arena
        lib.qcgc_arena_mark_free(ffi.cast("cell_t *",x))
        lib.qcgc_arena_mark_free(ffi.cast("cell_t *",y))
        lib.qcgc_fit_allocator_add(ffi.cast("cell_t *", x), 2**lib.QCGC_LARGE_FREE_LIST_FIRST_EXP)
        lib.qcgc_fit_allocator_add(ffi.cast("cell_t *", y), 2**lib.QCGC_LARGE_FREE_LIST_FIRST_EXP)
        self.set_blocktype(ffi.cast("cell_t *", y), lib.BLOCK_EXTENT)

        q = self.fit_allocate(2**lib.QCGC_LARGE_FREE_LIST_FIRST_EXP)
        self.assertEqual(p, q)
Exemple #49
0
 def fit_allocate(self, cells):
     p = lib.qcgc_fit_allocate(cells * 16)
     return ffi.cast("cell_t *", p)
Exemple #50
0
 def bump_allocate_cells(self, cells):
     p = self.bump_allocate(cells * 16)
     self.bump_allocate(16)   # Prevent non-coalseced arena
     return ffi.cast("cell_t *", p)
Exemple #51
0
 def test_mark_large(self):
     o = ffi.cast("object_t *", self.allocate(lib.qcgc_arena_size))
     self.push_root(o)
     p = ffi.cast("object_t *", self.allocate_ref(lib.qcgc_arena_size // ffi.sizeof("myobject_t *")))
     self.push_root(p)
     q = ffi.cast("object_t *", self.allocate(lib.qcgc_arena_size))
     self.push_root(q)
     r = ffi.cast("object_t *", self.allocate(1))
     self.push_root(r)
     s = ffi.cast("object_t *", self.allocate_ref(1))
     self.push_root(s)
     t = ffi.cast("object_t *", self.allocate(lib.qcgc_arena_size))
     self.push_root(t)
     self.set_ref(p, 0, q)
     self.set_ref(p, 1, r)
     self.set_ref(p, 2, s)
     self.set_ref(s, 0, p)
     #
     for _ in range(6):
         self.pop_root()
     self.push_root(o)
     self.push_root(s)
     #
     lib.qcgc_mark()
     #
     self.assertTrue(self.hbtable_has(o))
     self.assertTrue(self.hbtable_marked(o))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertTrue(self.hbtable_has(p))
     self.assertTrue(self.hbtable_marked(p))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertTrue(self.hbtable_has(q))
     self.assertTrue(self.hbtable_marked(q))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertTrue(self.hbtable_has(t))
     self.assertFalse(self.hbtable_marked(t))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertEqual(self.get_blocktype(
         ffi.cast("cell_t *", s)), lib.BLOCK_BLACK)
     self.assertEqual(self.get_blocktype(
         ffi.cast("cell_t *", r)), lib.BLOCK_BLACK)
     #
     lib.bump_ptr_reset()
     lib.qcgc_sweep()
     #
     self.assertTrue(self.hbtable_has(o))
     self.assertFalse(self.hbtable_marked(o))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertTrue(self.hbtable_has(p))
     self.assertFalse(self.hbtable_marked(p))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertTrue(self.hbtable_has(q))
     self.assertFalse(self.hbtable_marked(q))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertFalse(self.hbtable_has(t))
     self.assertFalse(self.hbtable_marked(t))
     self.assertEqual(lib.qcgc_state.gray_stack_size, 0)
     #
     self.assertEqual(self.get_blocktype(
         ffi.cast("cell_t *", s)), lib.BLOCK_WHITE)
     self.assertEqual(self.get_blocktype(
         ffi.cast("cell_t *", r)), lib.BLOCK_WHITE)
Exemple #52
0
 def push_root(self, o):
     lib.qcgc_push_root(ffi.cast("object_t *", o))
Exemple #53
0
 def test_self_allocate(self):
     p = self.allocate(1)
     self.assertEqual(lib._get_type_id(ffi.cast("object_t *", p)), 0)
     p = self.allocate_ref(1)
     self.assertEqual(lib._get_type_id(ffi.cast("object_t *", p)), 1)
Exemple #54
0
 def allocate_ref(self, size):
     o = lib.qcgc_allocate(self.header_size +
                           size * ffi.sizeof("myobject_t *"))
     self.assertNotEqual(o, ffi.NULL)
     lib._set_type_id(o, size)
     return ffi.cast("myobject_t *", o)