def op_int_xor(x, y): # used in computing hashes if isinstance(x, AddressAsInt): x = llmemory.cast_adr_to_int(x.adr) if isinstance(y, AddressAsInt): y = llmemory.cast_adr_to_int(y.adr) assert is_valid_int(x) assert is_valid_int(y) return x ^ y
def op_int_xor(x, y): # used in computing hashes if isinstance(x, AddressAsInt): x = llmemory.cast_adr_to_int(x.adr) if isinstance(y, AddressAsInt): y = llmemory.cast_adr_to_int(y.adr) assert is_valid_int(x) assert is_valid_int(y) return x ^ y
def fn(n): a = llmemory.cast_ptr_to_adr(p) if n == 2: return llmemory.cast_adr_to_int(a, "emulated") elif n == 4: return llmemory.cast_adr_to_int(a, "symbolic") else: return llmemory.cast_adr_to_int(a, "forced")
def fn(n): a = llmemory.cast_ptr_to_adr(p) if n == 2: return llmemory.cast_adr_to_int(a, "emulated") elif n == 4: return llmemory.cast_adr_to_int(a, "symbolic") else: return llmemory.cast_adr_to_int(a, "forced")
def test_it_saves_a_pointer_to_whatever_address_was_given(self, space): int8_ptr = lltype.malloc(rffi.CArray(rffi.CHAR), 1, flavor='raw') adr = llmemory.cast_ptr_to_adr(int8_ptr) aint = llmemory.cast_adr_to_int(adr, mode='forced') w_ptr_obj = space.execute(""" ptr = FFI::Pointer.new(%s) """ % aint) adr = llmemory.cast_ptr_to_adr(w_ptr_obj.ptr) assert llmemory.cast_adr_to_int(adr, mode='forced') == aint lltype.free(int8_ptr, flavor='raw') assert not aint in ALLOCATED
def test_it_saves_a_pointer_to_whatever_address_was_given(self, space): int8_ptr = lltype.malloc(rffi.CArray(rffi.CHAR), 1, flavor='raw') adr = llmemory.cast_ptr_to_adr(int8_ptr) aint = llmemory.cast_adr_to_int(adr, mode='forced') w_ptr_obj = space.execute(""" ptr = FFI::Pointer.new(%s) """ % aint) adr = llmemory.cast_ptr_to_adr(w_ptr_obj.ptr) assert llmemory.cast_adr_to_int(adr, mode='forced') == aint lltype.free(int8_ptr, flavor='raw') assert not aint in ALLOCATED
def test_address_eq_as_int(): a = arena_malloc(50, False) arena_reserve(a, precomputed_size) p = llmemory.cast_adr_to_ptr(a, SPTR) a1 = llmemory.cast_ptr_to_adr(p) assert a == a1 assert not (a != a1) assert (a + 1) != a1 assert not ((a + 1) == a1) py.test.skip("cast_adr_to_int() is hard to get consistent") assert llmemory.cast_adr_to_int(a) == llmemory.cast_adr_to_int(a1) assert llmemory.cast_adr_to_int(a + 1) == llmemory.cast_adr_to_int(a1) + 1
def test_address_eq_as_int(): a = arena_malloc(50, False) arena_reserve(a, precomputed_size) p = llmemory.cast_adr_to_ptr(a, SPTR) a1 = llmemory.cast_ptr_to_adr(p) assert a == a1 assert not (a != a1) assert (a+1) != a1 assert not ((a+1) == a1) py.test.skip("cast_adr_to_int() is hard to get consistent") assert llmemory.cast_adr_to_int(a) == llmemory.cast_adr_to_int(a1) assert llmemory.cast_adr_to_int(a+1) == llmemory.cast_adr_to_int(a1) + 1
def id(self, ptr): # Default implementation for id(), assuming that "external" objects # never move. Overriden in the HybridGC. obj = llmemory.cast_ptr_to_adr(ptr) # is it a tagged pointer? or an external object? if not self.is_valid_gc_object(obj) or self._is_external(obj): return llmemory.cast_adr_to_int(obj) # tagged pointers have ids of the form 2n + 1 # external objects have ids of the form 4n (due to word alignment) # self._compute_id returns addresses of the form 2n + 1 # if we multiply by 2, we get ids of the form 4n + 2, thus we get no # clashes return llmemory.cast_adr_to_int(self._compute_id(obj)) * 2
def test_it_can_also_be_called_with_a_type_size(self, space): int16_ptr = lltype.malloc(rffi.CArray(rffi.SHORT), 1, flavor='raw') adr = llmemory.cast_ptr_to_adr(int16_ptr) aint = llmemory.cast_adr_to_int(adr, mode='forced') # be careful: the first argument is the type size and the second the # address, not vice versa ptr_obj = space.execute(""" ptr = FFI::Pointer.new(2, %s) """ % aint) type_size = space.send(ptr_obj, 'type_size') assert self.unwrap(space, type_size) == 2 adr = llmemory.cast_ptr_to_adr(ptr_obj.ptr) assert llmemory.cast_adr_to_int(adr, mode='forced') == aint lltype.free(int16_ptr, flavor='raw') assert not aint in ALLOCATED
def test_it_can_also_be_called_with_a_type_size(self, space): int16_ptr = lltype.malloc(rffi.CArray(rffi.SHORT), 1, flavor='raw') adr = llmemory.cast_ptr_to_adr(int16_ptr) aint = llmemory.cast_adr_to_int(adr, mode='forced') # be careful: the first argument is the type size and the second the # address, not vice versa ptr_obj = space.execute(""" ptr = FFI::Pointer.new(2, %s) """ % aint) type_size = space.send(ptr_obj, 'type_size') assert self.unwrap(space, type_size) == 2 adr = llmemory.cast_ptr_to_adr(ptr_obj.ptr) assert llmemory.cast_adr_to_int(adr, mode='forced') == aint lltype.free(int16_ptr, flavor='raw') assert not aint in ALLOCATED
def id(self, ptr): # Default implementation for id(), assuming that "external" objects # never move. Overriden in the HybridGC. obj = llmemory.cast_ptr_to_adr(ptr) # is it a tagged pointer? or an external object? if not self.is_valid_gc_object(obj) or self._is_external(obj): return llmemory.cast_adr_to_int(obj) # tagged pointers have ids of the form 2n + 1 # external objects have ids of the form 4n (due to word alignment) # self._compute_id returns addresses of the form 2n + 1 # if we multiply by 2, we get ids of the form 4n + 2, thus we get no # clashes return llmemory.cast_adr_to_int(self._compute_id(obj)) * 2
def walk_stack_root(invoke, arg0, arg1, arg2, start, addr, is_minor): skip = 0 while addr != start: addr -= sizeofaddr #XXX reintroduce support for tagged values? #if gc.points_to_valid_gc_object(addr): # callback(gc, addr) if skip & 1 == 0: content = addr.address[0] n = llmemory.cast_adr_to_int(content) if n & 1 == 0: if content: # non-0, non-odd: a regular ptr invoke(arg0, arg1, arg2, addr) else: # odd number: a skip bitmask if n > 0: # initially, an unmarked value if is_minor: newcontent = llmemory.cast_int_to_adr(-n) addr.address[0] = newcontent # mark skip = n else: # a marked value if is_minor: return skip = -n skip >>= 1
def test_varsized_from_stack(self): expected = {} def verify(): for (index, index2), value in expected.items(): assert self.stackroots[index][index2].x == value x = 0 for i in range(40): assert 'DEAD' not in repr(self.stackroots) a = self.malloc(VAR, i) assert 'DEAD' not in repr(a) self.stackroots.append(a) print 'ADDED TO STACKROOTS:', llmemory.cast_adr_to_int( llmemory.cast_ptr_to_adr(a)) assert 'DEAD' not in repr(self.stackroots) for j in range(5): assert 'DEAD' not in repr(self.stackroots) p = self.malloc(S) assert 'DEAD' not in repr(self.stackroots) p.x = x index = x % len(self.stackroots) if index > 0: index2 = (x / len(self.stackroots)) % index a = self.stackroots[index] assert len(a) == index self.writearray(a, index2, p) expected[index, index2] = x x += 1291 verify() self.gc.collect() verify() self.gc.collect() verify()
def test_varsized_from_stack(self): expected = {} def verify(): for (index, index2), value in expected.items(): assert self.stackroots[index][index2].x == value x = 0 for i in range(40): assert 'DEAD' not in repr(self.stackroots) a = self.malloc(VAR, i) assert 'DEAD' not in repr(a) self.stackroots.append(a) print 'ADDED TO STACKROOTS:', llmemory.cast_adr_to_int( llmemory.cast_ptr_to_adr(a)) assert 'DEAD' not in repr(self.stackroots) for j in range(5): assert 'DEAD' not in repr(self.stackroots) p = self.malloc(S) assert 'DEAD' not in repr(self.stackroots) p.x = x index = x % len(self.stackroots) if index > 0: index2 = (x / len(self.stackroots)) % index a = self.stackroots[index] assert len(a) == index self.writearray(a, index2, p) expected[index, index2] = x x += 1291 verify() self.gc.collect() verify() self.gc.collect() verify()
def adr2int(addr): """ Cast an address to an int. Returns an AddressAsInt object which can be cast back to an address. """ return llmemory.cast_adr_to_int(addr, "symbolic")
def start_of_page(addr, page_size): """Return the address of the start of the page that contains 'addr'.""" if we_are_translated(): offset = llmemory.cast_adr_to_int(addr) % page_size return addr - offset else: return _start_of_page_untranslated(addr, page_size)
def start_of_page(addr, page_size): """Return the address of the start of the page that contains 'addr'.""" if we_are_translated(): offset = llmemory.cast_adr_to_int(addr) % page_size return addr - offset else: return _start_of_page_untranslated(addr, page_size)
def writeobj(self, obj): gc = self.gc typeid = gc.get_type_id(obj) self.write(llmemory.cast_adr_to_int(obj)) self.write(gc.get_member_index(typeid)) self.write(gc.get_size_incl_hash(obj)) gc.trace(obj, self._writeref, None) self.write(-1)
def writeobj(self, obj): gc = self.gc typeid = gc.get_type_id(obj) self.write(llmemory.cast_adr_to_int(obj)) self.write(gc.get_member_index(typeid)) self.write(gc.get_size_incl_hash(obj)) gc.trace(obj, self._writeref, None) self.write(-1)
def ptr2int(ptr): """ Cast a pointer to int. Returns an AddressAsInt object. """ addr = llmemory.cast_ptr_to_adr(ptr) return llmemory.cast_adr_to_int(addr, "symbolic")
def test_repr_ll2ctypes(): ptr = lltype.malloc(rffi.VOIDPP.TO, 10, flavor='raw') # force it to be a ll2ctypes object ptr = rffi.cast(rffi.VOIDPP, rffi.cast(rffi.LONG, ptr)) adr = llmemory.cast_ptr_to_adr(ptr) lltype.free(ptr, flavor='raw') intval = llmemory.cast_adr_to_int(adr, 'symbolic') box = BoxInt(intval) s = box.repr_rpython() assert s.startswith('12345/') # the arbitrary hash value used by
def test_repr_ll2ctypes(): ptr = lltype.malloc(rffi.VOIDPP.TO, 10, flavor='raw') # force it to be a ll2ctypes object ptr = rffi.cast(rffi.VOIDPP, rffi.cast(rffi.LONG, ptr)) adr = llmemory.cast_ptr_to_adr(ptr) lltype.free(ptr, flavor='raw') intval = llmemory.cast_adr_to_int(adr, 'symbolic') box = BoxInt(intval) s = box.repr_rpython() assert s.startswith('12345/') # the arbitrary hash value used by
def make_hashable_int(i): from rpython.rtyper.lltypesystem.ll2ctypes import NotCtypesAllocatedStructure if not we_are_translated() and isinstance(i, llmemory.AddressAsInt): # Warning: such a hash changes at the time of translation adr = heaptracker.int2adr(i) try: return llmemory.cast_adr_to_int(adr, "emulated") except NotCtypesAllocatedStructure: return 12345 # use an arbitrary number for the hash return i
def make_hashable_int(i): from rpython.rtyper.lltypesystem.ll2ctypes import NotCtypesAllocatedStructure if not we_are_translated() and isinstance(i, llmemory.AddressAsInt): # Warning: such a hash changes at the time of translation adr = int2adr(i) try: return llmemory.cast_adr_to_int(adr, "emulated") except NotCtypesAllocatedStructure: return 12345 # use an arbitrary number for the hash return i
def getvtable(cpu, S=None): cls1 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) cls1.subclassrange_min = 1 cls1.subclassrange_max = 3 if S is not None: descr = cpu.sizeof(S) if not hasattr(cpu.tracker, '_all_size_descrs_with_vtable'): cpu.tracker._all_size_descrs_with_vtable = [] cpu.tracker._all_size_descrs_with_vtable.append(descr) descr._corresponding_vtable = cls1 return llmemory.cast_adr_to_int(llmemory.cast_ptr_to_adr(cls1), "symbolic")
def getvtable(cpu, S=None): cls1 = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) cls1.subclassrange_min = 1 cls1.subclassrange_max = 3 if S is not None: descr = cpu.sizeof(S) if not hasattr(cpu.tracker, '_all_size_descrs_with_vtable'): cpu.tracker._all_size_descrs_with_vtable = [] cpu.tracker._all_size_descrs_with_vtable.append(descr) descr._corresponding_vtable = cls1 return llmemory.cast_adr_to_int(llmemory.cast_ptr_to_adr(cls1), "symbolic")
def _get_object_hash(self, obj, objsize, tid): # Returns the hash of the object, which must not be GC_HASH_NOTTAKEN. gc_hash = tid & GCFLAG_HASHMASK if gc_hash == GC_HASH_HASFIELD: obj = llarena.getfakearenaaddress(obj) return (obj + objsize).signed[0] elif gc_hash == GC_HASH_TAKEN_ADDR: return llmemory.cast_adr_to_int(obj) elif gc_hash == GC_HASH_TAKEN_NURS: return self._compute_current_nursery_hash(obj) else: assert 0, "gc_hash == GC_HASH_NOTTAKEN"
def _get_object_hash(self, obj, objsize, tid): # Returns the hash of the object, which must not be GC_HASH_NOTTAKEN. gc_hash = tid & GCFLAG_HASHMASK if gc_hash == GC_HASH_HASFIELD: obj = llarena.getfakearenaaddress(obj) return (obj + objsize).signed[0] elif gc_hash == GC_HASH_TAKEN_ADDR: return llmemory.cast_adr_to_int(obj) elif gc_hash == GC_HASH_TAKEN_NURS: return self._compute_current_nursery_hash(obj) else: assert 0, "gc_hash == GC_HASH_NOTTAKEN"
def id(self, ptr): obj = llmemory.cast_ptr_to_adr(ptr) # is it a tagged pointer? if not self.is_valid_gc_object(obj): return llmemory.cast_adr_to_int(obj) if self._is_external(obj): # a prebuilt or rawmalloced object if self.is_last_generation(obj): # a generation 3 object may be one that used to live in # the semispace. So we still need to check if the object had # its id taken before. If not, we can use its address as its # id as it is not going to move any more. result = self.objects_with_id.get(obj, obj) else: # a generation 2 external object was never non-external in # the past, so it cannot be listed in self.objects_with_id. result = obj else: result = self._compute_id(obj) # common case return llmemory.cast_adr_to_int(result) * 2 # see comment in base.py
def id(self, ptr): obj = llmemory.cast_ptr_to_adr(ptr) # is it a tagged pointer? if not self.is_valid_gc_object(obj): return llmemory.cast_adr_to_int(obj) if self._is_external(obj): # a prebuilt or rawmalloced object if self.is_last_generation(obj): # a generation 3 object may be one that used to live in # the semispace. So we still need to check if the object had # its id taken before. If not, we can use its address as its # id as it is not going to move any more. result = self.objects_with_id.get(obj, obj) else: # a generation 2 external object was never non-external in # the past, so it cannot be listed in self.objects_with_id. result = obj else: result = self._compute_id(obj) # common case return llmemory.cast_adr_to_int(result) * 2 # see comment in base.py
def must_compile(self, deadframe, metainterp_sd, jitdriver_sd): jitcounter = metainterp_sd.warmrunnerdesc.jitcounter # if self.status & (self.ST_BUSY_FLAG | self.ST_TYPE_MASK) == 0: # common case: this is not a guard_value, and we are not # already busy tracing. The rest of self.status stores a # valid per-guard index in the jitcounter. hash = self.status assert hash == (self.status & self.ST_SHIFT_MASK) # # do we have the BUSY flag? If so, we're tracing right now, e.g. in an # outer invocation of the same function, so don't trace again for now. elif self.status & self.ST_BUSY_FLAG: return False # else: # we have a GUARD_VALUE that fails. from rpython.rlib.objectmodel import current_object_addr_as_int index = intmask(self.status >> self.ST_SHIFT) typetag = intmask(self.status & self.ST_TYPE_MASK) # fetch the actual value of the guard_value, possibly turning # it to an integer if typetag == self.TY_INT: intval = metainterp_sd.cpu.get_value_direct( deadframe, 'i', index) elif typetag == self.TY_REF: refval = metainterp_sd.cpu.get_value_direct( deadframe, 'r', index) intval = lltype.cast_ptr_to_int(refval) elif typetag == self.TY_FLOAT: floatval = metainterp_sd.cpu.get_value_direct( deadframe, 'f', index) intval = longlong.gethash_fast(floatval) else: assert 0, typetag if not we_are_translated(): if isinstance(intval, llmemory.AddressAsInt): intval = llmemory.cast_adr_to_int( llmemory.cast_int_to_adr(intval), "forced") hash = r_uint( current_object_addr_as_int(self) * 777767777 + intval * 1442968193) # increment = jitdriver_sd.warmstate.increment_trace_eagerness return jitcounter.tick(hash, increment)
def must_compile(self, deadframe, metainterp_sd, jitdriver_sd): jitcounter = metainterp_sd.warmrunnerdesc.jitcounter # if self.status & (self.ST_BUSY_FLAG | self.ST_TYPE_MASK) == 0: # common case: this is not a guard_value, and we are not # already busy tracing. The rest of self.status stores a # valid per-guard index in the jitcounter. hash = self.status assert hash == (self.status & self.ST_SHIFT_MASK) # # do we have the BUSY flag? If so, we're tracing right now, e.g. in an # outer invocation of the same function, so don't trace again for now. elif self.status & self.ST_BUSY_FLAG: return False # else: # we have a GUARD_VALUE that fails. from rpython.rlib.objectmodel import current_object_addr_as_int index = intmask(self.status >> self.ST_SHIFT) typetag = intmask(self.status & self.ST_TYPE_MASK) # fetch the actual value of the guard_value, possibly turning # it to an integer if typetag == self.TY_INT: intval = metainterp_sd.cpu.get_value_direct(deadframe, 'i', index) elif typetag == self.TY_REF: refval = metainterp_sd.cpu.get_value_direct(deadframe, 'r', index) intval = lltype.cast_ptr_to_int(refval) elif typetag == self.TY_FLOAT: floatval = metainterp_sd.cpu.get_value_direct(deadframe, 'f', index) intval = longlong.gethash_fast(floatval) else: assert 0, typetag if not we_are_translated(): if isinstance(intval, llmemory.AddressAsInt): intval = llmemory.cast_adr_to_int( llmemory.cast_int_to_adr(intval), "forced") hash = r_uint(current_object_addr_as_int(self) * 777767777 + intval * 1442968193) # increment = jitdriver_sd.warmstate.increment_trace_eagerness return jitcounter.tick(hash, increment)
def _writeref(self, pointer, _): obj = pointer.address[0] self.write(llmemory.cast_adr_to_int(obj)) self.add(obj)
def op_cast_adr_to_int(self, adr, mode): checkadr(adr) return llmemory.cast_adr_to_int(adr, mode)
def ll_identityhash(addr): obj = llmemory.cast_adr_to_ptr(addr, HDRPTR) h = obj.hash if h == 0: obj.hash = h = ~llmemory.cast_adr_to_int(addr) return h
def run_guards_translated(gcremovetypeptr): class A(object): pass class B(A): pass class C(B): pass def main(argv): A() B().foo = len(argv) C() return 0 t = TranslationContext() t.config.translation.gc = "minimark" t.config.translation.gcremovetypeptr = gcremovetypeptr ann = t.buildannotator() ann.build_types(main, [s_list_of_strings], main_entry_point=True) rtyper = t.buildrtyper() rtyper.specialize() classdef = ann.bookkeeper.getuniqueclassdef(B) rclass = getclassrepr(rtyper, classdef) rinstance = getinstancerepr(rtyper, classdef) LLB = rinstance.lowleveltype.TO ptr_vtable_B = rclass.getvtable() adr_vtable_B = llmemory.cast_ptr_to_adr(ptr_vtable_B) vtable_B = llmemory.cast_adr_to_int(adr_vtable_B, mode="symbolic") CPU = getcpuclass() cpu = CPU(rtyper, NoStats(), translate_support_code=True, gcdescr=get_description(t.config)) execute_token = cpu.make_execute_token(llmemory.GCREF) finaldescr = BasicFinalDescr() faildescr = BasicFailDescr() descr_B = cpu.sizeof(LLB, ptr_vtable_B) typeid_B = descr_B.get_type_id() fielddescr_B = cpu.fielddescrof(LLB, 'inst_foo') LLD = lltype.GcStruct('D', ('dd', lltype.Signed)) descr_D = cpu.sizeof(LLD) fielddescr_D = cpu.fielddescrof(LLD, 'dd') ARRAY = lltype.GcArray(lltype.Signed) arraydescr = cpu.arraydescrof(ARRAY) loop1 = parse(""" [p0] guard_class(p0, ConstInt(vtable_B), descr=faildescr) [] finish(descr=finaldescr) """, namespace={ 'finaldescr': finaldescr, 'faildescr': faildescr, 'vtable_B': vtable_B }) loop1a = parse(""" [p0] guard_nonnull_class(p0, ConstInt(vtable_B), descr=faildescr) [] finish(descr=finaldescr) """, namespace={ 'finaldescr': finaldescr, 'faildescr': faildescr, 'vtable_B': vtable_B }) loop2 = parse(""" [p0] guard_gc_type(p0, ConstInt(typeid_B), descr=faildescr) [] finish(descr=finaldescr) """, namespace={ 'finaldescr': finaldescr, 'faildescr': faildescr, 'typeid_B': typeid_B }) loop3 = parse(""" [p0] guard_is_object(p0, descr=faildescr) [] finish(descr=finaldescr) """, namespace={ 'finaldescr': finaldescr, 'faildescr': faildescr }) loop4 = parse(""" [p0] guard_subclass(p0, ConstInt(vtable_B), descr=faildescr) [] finish(descr=finaldescr) """, namespace={ 'finaldescr': finaldescr, 'faildescr': faildescr, 'vtable_B': vtable_B }) def g(): cpu.setup_once() token1 = JitCellToken() token1a = JitCellToken() token2 = JitCellToken() token3 = JitCellToken() token4 = JitCellToken() cpu.compile_loop(loop1.inputargs, loop1.operations, token1) cpu.compile_loop(loop1a.inputargs, loop1a.operations, token1a) cpu.compile_loop(loop2.inputargs, loop2.operations, token2) cpu.compile_loop(loop3.inputargs, loop3.operations, token3) cpu.compile_loop(loop4.inputargs, loop4.operations, token4) for token, p0 in [ (token1, rffi.cast(llmemory.GCREF, A())), (token1, rffi.cast(llmemory.GCREF, B())), (token1, rffi.cast(llmemory.GCREF, C())), (token1a, rffi.cast(llmemory.GCREF, A())), (token1a, lltype.nullptr(llmemory.GCREF.TO)), (token1a, rffi.cast(llmemory.GCREF, B())), (token1a, rffi.cast(llmemory.GCREF, C())), (token2, rffi.cast(llmemory.GCREF, A())), (token2, rffi.cast(llmemory.GCREF, B())), (token2, rffi.cast(llmemory.GCREF, C())), (token2, rffi.cast(llmemory.GCREF, [42, 43])), (token3, rffi.cast(llmemory.GCREF, A())), (token3, rffi.cast(llmemory.GCREF, B())), (token3, rffi.cast(llmemory.GCREF, [44, 45])), (token4, rffi.cast(llmemory.GCREF, A())), (token4, rffi.cast(llmemory.GCREF, B())), (token4, rffi.cast(llmemory.GCREF, C())), ]: frame = execute_token(token, p0) descr = cpu.get_latest_descr(frame) if descr is finaldescr: print 'match' elif descr is faildescr: print 'fail' else: print '???' # if token is token2: # guard_gc_type print int(cpu.get_actual_typeid(p0) == typeid_B) if token is token3: # guard_is_object print int(cpu.check_is_object(p0)) for p0 in [ lltype.nullptr(llmemory.GCREF.TO), rffi.cast(llmemory.GCREF, A()), rffi.cast(llmemory.GCREF, B()), rffi.cast(llmemory.GCREF, C()), rffi.cast(llmemory.GCREF, lltype.malloc(LLD)), rffi.cast(llmemory.GCREF, lltype.malloc(ARRAY, 5)), rffi.cast(llmemory.GCREF, "foobar"), rffi.cast(llmemory.GCREF, u"foobaz") ]: results = ['B', 'D', 'A', 'S', 'U'] try: cpu.protect_speculative_field(p0, fielddescr_B) except SpeculativeError: results[0] = '-' try: cpu.protect_speculative_field(p0, fielddescr_D) except SpeculativeError: results[1] = '-' try: cpu.protect_speculative_array(p0, arraydescr) except SpeculativeError: results[2] = '-' try: cpu.protect_speculative_string(p0) except SpeculativeError: results[3] = '-' try: cpu.protect_speculative_unicode(p0) except SpeculativeError: results[4] = '-' print ''.join(results) call_initial_function(t, g) cbuilder = genc.CStandaloneBuilder(t, main, t.config) cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) cbuilder.compile() data = cbuilder.cmdexec('') assert data == ( 'fail\n' 'match\n' 'fail\n' 'fail\n' 'fail\n' 'match\n' 'fail\n' 'fail\n' '0\n' 'match\n' '1\n' 'fail\n' '0\n' 'fail\n' '0\n' 'match\n' '1\n' 'match\n' '1\n' 'fail\n' '0\n' 'fail\n' 'match\n' 'match\n' '-----\n' # null '-----\n' # instance of A 'B----\n' # instance of B 'B----\n' # instance of C '-D---\n' '--A--\n' '---S-\n' '----U\n')
def ll_addrhash(addr1): return cast_adr_to_int(addr1, "forced")
def is_in_nursery(self, addr): ll_assert(llmemory.cast_adr_to_int(addr) & 1 == 0, "odd-valued (i.e. tagged) pointer unexpected here") return self.nursery <= addr < self.nursery_top
def run_guards_translated(gcremovetypeptr): class A(object): pass class B(A): pass class C(B): pass def main(argv): A(); B(); C() return 0 t = TranslationContext() t.config.translation.gc = "minimark" t.config.translation.gcremovetypeptr = gcremovetypeptr ann = t.buildannotator() ann.build_types(main, [s_list_of_strings], main_entry_point=True) rtyper = t.buildrtyper() rtyper.specialize() classdef = ann.bookkeeper.getuniqueclassdef(B) rclass = getclassrepr(rtyper, classdef) rinstance = getinstancerepr(rtyper, classdef) LLB = rinstance.lowleveltype.TO vtable_B = rclass.getvtable() adr_vtable_B = llmemory.cast_ptr_to_adr(vtable_B) vtable_B = llmemory.cast_adr_to_int(adr_vtable_B, mode="symbolic") CPU = getcpuclass() cpu = CPU(rtyper, NoStats(), translate_support_code=True, gcdescr=get_description(t.config)) execute_token = cpu.make_execute_token(llmemory.GCREF) finaldescr = BasicFinalDescr() faildescr = BasicFailDescr() descr_B = cpu.sizeof(LLB, vtable_B) typeid_B = descr_B.get_type_id() loop1 = parse(""" [p0] guard_class(p0, ConstInt(vtable_B), descr=faildescr) [] finish(descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'faildescr': faildescr, 'vtable_B': vtable_B}) loop2 = parse(""" [p0] guard_gc_type(p0, ConstInt(typeid_B), descr=faildescr) [] finish(descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'faildescr': faildescr, 'typeid_B': typeid_B}) loop3 = parse(""" [p0] guard_is_object(p0, descr=faildescr) [] finish(descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'faildescr': faildescr}) loop4 = parse(""" [p0] guard_subclass(p0, ConstInt(vtable_B), descr=faildescr) [] finish(descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'faildescr': faildescr, 'vtable_B': vtable_B}) def g(): cpu.setup_once() token1 = JitCellToken() token2 = JitCellToken() token3 = JitCellToken() token4 = JitCellToken() cpu.compile_loop(loop1.inputargs, loop1.operations, token1) cpu.compile_loop(loop2.inputargs, loop2.operations, token2) cpu.compile_loop(loop3.inputargs, loop3.operations, token3) cpu.compile_loop(loop4.inputargs, loop4.operations, token4) for token, p0 in [ (token1, rffi.cast(llmemory.GCREF, A())), (token1, rffi.cast(llmemory.GCREF, B())), (token1, rffi.cast(llmemory.GCREF, C())), (token2, rffi.cast(llmemory.GCREF, A())), (token2, rffi.cast(llmemory.GCREF, B())), (token2, rffi.cast(llmemory.GCREF, C())), (token2, rffi.cast(llmemory.GCREF, [42, 43])), (token3, rffi.cast(llmemory.GCREF, A())), (token3, rffi.cast(llmemory.GCREF, B())), (token3, rffi.cast(llmemory.GCREF, [44, 45])), (token4, rffi.cast(llmemory.GCREF, A())), (token4, rffi.cast(llmemory.GCREF, B())), (token4, rffi.cast(llmemory.GCREF, C())), ]: frame = execute_token(token, p0) descr = cpu.get_latest_descr(frame) if descr is finaldescr: print 'match' elif descr is faildescr: print 'fail' else: print '???' # if token is token2: # guard_gc_type print int(cpu.get_actual_typeid(p0) == typeid_B) if token is token3: # guard_is_object print int(cpu.check_is_object(p0)) call_initial_function(t, g) cbuilder = genc.CStandaloneBuilder(t, main, t.config) cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) cbuilder.compile() data = cbuilder.cmdexec('') assert data == ('fail\n' 'match\n' 'fail\n' 'fail\n' '0\n' 'match\n' '1\n' 'fail\n' '0\n' 'fail\n' '0\n' 'match\n' '1\n' 'match\n' '1\n' 'fail\n' '0\n' 'fail\n' 'match\n' 'match\n')
def test_it_frees_whatever_the_Pointer_is_referencing(self, space): int16_ptr = lltype.malloc(rffi.CArray(rffi.SHORT), 1, flavor='raw') adr = llmemory.cast_ptr_to_adr(int16_ptr) aint = llmemory.cast_adr_to_int(adr, mode='forced') space.execute("FFI::Pointer.new(%s).free" % aint) assert not aint in ALLOCATED
def is_valid_gc_object(self, addr): return addr != NULL and (not self.config.taggedpointers or llmemory.cast_adr_to_int(addr) & 1 == 0)
def run_guards_translated(gcremovetypeptr): class A(object): pass class B(A): pass class C(B): pass def main(argv): A(); B().foo = len(argv); C() return 0 t = TranslationContext() t.config.translation.gc = "minimark" t.config.translation.gcremovetypeptr = gcremovetypeptr ann = t.buildannotator() ann.build_types(main, [s_list_of_strings], main_entry_point=True) rtyper = t.buildrtyper() rtyper.specialize() classdef = ann.bookkeeper.getuniqueclassdef(B) rclass = getclassrepr(rtyper, classdef) rinstance = getinstancerepr(rtyper, classdef) LLB = rinstance.lowleveltype.TO ptr_vtable_B = rclass.getvtable() adr_vtable_B = llmemory.cast_ptr_to_adr(ptr_vtable_B) vtable_B = llmemory.cast_adr_to_int(adr_vtable_B, mode="symbolic") CPU = getcpuclass() cpu = CPU(rtyper, NoStats(), translate_support_code=True, gcdescr=get_description(t.config)) execute_token = cpu.make_execute_token(llmemory.GCREF) finaldescr = BasicFinalDescr() faildescr = BasicFailDescr() descr_B = cpu.sizeof(LLB, ptr_vtable_B) typeid_B = descr_B.get_type_id() fielddescr_B = cpu.fielddescrof(LLB, 'inst_foo') LLD = lltype.GcStruct('D', ('dd', lltype.Signed)) descr_D = cpu.sizeof(LLD) fielddescr_D = cpu.fielddescrof(LLD, 'dd') ARRAY = lltype.GcArray(lltype.Signed) arraydescr = cpu.arraydescrof(ARRAY) loop1 = parse(""" [p0] guard_class(p0, ConstInt(vtable_B), descr=faildescr) [] finish(descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'faildescr': faildescr, 'vtable_B': vtable_B}) loop2 = parse(""" [p0] guard_gc_type(p0, ConstInt(typeid_B), descr=faildescr) [] finish(descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'faildescr': faildescr, 'typeid_B': typeid_B}) loop3 = parse(""" [p0] guard_is_object(p0, descr=faildescr) [] finish(descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'faildescr': faildescr}) loop4 = parse(""" [p0] guard_subclass(p0, ConstInt(vtable_B), descr=faildescr) [] finish(descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'faildescr': faildescr, 'vtable_B': vtable_B}) def g(): cpu.setup_once() token1 = JitCellToken() token2 = JitCellToken() token3 = JitCellToken() token4 = JitCellToken() cpu.compile_loop(loop1.inputargs, loop1.operations, token1) cpu.compile_loop(loop2.inputargs, loop2.operations, token2) cpu.compile_loop(loop3.inputargs, loop3.operations, token3) cpu.compile_loop(loop4.inputargs, loop4.operations, token4) for token, p0 in [ (token1, rffi.cast(llmemory.GCREF, A())), (token1, rffi.cast(llmemory.GCREF, B())), (token1, rffi.cast(llmemory.GCREF, C())), (token2, rffi.cast(llmemory.GCREF, A())), (token2, rffi.cast(llmemory.GCREF, B())), (token2, rffi.cast(llmemory.GCREF, C())), (token2, rffi.cast(llmemory.GCREF, [42, 43])), (token3, rffi.cast(llmemory.GCREF, A())), (token3, rffi.cast(llmemory.GCREF, B())), (token3, rffi.cast(llmemory.GCREF, [44, 45])), (token4, rffi.cast(llmemory.GCREF, A())), (token4, rffi.cast(llmemory.GCREF, B())), (token4, rffi.cast(llmemory.GCREF, C())), ]: frame = execute_token(token, p0) descr = cpu.get_latest_descr(frame) if descr is finaldescr: print 'match' elif descr is faildescr: print 'fail' else: print '???' # if token is token2: # guard_gc_type print int(cpu.get_actual_typeid(p0) == typeid_B) if token is token3: # guard_is_object print int(cpu.check_is_object(p0)) for p0 in [lltype.nullptr(llmemory.GCREF.TO), rffi.cast(llmemory.GCREF, A()), rffi.cast(llmemory.GCREF, B()), rffi.cast(llmemory.GCREF, C()), rffi.cast(llmemory.GCREF, lltype.malloc(LLD)), rffi.cast(llmemory.GCREF, lltype.malloc(ARRAY, 5)), rffi.cast(llmemory.GCREF, "foobar"), rffi.cast(llmemory.GCREF, u"foobaz")]: results = ['B', 'D', 'A', 'S', 'U'] try: cpu.protect_speculative_field(p0, fielddescr_B) except SpeculativeError: results[0] = '-' try: cpu.protect_speculative_field(p0, fielddescr_D) except SpeculativeError: results[1] = '-' try: cpu.protect_speculative_array(p0, arraydescr) except SpeculativeError: results[2] = '-' try: cpu.protect_speculative_string(p0) except SpeculativeError: results[3] = '-' try: cpu.protect_speculative_unicode(p0) except SpeculativeError: results[4] = '-' print ''.join(results) call_initial_function(t, g) cbuilder = genc.CStandaloneBuilder(t, main, t.config) cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) cbuilder.compile() data = cbuilder.cmdexec('') assert data == ('fail\n' 'match\n' 'fail\n' 'fail\n' '0\n' 'match\n' '1\n' 'fail\n' '0\n' 'fail\n' '0\n' 'match\n' '1\n' 'match\n' '1\n' 'fail\n' '0\n' 'fail\n' 'match\n' 'match\n' '-----\n' # null '-----\n' # instance of A 'B----\n' # instance of B 'B----\n' # instance of C '-D---\n' '--A--\n' '---S-\n' '----U\n' )
def adr2int(addr): # Cast an address to an int. Returns an AddressAsInt object which # can be cast back to an address. return llmemory.cast_adr_to_int(addr, "symbolic")
def ll_identityhash(addr): obj = llmemory.cast_adr_to_ptr(addr, HDRPTR) h = obj.hash if h == 0: obj.hash = h = ~llmemory.cast_adr_to_int(addr) return h
def _compute_current_nursery_hash(self, obj): return intmask(llmemory.cast_adr_to_int(obj) + self.nursery_hash_base)
def is_in_nursery(self, addr): ll_assert(llmemory.cast_adr_to_int(addr) & 1 == 0, "odd-valued (i.e. tagged) pointer unexpected here") return self.nursery <= addr < self.nursery_top
def _writeref(self, pointer, _): obj = pointer.address[0] self.write(llmemory.cast_adr_to_int(obj)) self.add(obj)
def is_valid_gc_object(self, addr): return (addr != NULL and (not self.config.taggedpointers or llmemory.cast_adr_to_int(addr) & 1 == 0))
def test_it_frees_whatever_the_Pointer_is_referencing(self, space): int16_ptr = lltype.malloc(rffi.CArray(rffi.SHORT), 1, flavor='raw') adr = llmemory.cast_ptr_to_adr(int16_ptr) aint = llmemory.cast_adr_to_int(adr, mode='forced') space.execute("FFI::Pointer.new(%s).free" % aint) assert not aint in ALLOCATED
def _hash(adr): return mangle_hash(llmemory.cast_adr_to_int(adr))
def ll_addrhash(addr1): return cast_adr_to_int(addr1, "forced")
def _compute_current_nursery_hash(self, obj): return intmask(llmemory.cast_adr_to_int(obj) + self.nursery_hash_base)
def ll_identityhash(addr): h = llmemory.cast_adr_to_int(addr) return h
def op_cast_adr_to_int(self, adr, mode): checkadr(adr) return llmemory.cast_adr_to_int(adr, mode)
def _hash(adr): return mangle_hash(llmemory.cast_adr_to_int(adr))