def get_random_structure_type_and_vtable(self, r): if self.structure_types_and_vtables and r.random() < 0.5: return r.choice(self.structure_types_and_vtables) vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) vtable.subclassrange_min = self.vtable_counter vtable.subclassrange_max = self.vtable_counter self.vtable_counter += 1 S = self.get_random_structure_type(r, with_vtable=vtable, cache=False) name = S._name heaptracker.set_testing_vtable_for_gcstruct(S, vtable, name) self.structure_types_and_vtables.append((S, vtable)) # return S, vtable
def get_random_structure_type_and_vtable(self, r): if self.structure_types_and_vtables and r.random() < 0.5: return r.choice(self.structure_types_and_vtables) vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) vtable.subclassrange_min = self.vtable_counter vtable.subclassrange_max = self.vtable_counter self.vtable_counter += 1 S = self.get_random_structure_type(r, with_vtable=vtable, cache=False) name = S._name heaptracker.set_testing_vtable_for_gcstruct(S, vtable, name) self.structure_types_and_vtables.append((S, vtable)) # return S, vtable
def test_malloc_new_with_vtable(): vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) S = lltype.GcStruct("S", ("parent", rclass.OBJECT)) heaptracker.set_testing_vtable_for_gcstruct(S, vtable, "S") v = varoftype(lltype.Ptr(S)) op = SpaceOperation("malloc", [Constant(S, lltype.Void), Constant({"flavor": "gc"}, lltype.Void)], v) cpu = FakeCPU() op1 = Transformer(cpu).rewrite_operation(op) assert op1.opname == "new_with_vtable" assert op1.args == [("sizedescr", S)] # assert heaptracker.descr2vtable(cpu, op1.args[0]) == vtable [type check] vtable_int = heaptracker.adr2int(llmemory.cast_ptr_to_adr(vtable)) assert heaptracker.vtable2descr(cpu, vtable_int) == op1.args[0]
def test_malloc_new_with_destructor(): vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) S = lltype.GcStruct("S", ("parent", rclass.OBJECT), rtti=True) DESTRUCTOR = lltype.FuncType([lltype.Ptr(S)], lltype.Void) destructor = lltype.functionptr(DESTRUCTOR, "destructor") lltype.attachRuntimeTypeInfo(S, destrptr=destructor) heaptracker.set_testing_vtable_for_gcstruct(S, vtable, "S") v = varoftype(lltype.Ptr(S)) op = SpaceOperation("malloc", [Constant(S, lltype.Void), Constant({"flavor": "gc"}, lltype.Void)], v) tr = Transformer(FakeCPU(), FakeResidualCallControl()) oplist = tr.rewrite_operation(op) op0, op1 = oplist assert op0.opname == "residual_call_r_r" assert op0.args[0].value == "alloc_with_del" # pseudo-function as a str assert list(op0.args[1]) == [] assert op1.opname == "-live-" assert op1.args == []
@staticmethod def _new(): return lltype.malloc(NODE) # ____________________________________________________________ # Run 3: all the tests use lltype.malloc to make a NODE2 # (same as Run 2 but it is part of the OBJECT hierarchy) NODE2 = lltype.GcStruct( "NODE2", ("parent", rclass.OBJECT), ("floatval", lltype.Float), ("value", lltype.Signed), ("extra", lltype.Signed) ) vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) heaptracker.set_testing_vtable_for_gcstruct(NODE2, vtable2, "NODE2") class TestLLtype_Object(VirtualTests, LLJitMixin): _new_op = "new_with_vtable" _field_prefix = "" @staticmethod def _new(): p = lltype.malloc(NODE2) p.parent.typeptr = vtable2 return p # misc
@staticmethod def _new(): return lltype.malloc(NODE) # ____________________________________________________________ # Run 3: all the tests use lltype.malloc to make a NODE2 # (same as Run 2 but it is part of the OBJECT hierarchy) NODE2 = lltype.GcStruct('NODE2', ('parent', rclass.OBJECT), ('floatval', lltype.Float), ('value', lltype.Signed), ('extra', lltype.Signed)) vtable2 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) heaptracker.set_testing_vtable_for_gcstruct(NODE2, vtable2, 'NODE2') class TestLLtype_Object(VirtualTests, LLJitMixin): _new_op = 'new_with_vtable' _field_prefix = '' @staticmethod def _new(): p = lltype.malloc(NODE2) p.parent.typeptr = vtable2 return p # misc