Beispiel #1
0
def test_gc_offsets():
    STRUCT = lltype.GcStruct('S1', ('x', lltype.Signed), ('y', lltype.Char))
    ARRAY = lltype.GcArray(lltype.Signed)
    s1 = llarena.round_up_for_allocation(llmemory.sizeof(STRUCT))
    s2 = llmemory.offsetof(STRUCT, 'x')
    s3 = llmemory.ArrayLengthOffset(ARRAY)
    s4 = llmemory.sizeof(ARRAY, 0)
    s5 = llmemory.ArrayItemsOffset(ARRAY)

    def fn():
        return (s1 * 100000000 + s2 * 1000000 + s3 * 10000 + s4 * 100 + s5)

    mod, f = compile_test(fn, [], gcpolicy="semispace")
    res = f()
    i1 = (res // 100000000) % 100
    i2 = (res // 1000000) % 100
    i3 = (res // 10000) % 100
    i4 = (res // 100) % 100
    i5 = (res // 1) % 100
    assert i1 % 4 == 0
    assert 12 <= i1 <= 24
    assert 4 <= i2 <= i1 - 8
    assert 4 <= i3 <= 12
    assert i4 == i5
    assert i3 + 4 <= i5
Beispiel #2
0
def test_vararray():
    S1 = lltype.Struct('s1', ('s', lltype.Signed))
    A = lltype.Array(S1)
    S2 = lltype.GcStruct('s2', ('b', lltype.Signed), ('a', A))
    S1PTR = lltype.Ptr(S1)

    offset1 = (llmemory.offsetof(S2, 'a') + llmemory.ArrayItemsOffset(A) +
               llmemory.ItemOffset(S1, 21) + llmemory.offsetof(S1, 's'))

    offset2 = (llmemory.offsetof(S2, 'a') + llmemory.ArrayItemsOffset(A) +
               llmemory.ItemOffset(S1, 21))

    def vararray(n):
        s = lltype.malloc(S2, n)
        adr = llmemory.cast_ptr_to_adr(s)
        s.a[n].s = n
        s1 = llmemory.cast_adr_to_ptr(adr + offset2, S1PTR)
        return (adr + offset1).signed[0] + s1.s

    fn = compile_function(vararray, [int])
    assert fn(21) == 42
Beispiel #3
0
    def finish_tables(self):
        table = self.layoutbuilder.flatten_table()
        log.info("assigned %s typeids" % (len(table), ))
        log.info("added %s push/pop stack root instructions" %
                 (self.num_pushs, ))
        if self.write_barrier_ptr:
            log.info("inserted %s write barrier calls" %
                     (self.write_barrier_calls, ))

        # replace the type_info_table pointer in gcdata -- at this point,
        # the database is in principle complete, so it has already seen
        # the delayed pointer.  We need to force it to consider the new
        # array now.

        self.gcdata.type_info_table._become(table)

        # XXX because we call inputconst already in replace_malloc, we can't
        # modify the instance, we have to modify the 'rtyped instance'
        # instead.  horrors.  is there a better way?

        s_gcdata = self.translator.annotator.bookkeeper.immutablevalue(
            self.gcdata)
        r_gcdata = self.translator.rtyper.getrepr(s_gcdata)
        ll_instance = rmodel.inputconst(r_gcdata, self.gcdata).value

        addresses_of_static_ptrs = (
            self.layoutbuilder.addresses_of_static_ptrs_in_nongc +
            self.layoutbuilder.addresses_of_static_ptrs)
        log.info("found %s static roots" % (len(addresses_of_static_ptrs), ))
        additional_ptrs = self.layoutbuilder.additional_roots_sources
        log.info("additional %d potential static roots" % additional_ptrs)
        ll_static_roots_inside = lltype.malloc(lltype.Array(llmemory.Address),
                                               len(addresses_of_static_ptrs) +
                                               additional_ptrs,
                                               immortal=True)
        for i in range(len(addresses_of_static_ptrs)):
            ll_static_roots_inside[i] = addresses_of_static_ptrs[i]
        ll_instance.inst_static_root_start = llmemory.cast_ptr_to_adr(
            ll_static_roots_inside) + llmemory.ArrayItemsOffset(
                lltype.Array(llmemory.Address))
        ll_instance.inst_static_root_nongcend = ll_instance.inst_static_root_start + llmemory.sizeof(
            llmemory.Address) * len(
                self.layoutbuilder.addresses_of_static_ptrs_in_nongc)
        ll_instance.inst_static_root_end = ll_instance.inst_static_root_start + llmemory.sizeof(
            llmemory.Address) * len(addresses_of_static_ptrs)

        newgcdependencies = []
        newgcdependencies.append(ll_static_roots_inside)
        self.write_typeid_list()
        return newgcdependencies
Beispiel #4
0
def test_sizeof_array_with_no_length():
    A = lltype.GcArray(lltype.Signed, hints={'nolength': True})
    B = lltype.Array(lltype.Signed, hints={'nolength': True})
    a = lltype.malloc(A, 5, zero=True)

    arraysize = llmemory.itemoffsetof(A, 10)
    signedsize = llmemory.sizeof(lltype.Signed)
    b_items = llmemory.ArrayItemsOffset(B)

    def f():
        return (a[0] + arraysize - signedsize * 10) * 1000 + b_items

    fn = compile_function(f, [])
    res = fn()
    assert res == 0
Beispiel #5
0
def test_null_padding():
    from pypy.rpython.lltypesystem import llmemory
    from pypy.rpython.lltypesystem import rstr
    chars_offset = llmemory.FieldOffset(rstr.STR, 'chars') + \
                   llmemory.ArrayItemsOffset(rstr.STR.chars)
    # sadly, there's no way of forcing this to fail if the strings
    # are allocated in a region of memory such that they just
    # happen to get a NUL byte anyway :/ (a debug build will
    # always fail though)
    def trailing_byte(s):
        adr_s = llmemory.cast_ptr_to_adr(s)
        return (adr_s + chars_offset).char[len(s)]
    def f(x):
        r = 0
        for i in range(x):
            r += ord(trailing_byte(' '*(100-x*x)))
        return r
    fn = compile_function(f, [int])
    res = fn(10)
    assert res == 0
Beispiel #6
0
 def arrayToken(A):
     return (llmemory.ArrayLengthOffset(A),
             llmemory.ArrayItemsOffset(A),
             llmemory.ItemOffset(A.OF),
             RLLVMGenOp.kindToken(A.OF))
Beispiel #7
0
 def arrayToken(A):
     return ((llmemory.ArrayLengthOffset(A), WORD),
             llmemory.ArrayItemsOffset(A),
             llmemory.ItemOffset(A.OF))