def test_assemble_cast_consts(): ssarepr = SSARepr("test") S = lltype.GcStruct('S') s = lltype.malloc(S) np = lltype.nullptr(S) F = lltype.FuncType([], lltype.Signed) f = lltype.functionptr(F, 'f') ssarepr.insns = [ ('int_return', Constant('X', lltype.Char)), ('int_return', Constant(unichr(0x1234), lltype.UniChar)), ('int_return', Constant(f, lltype.Ptr(F))), ('ref_return', Constant(s, lltype.Ptr(S))), ('ref_return', Constant(np, lltype.Ptr(S))), ('ref_return', Constant(s, lltype.Ptr(S))), ('ref_return', Constant(np, lltype.Ptr(S))), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ("\x00\x58" "\x01\xFF" "\x01\xFE" "\x02\xFF" "\x02\xFE" "\x02\xFF" "\x02\xFE") assert assembler.insns == { 'int_return/c': 0, 'int_return/i': 1, 'ref_return/r': 2 } f_int = ptr2int(f) assert jitcode.constants_i == [0x1234, f_int] s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) np_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, np) assert jitcode.constants_r == [s_gcref, np_gcref]
def realloc_frame(frame, size): try: if not we_are_translated(): assert not self._exception_emulator[0] frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) if size > frame.jf_frame_info.jfi_frame_depth: # update the frame_info size, which is for whatever reason # not up to date # frame info lives on assembler stack, so we need to enable # writing enter_assembler_writing() frame.jf_frame_info.update_frame_depth(base_ofs, size) leave_assembler_writing() new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) frame.jf_forward = new_frame i = 0 while i < len(frame.jf_frame): new_frame.jf_frame[i] = frame.jf_frame[i] frame.jf_frame[i] = 0 i += 1 new_frame.jf_savedata = frame.jf_savedata new_frame.jf_guard_exc = frame.jf_guard_exc # all other fields are empty llop.gc_writebarrier(lltype.Void, new_frame) return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame) except Exception as e: print "Unhandled exception", e, "in realloc_frame" return lltype.nullptr(llmemory.GCREF.TO)
def virtual_ref_during_tracing(self, real_object): assert real_object vref = lltype.malloc(self.JIT_VIRTUAL_REF) p = lltype.cast_pointer(rclass.OBJECTPTR, vref) p.typeptr = self.jit_virtual_ref_vtable vref.virtual_token = TOKEN_NONE vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object) return lltype.cast_opaque_ptr(llmemory.GCREF, vref)
def virtual_ref_during_tracing(self, real_object): assert real_object vref = lltype.malloc(self.JIT_VIRTUAL_REF) p = lltype.cast_pointer(rclass.OBJECTPTR, vref) p.typeptr = self.jit_virtual_ref_vtable vref.virtual_token = TOKEN_NONE vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object) return lltype.cast_opaque_ptr(llmemory.GCREF, vref)
def continue_tracing(self, gcref, real_object): if not self.is_virtual_ref(gcref): return assert real_object vref = lltype.cast_opaque_ptr(lltype.Ptr(self.JIT_VIRTUAL_REF), gcref) assert vref.virtual_token != TOKEN_TRACING_RESCALL vref.virtual_token = TOKEN_NONE vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object)
def continue_tracing(self, gcref, real_object): if not self.is_virtual_ref(gcref): return assert real_object vref = lltype.cast_opaque_ptr(lltype.Ptr(self.JIT_VIRTUAL_REF), gcref) assert vref.virtual_token != TOKEN_TRACING_RESCALL vref.virtual_token = TOKEN_NONE vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object)
def test_compile_tmp_callback(): from rpython.jit.backend.llgraph import runner from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.llinterp import LLException # cpu = runner.LLGraphCPU(None) FUNC = lltype.FuncType([lltype.Signed] * 4, lltype.Signed) def ll_portal_runner(g1, g2, r3, r4): assert (g1, g2, r3, r4) == (12, 34, -156, -178) if raiseme: raise raiseme else: return 54321 # class FakeJitDriverSD: portal_runner_ptr = llhelper(lltype.Ptr(FUNC), ll_portal_runner) portal_runner_adr = llmemory.cast_ptr_to_adr(portal_runner_ptr) portal_calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, None) portal_finishtoken = compile.DoneWithThisFrameDescrInt() propagate_exc_descr = compile.PropagateExceptionDescr() num_red_args = 2 result_type = INT # loop_token = compile_tmp_callback( cpu, FakeJitDriverSD(), [ConstInt(12), ConstInt(34)], "ii") # raiseme = None # only two arguments must be passed in deadframe = cpu.execute_token(loop_token, -156, -178) fail_descr = cpu.get_latest_descr(deadframe) assert fail_descr is FakeJitDriverSD().portal_finishtoken # EXC = lltype.GcStruct('EXC') llexc = lltype.malloc(EXC) raiseme = LLException("exception class", llexc) deadframe = cpu.execute_token(loop_token, -156, -178) fail_descr = cpu.get_latest_descr(deadframe) assert isinstance(fail_descr, compile.PropagateExceptionDescr) got = cpu.grab_exc_value(deadframe) assert lltype.cast_opaque_ptr(lltype.Ptr(EXC), got) == llexc # class FakeMetaInterpSD: pass FakeMetaInterpSD.cpu = cpu deadframe = cpu.execute_token(loop_token, -156, -178) fail_descr = cpu.get_latest_descr(deadframe) try: fail_descr.handle_fail(deadframe, FakeMetaInterpSD(), None) except jitexc.ExitFrameWithExceptionRef as e: assert lltype.cast_opaque_ptr(lltype.Ptr(EXC), e.value) == llexc else: assert 0, "should have raised"
def test_compile_tmp_callback(): from rpython.jit.codewriter import heaptracker from rpython.jit.backend.llgraph import runner from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.llinterp import LLException # cpu = runner.LLGraphCPU(None) FUNC = lltype.FuncType([lltype.Signed] * 4, lltype.Signed) def ll_portal_runner(g1, g2, r3, r4): assert (g1, g2, r3, r4) == (12, 34, -156, -178) if raiseme: raise raiseme else: return 54321 # class FakeJitDriverSD: portal_runner_ptr = llhelper(lltype.Ptr(FUNC), ll_portal_runner) portal_runner_adr = llmemory.cast_ptr_to_adr(portal_runner_ptr) portal_calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, None) portal_finishtoken = compile.DoneWithThisFrameDescrInt() propagate_exc_descr = compile.PropagateExceptionDescr() num_red_args = 2 result_type = INT # loop_token = compile_tmp_callback(cpu, FakeJitDriverSD(), [ConstInt(12), ConstInt(34)], "ii") # raiseme = None # only two arguments must be passed in deadframe = cpu.execute_token(loop_token, -156, -178) fail_descr = cpu.get_latest_descr(deadframe) assert fail_descr is FakeJitDriverSD().portal_finishtoken # EXC = lltype.GcStruct("EXC") llexc = lltype.malloc(EXC) raiseme = LLException("exception class", llexc) deadframe = cpu.execute_token(loop_token, -156, -178) fail_descr = cpu.get_latest_descr(deadframe) assert isinstance(fail_descr, compile.PropagateExceptionDescr) got = cpu.grab_exc_value(deadframe) assert lltype.cast_opaque_ptr(lltype.Ptr(EXC), got) == llexc # class FakeMetaInterpSD: pass FakeMetaInterpSD.cpu = cpu deadframe = cpu.execute_token(loop_token, -156, -178) fail_descr = cpu.get_latest_descr(deadframe) try: fail_descr.handle_fail(deadframe, FakeMetaInterpSD(), None) except jitexc.ExitFrameWithExceptionRef, e: assert lltype.cast_opaque_ptr(lltype.Ptr(EXC), e.value) == llexc
def g(s): lst = rgc.get_rpy_roots() found = False for x in lst: if x == lltype.cast_opaque_ptr(llmemory.GCREF, s): found = True if x == lltype.cast_opaque_ptr(llmemory.GCREF, s.u): os.write(2, "s.u should not be found!\n") assert False return found == 1
def fn(): s = lltype.malloc(S) s.u = lltype.malloc(U) gcref1 = lltype.cast_opaque_ptr(llmemory.GCREF, s) gcref2 = lltype.cast_opaque_ptr(llmemory.GCREF, s.u) lst = rgc.get_rpy_referents(gcref1) assert gcref2 in lst assert gcref1 not in lst s.u.x = 42 return 0
def ll_clear_indexes(d, n): fun = d.lookup_function_no & FUNC_MASK d.lookup_function_no = fun if fun == FUNC_BYTE: rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_BYTE, d.indexes)) elif fun == FUNC_SHORT: rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_SHORT, d.indexes)) elif IS_64BIT and fun == FUNC_INT: rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_INT, d.indexes)) elif fun == FUNC_LONG: rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_LONG, d.indexes)) else: assert False
def ll_clear_indexes(d, n): fun = d.lookup_function_no & FUNC_MASK d.lookup_function_no = fun if fun == FUNC_BYTE: rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_BYTE, d.indexes)) elif fun == FUNC_SHORT: rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_SHORT, d.indexes)) elif IS_64BIT and fun == FUNC_INT: rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_INT, d.indexes)) elif fun == FUNC_LONG: rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_LONG, d.indexes)) else: assert False
def ll_malloc_indexes_and_choose_lookup(d, n): # keep in sync with ll_clear_indexes() below if n <= 256: d.indexes = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(DICTINDEX_BYTE.TO, n, zero=True)) d.lookup_function_no = FUNC_BYTE elif n <= 65536: d.indexes = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(DICTINDEX_SHORT.TO, n, zero=True)) d.lookup_function_no = FUNC_SHORT elif IS_64BIT and n <= 2 ** 32: d.indexes = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(DICTINDEX_INT.TO, n, zero=True)) d.lookup_function_no = FUNC_INT else: d.indexes = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(DICTINDEX_LONG.TO, n, zero=True)) d.lookup_function_no = FUNC_LONG
def check_correct_type(self, struct): if self.parent_descr.is_object(): cls = llmemory.cast_adr_to_ptr( heaptracker.int2adr(self.parent_descr.get_vtable()), lltype.Ptr(rclass.OBJECT_VTABLE)) tpptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct).typeptr # this comparison is necessary, since we want to make sure # that vtable for JitVirtualRef is the same without actually reading # fields if tpptr != cls: assert rclass.ll_isinstance(lltype.cast_opaque_ptr( rclass.OBJECTPTR, struct), cls) else: pass
def fn(): s = lltype.malloc(S) s.u = lltype.malloc(U) a = lltype.malloc(A, 1000) gcref1 = lltype.cast_opaque_ptr(llmemory.GCREF, s) int1 = rgc.get_rpy_memory_usage(gcref1) assert 8 <= int1 <= 32 gcref2 = lltype.cast_opaque_ptr(llmemory.GCREF, s.u) int2 = rgc.get_rpy_memory_usage(gcref2) assert 4 * 9 <= int2 <= 8 * 12 gcref3 = lltype.cast_opaque_ptr(llmemory.GCREF, a) int3 = rgc.get_rpy_memory_usage(gcref3) assert 4 * 1001 <= int3 <= 8 * 1010 return 0
def g(): r = lltype.malloc(P) r.x = 1 p = llop.do_malloc_fixedsize(llmemory.GCREF) # placeholder p = lltype.cast_opaque_ptr(lltype.Ptr(P), p) p.x = r.x return p.x
def g(): r = lltype.malloc(P) r.x = 1 p = llop.do_malloc_fixedsize(llmemory.GCREF) # placeholder p = lltype.cast_opaque_ptr(lltype.Ptr(P), p) p.x = r.x return p.x
def test_record_constptrs(self): class MyFakeCPU(object): def cast_adr_to_int(self, adr): assert adr == "some fake address" return 43 class MyFakeGCRefList(object): def get_address_of_gcref(self, s_gcref1): assert s_gcref1 == s_gcref return "some fake address" S = lltype.GcStruct('S') s = lltype.malloc(S) s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) v_random_box = BoxPtr() v_result = BoxInt() operations = [ ResOperation(rop.PTR_EQ, [v_random_box, ConstPtr(s_gcref)], v_result), ] gc_ll_descr = self.gc_ll_descr gc_ll_descr.gcrefs = MyFakeGCRefList() gcrefs = [] operations = get_deep_immutable_oplist(operations) operations2 = gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations, gcrefs) assert operations2 == operations assert gcrefs == [s_gcref]
def test_repr(): S = lltype.GcStruct('S') T = lltype.GcStruct('T', ('header', S)) t = lltype.malloc(T) s = lltype.cast_pointer(lltype.Ptr(S), t) const = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s)) assert const._getrepr_() == "*T"
def test_guard(self): ops = ''' [i0, p0, i1, p1] p3 = getfield_gc(p0, descr=fielddescr) guard_true(i0) [p0, i1, p1, p3] ''' s1 = lltype.malloc(self.S) s2 = lltype.malloc(self.S) s1.field = s2 self.interpret(ops, [0, s1, 1, s2]) frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, self.deadframe) # p0 and p3 should be in registers, p1 not so much assert self.getptr(0, lltype.Ptr(self.S)) == s1 # the gcmap should contain three things, p0, p1 and p3 # p3 stays in a register # while p0 and p1 are on the frame b = getmap(frame) nos = [len(b) - 1 - i.start() for i in re.finditer('1', b)] nos.reverse() if self.cpu.backend_name.startswith('x86'): if self.cpu.IS_64_BIT: assert nos == [0, 1, 31] else: assert nos == [0, 1, 25] elif self.cpu.backend_name.startswith('arm'): assert nos == [0, 1, 47] else: raise Exception("write the data here") assert frame.jf_frame[nos[0]] assert frame.jf_frame[nos[1]] assert frame.jf_frame[nos[2]]
def test_get_current_qmut_instance(): accessor = FieldListAccessor() accessor.initialize(None, {'inst_x': IR_QUASIIMMUTABLE}) STRUCT = lltype.GcStruct('Foo', ('inst_x', lltype.Signed), ('mutate_x', rclass.OBJECTPTR), hints={'immutable_fields': accessor}) foo = lltype.malloc(STRUCT, zero=True) foo.inst_x = 42 assert not foo.mutate_x class FakeCPU: ts = typesystem.llhelper def bh_getfield_gc_r(self, gcref, fielddescr): assert fielddescr == mutatefielddescr foo = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), gcref) result = foo.mutate_x return lltype.cast_opaque_ptr(llmemory.GCREF, result) def bh_setfield_gc_r(self, gcref, newvalue_gcref, fielddescr): assert fielddescr == mutatefielddescr foo = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), gcref) newvalue = lltype.cast_opaque_ptr(rclass.OBJECTPTR, newvalue_gcref) foo.mutate_x = newvalue cpu = FakeCPU() mutatefielddescr = ('fielddescr', STRUCT, 'mutate_x') foo_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, foo) qmut1 = get_current_qmut_instance(cpu, foo_gcref, mutatefielddescr) assert isinstance(qmut1, QuasiImmut) qmut2 = get_current_qmut_instance(cpu, foo_gcref, mutatefielddescr) assert qmut1 is qmut2
def do_force_quasi_immutable(cpu, p, mutatefielddescr): qmut_ref = cpu.bh_getfield_gc_r(p, mutatefielddescr) if qmut_ref: cpu.bh_setfield_gc_r(p, cpu.ts.NULLREF, mutatefielddescr) qmut_ptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, qmut_ref) qmut = cast_base_ptr_to_instance(QuasiImmut, qmut_ptr) qmut.invalidate()
def test_guard(self): ops = ''' [i0, p0, i1, p1] p3 = getfield_gc_r(p0, descr=fielddescr) guard_true(i0) [p0, i1, p1, p3] ''' s1 = lltype.malloc(self.S) s2 = lltype.malloc(self.S) s1.field = s2 self.interpret(ops, [0, s1, 1, s2]) frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, self.deadframe) # p0 and p3 should be in registers, p1 not so much assert self.getptr(0, lltype.Ptr(self.S)) == s1 # the gcmap should contain three things, p0, p1 and p3 # p3 stays in a register # while p0 and p1 are on the frame b = getmap(frame) nos = [len(b) - 1 - i.start() for i in re.finditer('1', b)] nos.reverse() if self.cpu.backend_name.startswith('x86'): if self.cpu.IS_64_BIT: assert nos == [0, 1, 31] else: assert nos == [0, 1, 25] elif self.cpu.backend_name.startswith('arm'): assert nos == [0, 1, 47] elif self.cpu.backend_name.startswith('ppc64'): assert nos == [0, 1, 33] elif self.cpu.backend_name.startswith('zarch'): assert nos == [0, 1, 29] else: raise Exception("write the data here") assert frame.jf_frame[nos[0]] assert frame.jf_frame[nos[1]] assert frame.jf_frame[nos[2]]
def test_malloc_1(self): cpu = self.cpu sizeof = cpu.sizeof(self.S, None) sizeof.tid = 0 size = sizeof.size loop = self.parse(""" [] p0 = call_malloc_nursery(%d) p1 = call_malloc_nursery(%d) p2 = call_malloc_nursery(%d) # this overflows guard_nonnull(p2, descr=faildescr) [p0, p1, p2] finish(p2, descr=finaldescr) """ % (size, size, size), namespace={'sizedescr': sizeof, 'finaldescr': BasicFinalDescr(), 'faildescr': BasicFailDescr()}) token = JitCellToken() cpu.gc_ll_descr.collections = [[0, sizeof.size]] cpu.gc_ll_descr.init_nursery(2 * sizeof.size) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) frame = cpu.execute_token(token) # now we should be able to track everything from the frame frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) thing = frame.jf_frame[unpack_gcmap(frame)[0]] assert thing == rffi.cast(lltype.Signed, cpu.gc_ll_descr.nursery) assert cpu.gc_ll_descr.nursery_ptrs[0] == thing + sizeof.size assert rffi.cast(JITFRAMEPTR, cpu.gc_ll_descr.write_barrier_on_frame_called) == frame
def __init__(self, cpu, const_pointers): size = len(const_pointers) # check that there are any moving object (i.e. chaning pointers). # Otherwise there is no reason for an instance of this class. assert size > 0 # # prepare GC array to hold the pointers that may change self.ptr_array = lltype.malloc(MovableObjectTracker.ptr_array_type, size) self.ptr_array_descr = cpu.arraydescrof( MovableObjectTracker.ptr_array_type) self.ptr_array_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, self.ptr_array) # use always the same ConstPtr to access the array # (easer to read JIT trace) self.const_ptr_gcref_array = ConstPtr(self.ptr_array_gcref) # # assign each pointer an index and put the pointer into the GC array. # as pointers and addresses are not a good key to use before translation # ConstPtrs are used as the key for the dict. self._indexes = {} for index in range(size): ptr = const_pointers[index] self._indexes[ptr] = index self.ptr_array[index] = ptr.value
def test_get_current_qmut_instance(): accessor = FieldListAccessor() accessor.initialize(None, {'inst_x': IR_QUASIIMMUTABLE}) STRUCT = lltype.GcStruct('Foo', ('inst_x', lltype.Signed), ('mutate_x', rclass.OBJECTPTR), hints={'immutable_fields': accessor}) foo = lltype.malloc(STRUCT, zero=True) foo.inst_x = 42 assert not foo.mutate_x class FakeCPU: ts = typesystem.llhelper def bh_getfield_gc_r(self, gcref, fielddescr): assert fielddescr == mutatefielddescr foo = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), gcref) result = foo.mutate_x return lltype.cast_opaque_ptr(llmemory.GCREF, result) def bh_setfield_gc_r(self, gcref, newvalue_gcref, fielddescr): assert fielddescr == mutatefielddescr foo = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), gcref) newvalue = lltype.cast_opaque_ptr(rclass.OBJECTPTR, newvalue_gcref) foo.mutate_x = newvalue cpu = FakeCPU() mutatefielddescr = ('fielddescr', STRUCT, 'mutate_x') foo_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, foo) qmut1 = get_current_qmut_instance(cpu, foo_gcref, mutatefielddescr) assert isinstance(qmut1, QuasiImmut) qmut2 = get_current_qmut_instance(cpu, foo_gcref, mutatefielddescr) assert qmut1 is qmut2
def test_malloc_1(self): cpu = self.cpu sizeof = cpu.sizeof(self.S) sizeof.tid = 0 size = sizeof.size loop = self.parse(""" [] p0 = call_malloc_nursery(%d) p1 = call_malloc_nursery(%d) p2 = call_malloc_nursery(%d) # this overflows guard_nonnull(p2, descr=faildescr) [p0, p1, p2] finish(p2, descr=finaldescr) """ % (size, size, size), namespace={'sizedescr': sizeof, 'finaldescr': BasicFinalDescr(), 'faildescr': BasicFailDescr()}) token = JitCellToken() cpu.gc_ll_descr.collections = [[0, sizeof.size]] cpu.gc_ll_descr.init_nursery(2 * sizeof.size) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) frame = cpu.execute_token(token) # now we should be able to track everything from the frame frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) thing = frame.jf_frame[unpack_gcmap(frame)[0]] assert thing == rffi.cast(lltype.Signed, cpu.gc_ll_descr.nursery) assert cpu.gc_ll_descr.nursery_ptrs[0] == thing + sizeof.size assert rffi.cast(JITFRAMEPTR, cpu.gc_ll_descr.write_barrier_on_frame_called) == frame
def ll_finalizer(gcref): exc_instance = llop.gc_fetch_exception(EXC_INSTANCE_TYPE) if revdb: llop.revdb_call_destructor(lltype.Void, gcref) v = lltype.cast_opaque_ptr(DESTR_ARG, gcref) ll_call_destructor(destrptr, v, typename) llop.gc_restore_exception(lltype.Void, exc_instance)
def test_assemble_cast_consts(): ssarepr = SSARepr("test") S = lltype.GcStruct('S') s = lltype.malloc(S) F = lltype.FuncType([], lltype.Signed) f = lltype.functionptr(F, 'f') ssarepr.insns = [ ('int_return', Constant('X', lltype.Char)), ('int_return', Constant(unichr(0x1234), lltype.UniChar)), ('int_return', Constant(f, lltype.Ptr(F))), ('ref_return', Constant(s, lltype.Ptr(S))), ] assembler = Assembler() jitcode = assembler.assemble(ssarepr) assert jitcode.code == ("\x00\x58" "\x01\xFF" "\x01\xFE" "\x02\xFF") assert assembler.insns == {'int_return/c': 0, 'int_return/i': 1, 'ref_return/r': 2} f_int = heaptracker.adr2int(llmemory.cast_ptr_to_adr(f)) assert jitcode.constants_i == [0x1234, f_int] s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) assert jitcode.constants_r == [s_gcref]
def wrap(cpu, value, in_const_box=False): if isinstance(lltype.typeOf(value), lltype.Ptr): if lltype.typeOf(value).TO._gckind == 'gc': value = lltype.cast_opaque_ptr(llmemory.GCREF, value) if in_const_box: return history.ConstPtr(value) else: return resoperation.InputArgRef(value) else: adr = llmemory.cast_ptr_to_adr(value) value = heaptracker.adr2int(adr) # fall through to the end of the function elif (isinstance(value, float) or longlong.is_longlong(lltype.typeOf(value))): if isinstance(value, float): value = longlong.getfloatstorage(value) else: value = rffi.cast(lltype.SignedLongLong, value) if in_const_box: return history.ConstFloat(value) else: return resoperation.InputArgFloat(value) elif isinstance(value, str) or isinstance(value, unicode): assert len(value) == 1 # must be a character value = ord(value) elif lltype.typeOf(value) is lltype.SingleFloat: value = longlong.singlefloat2int(value) else: value = intmask(value) if in_const_box: return history.ConstInt(value) else: return resoperation.InputArgInt(value)
def get_structptr_var(self, r, must_have_vtable=False, type=lltype.Struct, array_of_structs=False): while True: ptrvars = self._choose_ptr_vars(self.ptrvars, type, array_of_structs) if ptrvars and r.random() < 0.8: v, S = r.choice(ptrvars) else: prebuilt_ptr_consts = self._choose_ptr_vars( self.prebuilt_ptr_consts, type, array_of_structs) if prebuilt_ptr_consts and r.random() < 0.7: v, S = r.choice(prebuilt_ptr_consts) else: if type is lltype.Struct: # create a new constant structure must_have_vtable = must_have_vtable or r.random() < 0.5 p = self.get_random_structure( r, has_vtable=must_have_vtable) else: # create a new constant array p = self.get_random_array( r, must_be_array_of_structs=array_of_structs) S = lltype.typeOf(p).TO v = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, p)) self.prebuilt_ptr_consts.append( (v, S, self.field_values(p))) if not (must_have_vtable and S._names[0] != 'parent'): break return v, S
def do_force_quasi_immutable(cpu, p, mutatefielddescr): qmut_ref = cpu.bh_getfield_gc_r(p, mutatefielddescr) if qmut_ref: cpu.bh_setfield_gc_r(p, cpu.ts.NULLREF, mutatefielddescr) qmut_ptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, qmut_ref) qmut = cast_base_ptr_to_instance(QuasiImmut, qmut_ptr) qmut.invalidate()
def wrap(cpu, value, in_const_box=False): if isinstance(lltype.typeOf(value), lltype.Ptr): if lltype.typeOf(value).TO._gckind == 'gc': value = lltype.cast_opaque_ptr(llmemory.GCREF, value) if in_const_box: return history.ConstPtr(value) else: return history.BoxPtr(value) else: adr = llmemory.cast_ptr_to_adr(value) value = heaptracker.adr2int(adr) # fall through to the end of the function elif (isinstance(value, float) or longlong.is_longlong(lltype.typeOf(value))): if isinstance(value, float): value = longlong.getfloatstorage(value) else: value = rffi.cast(lltype.SignedLongLong, value) if in_const_box: return history.ConstFloat(value) else: return history.BoxFloat(value) elif isinstance(value, str) or isinstance(value, unicode): assert len(value) == 1 # must be a character value = ord(value) elif lltype.typeOf(value) is lltype.SingleFloat: value = longlong.singlefloat2int(value) else: value = intmask(value) if in_const_box: return history.ConstInt(value) else: return history.BoxInt(value)
def execute_guard_class(self, descr, arg, klass): value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, arg) expected_class = llmemory.cast_adr_to_ptr( llmemory.cast_int_to_adr(klass), rclass.CLASSTYPE) if value.typeptr != expected_class: self.fail_guard(descr)
def grab_exc_value(self, deadframe): if deadframe._last_exception is not None: result = deadframe._last_exception.args[1] gcref = lltype.cast_opaque_ptr(llmemory.GCREF, result) else: gcref = lltype.nullptr(llmemory.GCREF.TO) return gcref
def test_record_constptrs(self): class MyFakeCPU(object): def cast_adr_to_int(self, adr): assert adr == "some fake address" return 43 class MyFakeGCRefList(object): def get_address_of_gcref(self, s_gcref1): assert s_gcref1 == s_gcref return "some fake address" S = lltype.GcStruct('S') s = lltype.malloc(S) s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) v_random_box = BoxPtr() v_result = BoxInt() operations = [ ResOperation(rop.PTR_EQ, [v_random_box, ConstPtr(s_gcref)], v_result), ] gc_ll_descr = self.gc_ll_descr gc_ll_descr.gcrefs = MyFakeGCRefList() gcrefs = [] operations = get_deep_immutable_oplist(operations) operations2 = gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations, gcrefs) assert operations2 == operations assert gcrefs == [s_gcref]
def grab_exc_value(self, deadframe): if deadframe._last_exception is not None: result = deadframe._last_exception.args[1] gcref = lltype.cast_opaque_ptr(llmemory.GCREF, result) else: gcref = lltype.nullptr(llmemory.GCREF.TO) return gcref
def get_structptr_var(self, r, must_have_vtable=False, type=lltype.Struct, array_of_structs=False): while True: ptrvars = self._choose_ptr_vars(self.ptrvars, type, array_of_structs) if ptrvars and r.random() < 0.8: v, S = r.choice(ptrvars) else: prebuilt_ptr_consts = self._choose_ptr_vars( self.prebuilt_ptr_consts, type, array_of_structs) if prebuilt_ptr_consts and r.random() < 0.7: v, S = r.choice(prebuilt_ptr_consts) else: if type is lltype.Struct: # create a new constant structure must_have_vtable = must_have_vtable or r.random() < 0.5 p = self.get_random_structure(r, has_vtable=must_have_vtable) else: # create a new constant array p = self.get_random_array(r, must_be_array_of_structs=array_of_structs) S = lltype.typeOf(p).TO v = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, p)) self.prebuilt_ptr_consts.append((v, S, self.field_values(p))) if not (must_have_vtable and S._names[0] != 'parent'): break return v, S
def test_nullity_with_guard(self): allops = [rop.INT_IS_TRUE] guards = [rop.GUARD_TRUE, rop.GUARD_FALSE] p = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(lltype.GcStruct('x'))) nullptr = lltype.nullptr(llmemory.GCREF.TO) f = InputArgInt() for op in allops: for guard in guards: if op == rop.INT_IS_TRUE: bp = InputArgInt(1) n = InputArgInt(0) else: bp = InputArgRef(p) n = InputArgRef(nullptr) for b in (bp, n): i1 = ResOperation(rop.SAME_AS_I, [ConstInt(1)]) f = ResOperation(op, [b]) ops = [ i1, f, ResOperation(guard, [f], descr=BasicFailDescr()), ResOperation(rop.FINISH, [ConstInt(0)], descr=BasicFinalDescr()), ] ops[-2].setfailargs([i1]) looptoken = JitCellToken() self.cpu.compile_loop([b], ops, looptoken) deadframe = self.cpu.execute_token(looptoken, b.getint()) result = self.cpu.get_int_value(deadframe, 0) if guard == rop.GUARD_FALSE: assert result == execute(self.cpu, None, op, None, b) else: assert result != execute(self.cpu, None, op, None, b)
def emit_const(self, const, kind, allow_short=False): value = const.value value_key = value if kind == 'int': TYPE = const.concretetype if isinstance(TYPE, lltype.Ptr): assert TYPE.TO._gckind == 'raw' self.see_raw_object(value) value = llmemory.cast_ptr_to_adr(value) TYPE = llmemory.Address if TYPE == llmemory.Address: value = adr2int(value) if TYPE is lltype.SingleFloat: value = longlong.singlefloat2int(value) if not isinstance(value, (llmemory.AddressAsInt, ComputedIntSymbolic)): value = lltype.cast_primitive(lltype.Signed, value) if type(value) is r_int: value = int(value) if allow_short: try: short_num = -128 <= value <= 127 except TypeError: # "Symbolics cannot be compared!" short_num = False if short_num: # emit the constant as a small integer self.code.append(chr(value & 0xFF)) return True constants = self.constants_i elif kind == 'ref': value = lltype.cast_opaque_ptr(llmemory.GCREF, value) constants = self.constants_r if not value: # nullptr value_key = None else: value_key = value._obj.container elif kind == 'float': if const.concretetype == lltype.Float: value = longlong.getfloatstorage(value) else: assert longlong.is_longlong(const.concretetype) value = rffi.cast(lltype.SignedLongLong, value) constants = self.constants_f else: raise AssemblerError('unimplemented %r in %r' % (const, self.ssareprname)) key = (kind, Constant(value_key)) try: val = self.constants_dict[key] except KeyError: constants.append(value) val = 256 - len(constants) assert val >= 0, "too many constants" self.constants_dict[key] = val # emit the constant normally, as one byte that is an index in the # list of constants self.code.append(chr(val)) return False
def test_name_gcref(): from rpython.rtyper.lltypesystem import lltype, llmemory, rclass from rpython.translator.c import primitive from rpython.translator.c.database import LowLevelDatabase x = lltype.cast_int_to_ptr(rclass.OBJECTPTR, 19) y = lltype.cast_opaque_ptr(llmemory.GCREF, x) db = LowLevelDatabase() assert primitive.name_gcref(y, db) == "((void*) 19)"
def is_valid_class_for(self, struct): objptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) cls = llmemory.cast_adr_to_ptr(heaptracker.int2adr(self.get_vtable()), lltype.Ptr(rclass.OBJECT_VTABLE)) # this first comparison is necessary, since we want to make sure # that vtable for JitVirtualRef is the same without actually reading # fields return objptr.typeptr == cls or rclass.ll_isinstance(objptr, cls)
def _get_str(self): # for debugging only from rpython.rtyper.annlowlevel import hlstr from rpython.rtyper.lltypesystem import rstr try: return hlstr(lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), self.value)) except lltype.UninitializedMemoryAccess: return '<uninitialized string>'
def get_zero_division_error(self): # for tests, a random emulated ll_inst will do ll_inst = lltype.malloc(rclass.OBJECT) ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) _zer_error_vtable = llmemory.cast_ptr_to_adr(ll_inst.typeptr) zer_vtable = self.cast_adr_to_int(_zer_error_vtable) zer_inst = lltype.cast_opaque_ptr(llmemory.GCREF, ll_inst) return zer_vtable, zer_inst
def get_zero_division_error(self): # for tests, a random emulated ll_inst will do ll_inst = lltype.malloc(rclass.OBJECT) ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) _zer_error_vtable = llmemory.cast_ptr_to_adr(ll_inst.typeptr) zer_vtable = self.cast_adr_to_int(_zer_error_vtable) zer_inst = lltype.cast_opaque_ptr(llmemory.GCREF, ll_inst) return zer_vtable, zer_inst
def _get_str(self): # for debugging only from rpython.rtyper.annlowlevel import hlstr from rpython.rtyper.lltypesystem import rstr try: return hlstr(lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), self.value)) except lltype.UninitializedMemoryAccess: return '<uninitialized string>'
def cast_instance_to_gcref(x): # Before translation, casts an RPython instance into a _GcRef. # After translation, it is a variant of cast_object_to_ptr(GCREF). if we_are_translated(): from rpython.rtyper import annlowlevel x = annlowlevel.cast_instance_to_base_ptr(x) return lltype.cast_opaque_ptr(llmemory.GCREF, x) else: return _GcRef(x)
def _rawrefcount_pair(self, intval, is_light=False, is_pyobj=False, create_old=False, create_immortal=False, force_external=False): if is_light: rc = REFCNT_FROM_PYPY_LIGHT else: rc = REFCNT_FROM_PYPY self.trigger = [] self.gc.rawrefcount_init(lambda: self.trigger.append(1)) # if create_immortal: p1 = lltype.malloc(S, immortal=True) else: saved = self.gc.nonlarge_max try: if force_external: self.gc.nonlarge_max = 1 p1 = self.malloc(S) finally: self.gc.nonlarge_max = saved p1.x = intval if create_immortal: self.consider_constant(p1) elif create_old: self.stackroots.append(p1) self._collect(major=False) p1 = self.stackroots.pop() p1ref = lltype.cast_opaque_ptr(llmemory.GCREF, p1) r1 = lltype.malloc(PYOBJ_HDR, flavor='raw', immortal=create_immortal) r1.ob_refcnt = rc r1.ob_pypy_link = 0 r1addr = llmemory.cast_ptr_to_adr(r1) if is_pyobj: assert not is_light self.gc.rawrefcount_create_link_pyobj(p1ref, r1addr) else: self.gc.rawrefcount_create_link_pypy(p1ref, r1addr) assert r1.ob_refcnt == rc assert r1.ob_pypy_link != 0 def check_alive(extra_refcount): assert r1.ob_refcnt == rc + extra_refcount assert r1.ob_pypy_link != 0 p1ref = self.gc.rawrefcount_to_obj(r1addr) p1 = lltype.cast_opaque_ptr(lltype.Ptr(S), p1ref) assert p1.x == intval if not is_pyobj: assert self.gc.rawrefcount_from_obj(p1ref) == r1addr else: assert self.gc.rawrefcount_from_obj(p1ref) == llmemory.NULL return p1 return p1, p1ref, r1, r1addr, check_alive
def is_valid_class_for(self, struct): objptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) cls = llmemory.cast_adr_to_ptr( heaptracker.int2adr(self.get_vtable()), lltype.Ptr(rclass.OBJECT_VTABLE)) # this first comparison is necessary, since we want to make sure # that vtable for JitVirtualRef is the same without actually reading # fields return objptr.typeptr == cls or rclass.ll_isinstance(objptr, cls)
def test_getvar_const_ptr(self): x = ''' [] call(ConstPtr(func_ptr)) ''' TP = lltype.GcArray(lltype.Signed) NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP)) loop = self.parse(x, None, {'func_ptr' : NULL}) assert loop.operations[0].getarg(0).value == NULL
def ll_malloc_indexes_and_choose_lookup(d, n): # keep in sync with ll_clear_indexes() below if n <= 256: d.indexes = lltype.cast_opaque_ptr( llmemory.GCREF, lltype.malloc(DICTINDEX_BYTE.TO, n, zero=True)) d.lookup_function_no = FUNC_BYTE elif n <= 65536: d.indexes = lltype.cast_opaque_ptr( llmemory.GCREF, lltype.malloc(DICTINDEX_SHORT.TO, n, zero=True)) d.lookup_function_no = FUNC_SHORT elif IS_64BIT and n <= 2**32: d.indexes = lltype.cast_opaque_ptr( llmemory.GCREF, lltype.malloc(DICTINDEX_INT.TO, n, zero=True)) d.lookup_function_no = FUNC_INT else: d.indexes = lltype.cast_opaque_ptr( llmemory.GCREF, lltype.malloc(DICTINDEX_LONG.TO, n, zero=True)) d.lookup_function_no = FUNC_LONG
def get_latest_descr(self, deadframe): deadframe = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, deadframe) descr = deadframe.jf_descr res = history.AbstractDescr.show(self, descr) if not we_are_translated(): # tests only: for missing if res is None: # propagate_exception_descr raise MissingLatestDescrError assert isinstance(res, history.AbstractFailDescr) return res
def fn(): s = lltype.malloc(S) s.u = lltype.malloc(U) a = lltype.malloc(A, 1000) s2 = lltype.malloc(S) gcref1 = lltype.cast_opaque_ptr(llmemory.GCREF, s) int1 = rgc.get_rpy_type_index(gcref1) gcref2 = lltype.cast_opaque_ptr(llmemory.GCREF, s.u) int2 = rgc.get_rpy_type_index(gcref2) gcref3 = lltype.cast_opaque_ptr(llmemory.GCREF, a) int3 = rgc.get_rpy_type_index(gcref3) gcref4 = lltype.cast_opaque_ptr(llmemory.GCREF, s2) int4 = rgc.get_rpy_type_index(gcref4) assert int1 != int2 assert int1 != int3 assert int2 != int3 assert int1 == int4 return 0
def cast_instance_to_gcref(x): # Before translation, casts an RPython instance into a _GcRef. # After translation, it is a variant of cast_object_to_ptr(GCREF). if we_are_translated(): from rpython.rtyper import annlowlevel x = annlowlevel.cast_instance_to_base_ptr(x) return lltype.cast_opaque_ptr(llmemory.GCREF, x) else: return _GcRef(x)
def test_getvar_const_ptr(self): x = ''' [] call_n(ConstPtr(func_ptr)) ''' TP = lltype.GcArray(lltype.Signed) NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP)) loop = self.parse(x, None, {'func_ptr': NULL}) assert loop.operations[0].getarg(0).value == NULL
def test_name_gcref(): from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper import rclass from rpython.translator.c import primitive from rpython.translator.c.database import LowLevelDatabase x = lltype.cast_int_to_ptr(rclass.OBJECTPTR, 19) y = lltype.cast_opaque_ptr(llmemory.GCREF, x) db = LowLevelDatabase() assert primitive.name_gcref(y, db) == "((void*) 19)"
def get_latest_descr(self, deadframe): deadframe = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, deadframe) descr = deadframe.jf_descr res = history.AbstractDescr.show(self, descr) if not we_are_translated(): # tests only: for missing if res is None: # propagate_exception_descr raise MissingLatestDescrError assert isinstance(res, history.AbstractFailDescr) return res
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 assembler_call_helper(deadframe, virtualizableref): fail_descr = self.cpu.get_latest_descr(deadframe) if vinfo is not None: virtualizable = lltype.cast_opaque_ptr( vinfo.VTYPEPTR, virtualizableref) vinfo.reset_vable_token(virtualizable) try: fail_descr.handle_fail(deadframe, self.metainterp_sd, jd) except jitexc.JitException, e: return handle_jitexception(e)