def test_simple_cast_pointer(self): GCS1 = lltype.GcStruct('s1', ('x', lltype.Signed)) GCS2 = lltype.GcStruct('s2', ('sub', GCS1), ('y', lltype.Signed)) PGCS1 = lltype.Ptr(GCS1) PGCS2 = lltype.Ptr(GCS2) def ll1(): s2 = lltype.malloc(GCS2) return lltype.cast_pointer(PGCS1, s2) hs = self.hannotate(ll1, []) assert isinstance(hs, SomeLLAbstractContainer) assert hs.concretetype == PGCS1 def ll1(): s2 = lltype.malloc(GCS2) s1 = s2.sub return lltype.cast_pointer(PGCS2, s1) hs = self.hannotate(ll1, []) assert isinstance(hs, SomeLLAbstractContainer) assert hs.concretetype == PGCS2
def test_interior_ptr(self): py.test.skip("llptr support not really useful any more") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('s', S)) def f(x): t = lltype.malloc(T) t.s.x = x return t.s.x graph = self.check(f, [int], [42], 42)
def test_deallocator_simple(): S = lltype.GcStruct("S", ('x', lltype.Signed)) dgraph, t = make_deallocator(S) ops = [] for block in dgraph.iterblocks(): ops.extend([op for op in block.operations if op.opname != 'same_as']) # XXX assert len(ops) == 1 op = ops[0] assert op.opname == 'gc_free'
def test_simple_barrier(): S = lltype.GcStruct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('s', lltype.Ptr(S))) def f(): s1 = lltype.malloc(S) s1.x = 1 s2 = lltype.malloc(S) s2.x = 2 t = lltype.malloc(T) t.s = s1 t.s = s2 return t t, transformer = rtype_and_transform(f, [], RefcountingGCTransformer, check=False) graph = graphof(t, f) ops = getops(graph) assert len(ops['getfield']) == 2 assert len(ops['bare_setfield']) == 4
def test_write_barrier_support_setarrayitem(): PTR_TYPE2 = lltype.Ptr(lltype.GcStruct('T', ('y', lltype.Signed))) ARRAYPTR = lltype.Ptr(lltype.GcArray(PTR_TYPE2)) write_barrier_check( SpaceOperation("setarrayitem", [ varoftype(ARRAYPTR), varoftype(lltype.Signed), varoftype(PTR_TYPE2) ], varoftype(lltype.Void)))
def test_fakeaddress2(): S1 = lltype.GcStruct("S1", ("x", lltype.Signed), ("y", lltype.Signed)) PtrS1 = lltype.Ptr(S1) S2 = lltype.GcStruct("S2", ("s", S1)) s2 = lltype.malloc(S2) s2.s.x = 123 s2.s.y = 456 addr_s2 = llmemory.cast_ptr_to_adr(s2) addr_s1 = addr_s2 + llmemory.FieldOffset(S2, 's') def f(): s1 = llmemory.cast_adr_to_ptr(addr_s1, PtrS1) return s1.x + s1.y fn = compile_function(f, []) assert fn() == 579
def test_cancollect(): S = lltype.GcStruct('S', ('x', lltype.Signed)) def g(): lltype.malloc(S, zero=True) t = rtype(g, []) gg = graphof(t, g) assert CollectAnalyzer(t).analyze_direct_call(gg)
def test_gc_malloc(self): S = lltype.GcStruct('S', ('x', lltype.Signed)) sizedescr = get_size_descr(self.gc_ll_descr, S) p = self.gc_ll_descr.gc_malloc(sizedescr) assert self.llop1.record == [("fixedsize", repr(sizedescr.size), sizedescr.tid, p)] assert repr(self.gc_ll_descr.args_for_new(sizedescr)) == repr( [sizedescr.size, sizedescr.tid])
def test_ptr_ne_diff_struct(self): S = lltype.GcStruct('S') def fn(): s1 = lltype.malloc(S) s2 = lltype.malloc(S) return lloperation.llop.ptr_ne(lltype.Bool, s1, s2) self.check(fn, [], [], True, expected_mallocs=0)
def test_interior_ptr_with_field_and_index(self): py.test.skip("llptr support not really useful any more") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('items', lltype.Array(S))) def f(x): t = lltype.malloc(T, 1) t.items[0].x = x return t.items[0].x graph = self.check(f, [int], [42], 42)
def create_lowlevel_type(self): entry_methods = { "valid": LLOrderedDict.ll_valid_from_flag, "everused": LLOrderedDict.ll_everused_from_flag, "mark_deleted": LLOrderedDict.ll_mark_deleted_in_flag, "must_clear_key": self._must_clear(self.key_repr.lowleveltype), "must_clear_value": self._must_clear(self.value_repr.lowleveltype), } fields = [ ("key", self.key_repr.lowleveltype), ("value", self.value_repr.lowleveltype), ("next", lltype.Signed), ("prev", lltype.Signed), ("everused", lltype.Bool), ("valid", lltype.Bool), ] fast_hash_func = None if not self.hash_func_repr: fast_hash_func = self.key_repr.get_ll_hash_function() if fast_hash_func is None: fields.append(("hash", lltype.Signed)) entry_methods["hash"] = LLOrderedDict.ll_hash_from_cache else: entry_methods["hash"] = LLOrderedDict.ll_hash_recompute entry_methods["fast_hash_func"] = fast_hash_func DICTENTRY = lltype.Struct("ORDEREDDICTENTRY", *fields) fields = [ ("num_items", lltype.Signed), ("resize_counter", lltype.Signed), ("first_entry", lltype.Signed), ("last_entry", lltype.Signed), ("entries", lltype.Ptr(lltype.GcArray(DICTENTRY, adtmeths=entry_methods))), ] dict_methods = {} if self.eq_func_repr and self.hash_func_repr: dict_methods["paranoia"] = True dict_methods["hashkey"] = LLOrderedDict.ll_hashkey_custom dict_methods["keyeq"] = LLOrderedDict.ll_keyeq_custom dict_methods["r_hashkey"] = self.hash_func_repr dict_methods["r_keyeq"] = self.eq_func_repr fields.append(("hashkey_func", self.hash_func_repr.lowleveltype)) fields.append(("keyeq_func", self.eq_func_repr.lowleveltype)) else: dict_methods["paranoia"] = False dict_methods["hashkey"] = lltype.staticAdtMethod( self.key_repr.get_ll_hash_function()) ll_keyeq = self.key_repr.get_ll_eq_function() if ll_keyeq is not None: ll_keyeq = lltype.staticAdtMethod(ll_keyeq) dict_methods["keyeq"] = ll_keyeq DICT = lltype.GcStruct("ORDEREDDICT", *fields, adtmeths=dict_methods) return lltype.Ptr(DICT)
def test_ptr_eq_null_left(self): S = lltype.GcStruct('S') def fn(): s = lltype.malloc(S) null = lltype.nullptr(S) return lloperation.llop.ptr_eq(lltype.Bool, s, null) self.check(fn, [], [], False, expected_mallocs=0)
def test_get_call_descr_translated(): c1 = GcCache(True) T = lltype.GcStruct('T') U = lltype.GcStruct('U', ('x', lltype.Signed)) descr3 = get_call_descr(c1, [lltype.Ptr(T)], lltype.Ptr(U)) assert isinstance(descr3.get_result_size(), Symbolic) assert descr3.get_result_type() == history.REF assert descr3.arg_classes == "r" # descr4 = get_call_descr(c1, [lltype.Float, lltype.Float], lltype.Float) assert isinstance(descr4.get_result_size(), Symbolic) assert descr4.get_result_type() == history.FLOAT assert descr4.arg_classes == "ff" # descr5 = get_call_descr(c1, [lltype.SingleFloat], lltype.SingleFloat) assert isinstance(descr5.get_result_size(), Symbolic) assert descr5.get_result_type() == "S" assert descr5.arg_classes == "S"
def test_weakref(): S1 = lltype.GcStruct('S1', ('x',lltype.Signed)) S = lltype.GcStruct('S', ('s1', S1)) s = lltype.malloc(S) s1 = lltype.cast_pointer(lltype.Ptr(S1), s) w = weakref_create(s) assert weakref_deref(lltype.Ptr(S), w) == s assert weakref_deref(lltype.Ptr(S1), w) == s1 # check that the weakref stays alive even if there are only # cast_pointer'ed references around del s import gc; gc.collect() assert weakref_deref(lltype.Ptr(S1), w) == s1 # now really kill the structure del s1 import gc; gc.collect() assert weakref_deref(lltype.Ptr(S), w) == lltype.nullptr(S) assert weakref_deref(lltype.Ptr(S1), w) == lltype.nullptr(S1)
def define_hash_varsized(self): S = lltype.GcStruct('S', ('abc', lltype.Signed), ('def', lltype.Array(lltype.Signed))) s = lltype.malloc(S, 3, zero=True) h_s = lltype.identityhash(s) def f(): return lltype.identityhash(s) - h_s # != 0 (so far), # because S is a varsized structure. return f
def test_unwrap(): S = lltype.GcStruct('S') p = lltype.malloc(S) po = lltype.cast_opaque_ptr(llmemory.GCREF, p) assert unwrap(lltype.Void, BoxInt(42)) is None assert unwrap(lltype.Signed, BoxInt(42)) == 42 assert unwrap(lltype.Char, BoxInt(42)) == chr(42) assert unwrap(lltype.Float, BoxFloat(42.5)) == 42.5 assert unwrap(lltype.Ptr(S), BoxPtr(po)) == p
def test_getfield_gc_pure(): S = lltype.GcStruct('S', ('x', lltype.Char), hints={'immutable': True}) v1 = varoftype(lltype.Ptr(S)) v2 = varoftype(lltype.Char) op = SpaceOperation('getfield', [v1, Constant('x', lltype.Void)], v2) op1 = Transformer(FakeCPU()).rewrite_operation(op) assert op1.opname == 'getfield_gc_i_pure' assert op1.args == [v1, ('fielddescr', S, 'x')] assert op1.result == v2
def test_ptr_ne_null_right(self): S = lltype.GcStruct('S') def fn(): s = lltype.malloc(S) null = lltype.nullptr(S) return lloperation.llop.ptr_ne(lltype.Bool, null, s) self.check(fn, [], [], True, expected_mallocs=0)
def test_fakeaccessor(): S = lltype.GcStruct("S", ("x", lltype.Signed), ("y", lltype.Signed)) s = lltype.malloc(S) s.x = 123 s.y = 456 adr = cast_ptr_to_adr(s) adr += FieldOffset(S, "y") assert adr.signed[0] == 456 adr.signed[0] = 789 assert s.y == 789 A = lltype.GcArray(lltype.Signed) a = lltype.malloc(A, 5) a[3] = 123 adr = cast_ptr_to_adr(a) assert (adr + ArrayLengthOffset(A)).signed[0] == 5 assert (adr + ArrayItemsOffset(A)).signed[3] == 123 (adr + ArrayItemsOffset(A)).signed[3] = 456 assert a[3] == 456 adr1000 = (adr + ArrayItemsOffset(A) + ItemOffset(lltype.Signed, 1000)) assert adr1000.signed[-997] == 456 A = lltype.GcArray(lltype.Char) a = lltype.malloc(A, 5) a[3] = '*' adr = cast_ptr_to_adr(a) assert (adr + ArrayLengthOffset(A)).signed[0] == 5 assert (adr + ArrayItemsOffset(A)).char[3] == '*' (adr + ArrayItemsOffset(A)).char[3] = '+' assert a[3] == '+' adr1000 = (adr + ArrayItemsOffset(A) + ItemOffset(lltype.Char, 1000)) assert adr1000.char[-997] == '+' T = lltype.FixedSizeArray(lltype.Char, 10) S = lltype.GcStruct('S', ('z', lltype.Ptr(T))) s = lltype.malloc(S) s.z = lltype.malloc(T, immortal=True) adr = cast_ptr_to_adr(s) assert (adr + offsetof(S, 'z')).address[0] == cast_ptr_to_adr(s.z) (adr + offsetof(S, 'z')).address[0] = NULL assert s.z == lltype.nullptr(T) t = lltype.malloc(T, immortal=True) (adr + offsetof(S, 'z')).address[0] = cast_ptr_to_adr(t) assert s.z == t
def test_something_more(): S = lltype.GcStruct("S", ('x', lltype.Signed)) def f(x): s = lltype.malloc(S) s.x = x return s.x fn = compile_func(f, [int]) assert fn(1) == 1
def test_raw_memcopy(): T = lltype.GcStruct('T', ('x', lltype.Signed)) t1 = lltype.malloc(T) t2 = lltype.malloc(T) t1.x = 1 t2.x = 2 at1 = cast_ptr_to_adr(t1) at2 = cast_ptr_to_adr(t2) raw_memcopy(at1, at2, sizeof(T)) assert t2.x == 1
def test_opaque(): S = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed)) O = lltype.GcOpaqueType('O') s = lltype.malloc(S) adr = cast_ptr_to_adr(s) o = cast_adr_to_ptr(adr, lltype.Ptr(O)) assert lltype.cast_opaque_ptr(lltype.Ptr(S), o) == s adr2 = cast_ptr_to_adr(o) s2 = cast_adr_to_ptr(adr2, lltype.Ptr(S)) assert s2 == s
def test_do_write_barrier(self): gc_ll_descr = self.gc_ll_descr R = lltype.GcStruct('R') S = lltype.GcStruct('S', ('r', lltype.Ptr(R))) s = lltype.malloc(S) r = lltype.malloc(R) s_hdr = gc_ll_descr.gcheaderbuilder.new_header(s) s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) r_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, r) s_adr = llmemory.cast_ptr_to_adr(s) r_adr = llmemory.cast_ptr_to_adr(r) # s_hdr.tid &= ~gc_ll_descr.GCClass.JIT_WB_IF_FLAG gc_ll_descr.do_write_barrier(s_gcref, r_gcref) assert self.llop1.record == [] # not called # s_hdr.tid |= gc_ll_descr.GCClass.JIT_WB_IF_FLAG gc_ll_descr.do_write_barrier(s_gcref, r_gcref) assert self.llop1.record == [('barrier', s_adr)]
def test_is_pure(): from pypy.objspace.flow.model import Variable, Constant assert llop.bool_not.is_pure([Variable()]) assert llop.debug_assert.is_pure([Variable()]) assert not llop.int_add_ovf.is_pure([Variable(), Variable()]) # S1 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed)) v_s1 = Variable() v_s1.concretetype = lltype.Ptr(S1) assert not llop.setfield.is_pure([v_s1, Constant('x'), Variable()]) assert not llop.getfield.is_pure([v_s1, Constant('y')]) # A1 = lltype.GcArray(lltype.Signed) v_a1 = Variable() v_a1.concretetype = lltype.Ptr(A1) assert not llop.setarrayitem.is_pure([v_a1, Variable(), Variable()]) assert not llop.getarrayitem.is_pure([v_a1, Variable()]) assert llop.getarraysize.is_pure([v_a1]) # S2 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed), hints={'immutable': True}) v_s2 = Variable() v_s2.concretetype = lltype.Ptr(S2) assert not llop.setfield.is_pure([v_s2, Constant('x'), Variable()]) assert llop.getfield.is_pure([v_s2, Constant('y')]) # A2 = lltype.GcArray(lltype.Signed, hints={'immutable': True}) v_a2 = Variable() v_a2.concretetype = lltype.Ptr(A2) assert not llop.setarrayitem.is_pure([v_a2, Variable(), Variable()]) assert llop.getarrayitem.is_pure([v_a2, Variable()]) assert llop.getarraysize.is_pure([v_a2]) # accessor = rclass.FieldListAccessor() S3 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed), hints={'immutable_fields': accessor}) accessor.initialize(S3, ['x']) v_s3 = Variable() v_s3.concretetype = lltype.Ptr(S3) assert not llop.setfield.is_pure([v_s3, Constant('x'), Variable()]) assert not llop.setfield.is_pure([v_s3, Constant('y'), Variable()]) assert llop.getfield.is_pure([v_s3, Constant('x')]) assert not llop.getfield.is_pure([v_s3, Constant('y')])
def test_gcref_comparisons_back_and_forth(self): NODE = lltype.GcStruct('NODE') node = lltype.malloc(NODE) ref1 = lltype.cast_opaque_ptr(llmemory.GCREF, node) numb = rffi.cast(lltype.Signed, ref1) ref2 = rffi.cast(llmemory.GCREF, numb) assert ref1 == ref2 assert ref2 == ref1 assert not (ref1 != ref2) assert not (ref2 != ref1)
def test_multiple_exits(): S = lltype.GcStruct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('y', lltype.Signed)) def f(n): c = lltype.malloc(S) d = lltype.malloc(T) d.y = 1 e = lltype.malloc(T) e.y = 2 if n: x = d else: x = e return x.y fn = compile_func(f, [int]) assert fn(1) == 1 assert fn(0) == 2
def test_interior_ptr_with_field_and_index(self): S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('items', lltype.Array(S))) def f(x): t = lltype.malloc(T, 1) t.items[0].x = x return t.items[0].x graph = self.check(f, [int], [42], 42)
def test_direct_fieldptr(self): S = lltype.GcStruct('S', ('x', lltype.Signed)) def fn(): s = lltype.malloc(S) s.x = 11 p = lltype.direct_fieldptr(s, 'x') return p[0] self.check(fn, [], [], 11)
def define_ref_from_rawmalloced_to_regular(cls): import gc S = lltype.GcStruct('S', ('x', lltype.Signed)) A = lltype.GcStruct('A', ('p', lltype.Ptr(S)), ('a', lltype.Array(lltype.Char))) def setup(j): p = lltype.malloc(S) p.x = j*2 lst = lltype.malloc(A, j) # the following line generates a write_barrier call at the moment, # which is important because the 'lst' can be allocated directly # in generation 2. This can only occur with varsized mallocs. lst.p = p return lst def f(i, j): lst = setup(j) gc.collect() return lst.p.x return f
def test_malloc_new(): S = lltype.GcStruct('S') v = varoftype(lltype.Ptr(S)) op = SpaceOperation( 'malloc', [Constant(S, lltype.Void), Constant({'flavor': 'gc'}, lltype.Void)], v) op1 = Transformer(FakeCPU()).rewrite_operation(op) assert op1.opname == 'new' assert op1.args == [('sizedescr', S)]