示例#1
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)
示例#2
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)
示例#3
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
示例#4
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
示例#5
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)
示例#6
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)
示例#7
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)
示例#8
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)