def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE, translated_to_c=True): self.gcheaderbuilder = GCHeaderBuilder(self.HDR) self.AddressStack = get_address_stack(chunk_size) self.AddressDeque = get_address_deque(chunk_size) self.AddressDict = AddressDict self.null_address_dict = null_address_dict self.config = config assert isinstance(translated_to_c, bool) self.translated_to_c = translated_to_c
def test_shrink_obj(): from rpython.memory.gcheader import GCHeaderBuilder HDR = lltype.Struct('HDR', ('h', lltype.Signed)) gcheaderbuilder = GCHeaderBuilder(HDR) size_gc_header = gcheaderbuilder.size_gc_header S = lltype.GcStruct('S', ('x', lltype.Signed), ('a', lltype.Array(lltype.Signed))) myarenasize = 200 a = arena_malloc(myarenasize, False) arena_reserve(a, size_gc_header + llmemory.sizeof(S, 10)) arena_shrink_obj(a, size_gc_header + llmemory.sizeof(S, 5)) arena_reset(a, size_gc_header + llmemory.sizeof(S, 5), False)
def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE, translated_to_c=True, hooks=None): self.gcheaderbuilder = GCHeaderBuilder(self.HDR) self.AddressStack = get_address_stack(chunk_size) self.AddressDeque = get_address_deque(chunk_size) self.AddressDict = AddressDict self.null_address_dict = null_address_dict self.config = config assert isinstance(translated_to_c, bool) self.translated_to_c = translated_to_c if hooks is None: hooks = GcHooks() # the default hooks are empty self.hooks = hooks
def _setup_gcclass(self): from rpython.memory.gcheader import GCHeaderBuilder self.GCClass = self.layoutbuilder.GCClass self.moving_gc = self.GCClass.moving_gc self.malloc_zero_filled = self.GCClass.malloc_zero_filled self.HDRPTR = lltype.Ptr(self.GCClass.HDR) self.gcheaderbuilder = GCHeaderBuilder(self.HDRPTR.TO) self.max_size_of_young_obj = self.GCClass.JIT_max_size_of_young_obj() self.minimal_size_in_nursery=self.GCClass.JIT_minimal_size_in_nursery() # for the fast path of mallocs, the following must be true, at least assert self.GCClass.inline_simple_malloc assert self.GCClass.inline_simple_malloc_varsize
def test_raw_free_with_hdr(): from rpython.memory.gcheader import GCHeaderBuilder HDR = lltype.Struct('h', ('t', lltype.Signed)) gh = GCHeaderBuilder(HDR).size_gc_header A = lltype.GcArray(lltype.Signed) adr = raw_malloc(gh + sizeof(A, 10)) p_a = cast_adr_to_ptr(adr + gh, lltype.Ptr(A)) p_a[0] = 1 adr = cast_ptr_to_adr(p_a) - gh raw_free(adr) py.test.raises(RuntimeError, "p_a[0]") py.test.raises(RuntimeError, "p_a[0] = 2") repr(adr) str(p_a) S = lltype.GcStruct('S', ('x', lltype.Signed)) adr = raw_malloc(gh + sizeof(S)) p_s = cast_adr_to_ptr(adr + gh, lltype.Ptr(S)) p_s.x = 1 adr = cast_ptr_to_adr(p_s) - gh raw_free(adr) py.test.raises(RuntimeError, "p_s.x") py.test.raises(RuntimeError, "p_s.x = 2") repr(adr) str(p_s) T = lltype.GcStruct('T', ('s', S)) adr = raw_malloc(gh + sizeof(T)) p_s = cast_adr_to_ptr(adr + gh, lltype.Ptr(S)) p_s.x = 1 adr = cast_ptr_to_adr(p_s) - gh raw_free(adr) py.test.raises(RuntimeError, "p_s.x") py.test.raises(RuntimeError, "p_s.x = 2") repr(adr) str(p_s) U = lltype.Struct('U', ('y', lltype.Signed)) T = lltype.GcStruct('T', ('x', lltype.Signed), ('u', U)) adr = raw_malloc(gh + sizeof(T)) p_t = cast_adr_to_ptr(adr + gh, lltype.Ptr(T)) p_u = p_t.u p_u.y = 1 adr = cast_ptr_to_adr(p_t) - gh raw_free(adr) py.test.raises(RuntimeError, "p_u.y") py.test.raises(RuntimeError, "p_u.y = 2") repr(adr) str(p_u)
def test_replace_object_with_stub(): from rpython.memory.gcheader import GCHeaderBuilder HDR = lltype.Struct('HDR', ('x', lltype.Signed)) S = lltype.GcStruct('S', ('y', lltype.Signed), ('z', lltype.Signed)) STUB = lltype.GcStruct('STUB', ('t', lltype.Char)) gcheaderbuilder = GCHeaderBuilder(HDR) size_gc_header = gcheaderbuilder.size_gc_header ssize = llmemory.raw_malloc_usage(llmemory.sizeof(S)) a = arena_malloc(13 * ssize, True) hdraddr = a + 3 * ssize arena_reserve(hdraddr, size_gc_header + llmemory.sizeof(S)) hdr = llmemory.cast_adr_to_ptr(hdraddr, lltype.Ptr(HDR)) hdr.x = 42 obj = llmemory.cast_adr_to_ptr(hdraddr + size_gc_header, lltype.Ptr(S)) obj.y = -5 obj.z = -6 hdraddr = llmemory.cast_ptr_to_adr(obj) - size_gc_header arena_reset(hdraddr, size_gc_header + llmemory.sizeof(S), False) arena_reserve(hdraddr, size_gc_header + llmemory.sizeof(STUB)) # check that it possible to reach the newly reserved HDR+STUB # via the header of the old 'obj' pointer, both via the existing # 'hdraddr': hdr = llmemory.cast_adr_to_ptr(hdraddr, lltype.Ptr(HDR)) hdr.x = 46 stub = llmemory.cast_adr_to_ptr(hdraddr + size_gc_header, lltype.Ptr(STUB)) stub.t = '!' # and via a (now-invalid) pointer to the old 'obj': (this is needed # because during a garbage collection there are still pointers to # the old 'obj' around to be fixed) hdraddr = llmemory.cast_ptr_to_adr(obj) - size_gc_header hdr = llmemory.cast_adr_to_ptr(hdraddr, lltype.Ptr(HDR)) assert hdr.x == 46 stub = llmemory.cast_adr_to_ptr(hdraddr + size_gc_header, lltype.Ptr(STUB)) assert stub.t == '!'
def __init__(self, translator): super(RefcountingGCTransformer, self).__init__(translator, inline=True) self.gcheaderbuilder = GCHeaderBuilder(self.HDR) gc_header_offset = self.gcheaderbuilder.size_gc_header self.deallocator_graphs_needing_transforming = [] # create incref, etc graph memoryError = MemoryError() HDRPTR = lltype.Ptr(self.HDR) def ll_incref(adr): if adr: gcheader = llmemory.cast_adr_to_ptr(adr - gc_header_offset, HDRPTR) gcheader.refcount = gcheader.refcount + 1 def ll_decref(adr, dealloc): if adr: gcheader = llmemory.cast_adr_to_ptr(adr - gc_header_offset, HDRPTR) refcount = gcheader.refcount - 1 gcheader.refcount = refcount if refcount == 0: dealloc(adr) def ll_decref_simple(adr): if adr: gcheader = llmemory.cast_adr_to_ptr(adr - gc_header_offset, HDRPTR) refcount = gcheader.refcount - 1 if refcount == 0: llop.gc_free(lltype.Void, adr) else: gcheader.refcount = refcount def ll_no_pointer_dealloc(adr): llop.gc_free(lltype.Void, adr) mh = mallocHelpers(gckind='gc') mh.allocate = llmemory.raw_malloc def ll_malloc_fixedsize(size): size = gc_header_offset + size result = mh._ll_malloc_fixedsize(size) llmemory.raw_memclear(result, size) result += gc_header_offset return result def ll_malloc_varsize_no_length(length, size, itemsize): try: fixsize = gc_header_offset + size varsize = ovfcheck(itemsize * length) tot_size = ovfcheck(fixsize + varsize) except OverflowError: raise MemoryError() result = mh._ll_malloc_fixedsize(tot_size) llmemory.raw_memclear(result, tot_size) result += gc_header_offset return result mh.ll_malloc_varsize_no_length = ll_malloc_varsize_no_length ll_malloc_varsize = mh.ll_malloc_varsize def ll_identityhash(addr): h = llmemory.cast_adr_to_int(addr) return h if self.translator: self.increfptr = self.inittime_helper(ll_incref, [llmemory.Address], lltype.Void) self.decref_ptr = self.inittime_helper( ll_decref, [llmemory.Address, lltype.Ptr(ADDRESS_VOID_FUNC)], lltype.Void) self.decref_simple_ptr = self.inittime_helper( ll_decref_simple, [llmemory.Address], lltype.Void) self.no_pointer_dealloc_ptr = self.inittime_helper( ll_no_pointer_dealloc, [llmemory.Address], lltype.Void) self.malloc_fixedsize_ptr = self.inittime_helper( ll_malloc_fixedsize, [lltype.Signed], llmemory.Address) self.malloc_varsize_no_length_ptr = self.inittime_helper( ll_malloc_varsize_no_length, [lltype.Signed] * 3, llmemory.Address) self.malloc_varsize_ptr = self.inittime_helper( ll_malloc_varsize, [lltype.Signed] * 4, llmemory.Address) self.identityhash_ptr = self.inittime_helper(ll_identityhash, [llmemory.Address], lltype.Signed, inline=False) self.mixlevelannotator.finish() self.mixlevelannotator.backend_optimize() # cache graphs: self.decref_funcptrs = {} self.static_deallocator_funcptrs = {} self.dynamic_deallocator_funcptrs = {} self.queryptr2dynamic_deallocator_funcptr = {}