def test_redirect_assembler(self, tmpdir, metainterp_sd): looptoken = FakeCallAssemblerLoopToken(0x0) newlooptoken = FakeCallAssemblerLoopToken(0x1234) # logger = jl.JitLogger() file = tmpdir.join('binary_file') file.ensure() # use rfile instead of file.open since the host python and compiled # code may use different runtime libraries (win32 visual2008 vs. # visual2019 for instance rfile = create_file(str(file), 'wb') with SuppressIPH(): jl.jitlog_init(rfile.fileno()) logger.start_new_trace(metainterp_sd, jd_name='jdname') log_trace = logger.log_trace(jl.MARK_TRACE, None, None) op = ResOperation(rop.CALL_ASSEMBLER_I, [], descr=looptoken) log_trace.write([], [op]) jl.redirect_assembler(looptoken, newlooptoken, 0x1234) #the next line will close the 'fd', instead of logger.finish() rfile.close() binary = file.read() opnum = jl.encode_le_16bit(rop.CALL_ASSEMBLER_I) id_looptoken = compute_unique_id(looptoken) new_id_looptoken = compute_unique_id(newlooptoken) end = jl.MARK_RESOP_DESCR + opnum + jl.encode_str('i0,looptoken') + \ jl.encode_le_addr(id_looptoken) + jl.encode_str('') + \ jl.MARK_REDIRECT_ASSEMBLER + \ jl.encode_le_addr(id_looptoken) + \ jl.encode_le_addr(new_id_looptoken) + \ jl.encode_le_addr(newlooptoken._ll_function_addr) assert binary.endswith(end)
def test_redirect_assembler(self, tmpdir, metainterp_sd): looptoken = FakeCallAssemblerLoopToken(0x0) newlooptoken = FakeCallAssemblerLoopToken(0x1234) # logger = jl.JitLogger() file = tmpdir.join('binary_file') file.ensure() fd = file.open('wb') jl.jitlog_init(fd.fileno()) logger.start_new_trace(metainterp_sd, jd_name='jdname') log_trace = logger.log_trace(jl.MARK_TRACE, None, None) op = ResOperation(rop.CALL_ASSEMBLER_I, [], descr=looptoken) log_trace.write([], [op]) jl.redirect_assembler(looptoken, newlooptoken, 0x1234) #the next line will close 'fd', instead of logger.finish() fd.close() binary = file.read() opnum = jl.encode_le_16bit(rop.CALL_ASSEMBLER_I) id_looptoken = compute_unique_id(looptoken) new_id_looptoken = compute_unique_id(newlooptoken) end = jl.MARK_RESOP_DESCR + opnum + jl.encode_str('i0,looptoken') + \ jl.encode_le_addr(id_looptoken) + jl.encode_str('') + \ jl.MARK_REDIRECT_ASSEMBLER + \ jl.encode_le_addr(id_looptoken) + \ jl.encode_le_addr(new_id_looptoken) + \ jl.encode_le_addr(newlooptoken._ll_function_addr) assert binary.endswith(end)
def log_bridge(self, inputargs, operations, extra=None, descr=None, ops_offset=None, memo=None): if extra == "noopt": debug_start("jit-log-noopt-bridge") debug_print("# bridge out of Guard", "0x%x" % compute_unique_id(descr), "with", len(operations), "ops") logops = self._log_operations(inputargs, operations, ops_offset, memo) debug_stop("jit-log-noopt-bridge") elif extra == "rewritten": debug_start("jit-log-rewritten-bridge") debug_print("# bridge out of Guard", "0x%x" % compute_unique_id(descr), "with", len(operations), "ops") logops = self._log_operations(inputargs, operations, ops_offset, memo) debug_stop("jit-log-rewritten-bridge") elif extra == "compiling": debug_start("jit-log-compiling-bridge") logops = self._log_operations(inputargs, operations, ops_offset, memo) debug_stop("jit-log-compiling-bridge") else: debug_start("jit-log-opt-bridge") debug_print("# bridge out of Guard", "0x%x" % r_uint(compute_unique_id(descr)), "with", len(operations), "ops") logops = self._log_operations(inputargs, operations, ops_offset, memo) debug_stop("jit-log-opt-bridge") return logops
def test_redirect_assembler(self, tmpdir): looptoken = FakeCallAssemblerLoopToken(0x0) newlooptoken = FakeCallAssemblerLoopToken(0x1234) # logger = jl.JitLogger() file = tmpdir.join('binary_file') file.ensure() fd = file.open('wb') jl.jitlog_init(fd.fileno()) logger.start_new_trace(self.make_metainterp_sd(), jd_name='jdname') log_trace = logger.log_trace(jl.MARK_TRACE, None, None) op = ResOperation(rop.CALL_ASSEMBLER_I, [], descr=looptoken) log_trace.write([], [op]) jl.redirect_assembler(looptoken, newlooptoken, 0x1234) #the next line will close 'fd', instead of logger.finish() fd.close() binary = file.read() opnum = jl.encode_le_16bit(rop.CALL_ASSEMBLER_I) id_looptoken = compute_unique_id(looptoken) new_id_looptoken = compute_unique_id(newlooptoken) end = jl.MARK_RESOP_DESCR + opnum + jl.encode_str('i0,looptoken') + \ jl.encode_le_addr(id_looptoken) + jl.encode_str('') + \ jl.MARK_REDIRECT_ASSEMBLER + \ jl.encode_le_addr(id_looptoken) + \ jl.encode_le_addr(new_id_looptoken) + \ jl.encode_le_addr(newlooptoken._ll_function_addr) assert binary.endswith(end)
def log_bridge(self, inputargs, operations, extra=None, descr=None, ops_offset=None, memo=None): if extra == "noopt": # XXX this case no longer used debug_start("jit-log-noopt-bridge") debug_print("# bridge out of Guard", "0x%x" % compute_unique_id(descr), "with", len(operations), "ops") logops = self._log_operations(inputargs, operations, ops_offset, memo) debug_stop("jit-log-noopt-bridge") elif extra == "rewritten": debug_start("jit-log-rewritten-bridge") debug_print("# bridge out of Guard", "0x%x" % compute_unique_id(descr), "with", len(operations), "ops") logops = self._log_operations(inputargs, operations, ops_offset, memo) debug_stop("jit-log-rewritten-bridge") elif extra == "compiling": debug_start("jit-log-compiling-bridge") logops = self._log_operations(inputargs, operations, ops_offset, memo) debug_stop("jit-log-compiling-bridge") else: debug_start("jit-log-opt-bridge") debug_print("# bridge out of Guard", "0x%x" % r_uint(compute_unique_id(descr)), "with", len(operations), "ops") logops = self._log_operations(inputargs, operations, ops_offset, memo) debug_stop("jit-log-opt-bridge") return logops
def fn(): a1 = A() a2 = A() return ( compute_unique_id(a1), current_object_addr_as_int(a1), compute_unique_id(a2), current_object_addr_as_int(a2), )
def redirect_assembler(oldtoken, newtoken, asm_adr): if not jitlog_enabled(): return descr_nmr = compute_unique_id(oldtoken) new_descr_nmr = compute_unique_id(newtoken) list = [MARK_REDIRECT_ASSEMBLER, encode_le_addr(descr_nmr), encode_le_addr(new_descr_nmr), encode_le_addr(asm_adr)] content = ''.join(list) jitlog_write_marked(content, len(content))
def redirect_assembler(oldtoken, newtoken, asm_adr): if not jitlog_enabled(): return descr_nmr = compute_unique_id(oldtoken) new_descr_nmr = compute_unique_id(newtoken) list = [MARK_REDIRECT_ASSEMBLER, encode_le_addr(descr_nmr), encode_le_addr(new_descr_nmr), encode_le_addr(asm_adr)] content = ''.join(list) jitlog_write_marked(content, len(content))
def run_once(): a = A() ida = compute_unique_id(a) b = B() idb = compute_unique_id(b) c = C() idc = compute_unique_id(c) llop.gc__collect(lltype.Void) llop.gc__collect(lltype.Void) llop.gc__collect(lltype.Void) return ida, idb, idc
def run_once(): a = A() ida = compute_unique_id(a) b = B() idb = compute_unique_id(b) c = C() idc = compute_unique_id(c) llop.gc__collect(lltype.Void) llop.gc__collect(lltype.Void) llop.gc__collect(lltype.Void) return ida, idb, idc
def fn(n): id_prebuilt1 = compute_unique_id(u.x) if n > 0: x = BoxedObject(n) else: x = UnboxedObject(n) id_x1 = compute_unique_id(x) rgc.collect() # check that a prebuilt tagged pointer doesn't explode id_prebuilt2 = compute_unique_id(u.x) id_x2 = compute_unique_id(x) print u.x, id_prebuilt1, id_prebuilt2 print x, id_x1, id_x2 return ((id_x1 == id_x2) * 1 + (id_prebuilt1 == id_prebuilt2) * 10 + (id_x1 != id_prebuilt1) * 100)
def __init__(self, space, debug_info, is_bridge=False, wrap_ops=True): if wrap_ops: memo = {} logops = debug_info.logger._make_log_operations(memo) if debug_info.asminfo is not None: ofs = debug_info.asminfo.ops_offset else: ofs = {} ops = debug_info.operations self.w_ops = space.newlist(wrap_oplist(space, logops, ops, ofs)) else: self.w_ops = space.w_None self.jd_name = debug_info.get_jitdriver().name self.type = debug_info.type if is_bridge: self.bridge_no = compute_unique_id(debug_info.fail_descr) #self.bridge_no = debug_info.fail_descr_no self.w_green_key = space.w_None else: self.w_green_key = wrap_greenkey(space, debug_info.get_jitdriver(), debug_info.greenkey, debug_info.get_greenkey_repr()) self.loop_no = debug_info.looptoken.number asminfo = debug_info.asminfo if asminfo is not None: self.asmaddr = asminfo.asmaddr self.asmlen = asminfo.asmlen
def __init__(self, space, ctype, w_callable, w_error): raw_closure = rffi.cast(rffi.CCHARP, clibffi.closureHeap.alloc()) W_CData.__init__(self, space, raw_closure, ctype) # if not space.is_true(space.callable(w_callable)): raise operationerrfmt(space.w_TypeError, "expected a callable object, not %T", w_callable) self.w_callable = w_callable # fresult = self.getfunctype().ctitem size = fresult.size if size > 0: if fresult.is_primitive_integer and size < SIZE_OF_FFI_ARG: size = SIZE_OF_FFI_ARG self.ll_error = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw', zero=True) if not space.is_none(w_error): convert_from_object_fficallback(fresult, self.ll_error, w_error) # self.unique_id = compute_unique_id(self) global_callback_mapping.set(self.unique_id, self) # cif_descr = self.getfunctype().cif_descr if not cif_descr: raise OperationError(space.w_NotImplementedError, space.wrap("callbacks with '...'")) res = clibffi.c_ffi_prep_closure(self.get_closure(), cif_descr.cif, invoke_callback, rffi.cast(rffi.VOIDP, self.unique_id)) if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK: raise OperationError(space.w_SystemError, space.wrap("libffi failed to build this callback"))
def _repr_of_descr(self, descr): if self.logops: s = self.logops.repr_of_descr(descr) else: s = str(descr) s += " at %d" % compute_unique_id(descr) return s
def encode_op(self, op): """ an operation is written as follows: <marker> <opid (16 bit)> \ <len (32 bit)> \ <res_val>,<arg_0>,...,<arg_n> \ <descr> <failarg_0>,...<failarg_n> The marker indicates if the last argument is a descr or a normal argument. """ str_args = [self.var_to_str(arg) for arg in op.getarglist()] descr = op.getdescr() le_opnum = encode_le_16bit(op.getopnum()) str_res = self.var_to_str(op) line = ','.join([str_res] + str_args) failargslist = op.getfailargs() failargs = '' if failargslist: failargs = ','.join( [self.var_to_str(farg) for farg in failargslist]) # if descr: descr_str = descr.repr_of_descr() line = line + ',' + descr_str string = encode_str(line) descr_number = compute_unique_id(descr) le_descr_number = encode_le_addr(descr_number) return MARK_RESOP_DESCR, le_opnum + string + le_descr_number + encode_str( failargs) else: string = encode_str(line) return MARK_RESOP, le_opnum + string + encode_str(failargs)
def tmp_callback(looptoken): mark_tmp_callback = ''.join([ MARK_TMP_CALLBACK, encode_le_addr(compute_unique_id(looptoken)), encode_le_64bit(looptoken.number) ]) jitlog_write_marked(mark_tmp_callback, len(mark_tmp_callback))
def encode_op(self, op): """ an operation is written as follows: <marker> <opid (16 bit)> \ <len (32 bit)> \ <res_val>,<arg_0>,...,<arg_n> \ <descr> <failarg_0>,...<failarg_n> The marker indicates if the last argument is a descr or a normal argument. """ str_args = [self.var_to_str(arg) for arg in op.getarglist()] descr = op.getdescr() le_opnum = encode_le_16bit(op.getopnum()) str_res = self.var_to_str(op) line = ','.join([str_res] + str_args) failargslist = op.getfailargs() failargs = '' if failargslist: failargs = ','.join([self.var_to_str(farg) for farg in failargslist]) # if descr: descr_str = descr.repr_of_descr() line = line + ',' + descr_str string = encode_str(line) descr_number = compute_unique_id(descr) le_descr_number = encode_le_addr(descr_number) return MARK_RESOP_DESCR, le_opnum + string + le_descr_number + encode_str(failargs) else: string = encode_str(line) return MARK_RESOP, le_opnum + string + encode_str(failargs)
def __init__(self, space, debug_info, is_bridge=False): logops = debug_info.logger._make_log_operations() if debug_info.asminfo is not None: ofs = debug_info.asminfo.ops_offset else: ofs = {} self.w_ops = space.newlist( wrap_oplist(space, logops, debug_info.operations, ofs)) self.jd_name = debug_info.get_jitdriver().name self.type = debug_info.type if is_bridge: self.bridge_no = compute_unique_id(debug_info.fail_descr) #self.bridge_no = debug_info.fail_descr_no self.w_green_key = space.w_None else: self.w_green_key = wrap_greenkey(space, debug_info.get_jitdriver(), debug_info.greenkey, debug_info.get_greenkey_repr()) self.loop_no = debug_info.looptoken.number asminfo = debug_info.asminfo if asminfo is not None: self.asmaddr = asminfo.asmaddr self.asmlen = asminfo.asmlen
def fn(n): id_prebuilt1 = compute_unique_id(u.x) if n > 0: x = BoxedObject(n) else: x = UnboxedObject(n) id_x1 = compute_unique_id(x) rgc.collect( ) # check that a prebuilt tagged pointer doesn't explode id_prebuilt2 = compute_unique_id(u.x) id_x2 = compute_unique_id(x) print u.x, id_prebuilt1, id_prebuilt2 print x, id_x1, id_x2 return ((id_x1 == id_x2) * 1 + (id_prebuilt1 == id_prebuilt2) * 10 + (id_x1 != id_prebuilt1) * 100)
def test_compute_unique_id(): from rpython.rlib.rarithmetic import intmask class Foo(object): pass foo = Foo() x = compute_unique_id(foo) assert type(x) is int assert x == intmask(id(foo))
def _all_dot(self, output): identity = objectmodel.compute_unique_id(self) output.append('%s [shape=box%s];' % (identity, self._get_dot_text())) if self.nextmap_all: for w_key, value in self.nextmap_all.items(): assert isinstance(value, JSONMap) if value is self.nextmap_first: color = ", color=blue" else: color = "" output.append('%s -> %s [label="%s"%s];' % ( identity, objectmodel.compute_unique_id(value), value.w_key._utf8, color)) value._all_dot(output) elif self.nextmap_first is not None: value = self.nextmap_first output.append('%s -> %s [label="%s", color=blue];' % ( identity, objectmodel.compute_unique_id(value), value.w_key._utf8)) value._all_dot(output)
def _repr_of_value(self, value): if not we_are_translated() and isinstance(value, str): return value # for tests if self.logops: s = self.logops.repr_of_arg(value) else: s = str(value) s += " at %d" % compute_unique_id(value) return s
def test_compute_unique_id(): from rpython.rlib.rarithmetic import intmask class Foo(object): pass foo = Foo() x = compute_unique_id(foo) assert type(x) is int assert x == intmask(id(foo))
def __init__(self, space, ctype, w_callable, w_error, w_onerror): raw_closure = rffi.cast(rffi.CCHARP, clibffi.closureHeap.alloc()) W_CData.__init__(self, space, raw_closure, ctype) # if not space.is_true(space.callable(w_callable)): raise oefmt(space.w_TypeError, "expected a callable object, not %T", w_callable) self.w_callable = w_callable if not space.is_none(w_onerror): if not space.is_true(space.callable(w_onerror)): raise oefmt( space.w_TypeError, "expected a callable object for 'onerror', not %T", w_onerror) self.w_onerror = w_onerror # fresult = self.getfunctype().ctitem size = fresult.size if size > 0: if fresult.is_primitive_integer and size < SIZE_OF_FFI_ARG: size = SIZE_OF_FFI_ARG self.ll_error = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw', zero=True) if not space.is_none(w_error): convert_from_object_fficallback(fresult, self.ll_error, w_error) # self.unique_id = compute_unique_id(self) global_callback_mapping.set(self.unique_id, self) # cif_descr = self.getfunctype().cif_descr if not cif_descr: raise oefmt( space.w_NotImplementedError, "%s: callback with unsupported argument or " "return type or with '...'", self.getfunctype().name) with self as ptr: closure_ptr = rffi.cast(clibffi.FFI_CLOSUREP, ptr) unique_id = rffi.cast(rffi.VOIDP, self.unique_id) res = clibffi.c_ffi_prep_closure(closure_ptr, cif_descr.cif, invoke_callback, unique_id) if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK: raise OperationError( space.w_SystemError, space.wrap("libffi failed to build this callback")) # # We must setup the GIL here, in case the callback is invoked in # some other non-Pythonic thread. This is the same as cffi on # CPython. if space.config.translation.thread: from pypy.module.thread.os_thread import setup_threads setup_threads(space)
def repr_of_resop(self, op, ops_offset=None): if isinstance(op, AbstractInputArg): return self.repr_of_arg(op) if op.getopnum() == rop.DEBUG_MERGE_POINT: jd_sd = self.metainterp_sd.jitdrivers_sd[op.getarg(0).getint()] s = jd_sd.warmstate.get_location_str(op.getarglist()[3:]) s = s.replace(',', '.') # we use comma for argument splitting return "debug_merge_point(%d, %d, '%s')" % ( op.getarg(1).getint(), op.getarg(2).getint(), s) if op.getopnum() == rop.JIT_DEBUG: args = op.getarglist() s = args[0]._get_str() s = s.replace(',', '.') # we use comma for argument splitting s2 = '' for box in args[1:]: if isinstance(box, ConstInt): s2 += ', %d' % box.getint() else: s2 += ', box' return "jit_debug('%s'%s)" % (s, s2) if ops_offset is None: offset = -1 else: final_op = op.get_box_replacement() offset = ops_offset.get(final_op, -1) if offset == -1: s_offset = "" else: s_offset = "+%d: " % offset args = ", ".join( [self.repr_of_arg(op.getarg(i)) for i in range(op.numargs())]) if op.type != 'v': res = self.repr_of_arg(op) + " = " else: res = "" is_guard = op.is_guard() if op.getdescr() is not None: descr = op.getdescr() if is_guard and self.guard_number: hash = r_uint(compute_unique_id(descr)) r = "<Guard0x%x>" % hash else: r = self.repr_of_descr(descr) if args: args += ', descr=' + r else: args = "descr=" + r if is_guard and op.getfailargs() is not None: fail_args = ' [' + ", ".join( [self.repr_of_arg(arg) for arg in op.getfailargs()]) + ']' else: fail_args = '' return s_offset + res + op.getopname() + '(' + args + ')' + fail_args
def test_invoke(space): size = llmemory.raw_malloc_usage(llmemory.sizeof(CIF_DESCRIPTION, 2)) cif_descr = lltype.malloc(CIF_DESCRIPTION_P.TO, size, flavor='raw') p_arg1 = lltype.malloc(rffi.CCHARP.TO, 1, flavor='raw') p_arg2 = lltype.malloc(rffi.CCHARP.TO, 1, flavor='raw') p_args = lltype.malloc(rffi.CCHARPP.TO, 2, flavor='raw') p_res = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') w_proc_mul = space.execute("proc { |x, y| x * y }") w_proc_diff = space.execute("proc { |x, y| (x - y).abs }") w_callback_info = space.execute(""" int32 = FFI::Type::INT32 func_type = FFI::FunctionType.new(int32, [int32, int32]) """) data_mul_w = _callback.Data(space, w_proc_mul, w_callback_info) data_diff_w = _callback.Data(space, w_proc_diff, w_callback_info) id_mul = compute_unique_id(data_mul_w) id_diff = compute_unique_id(data_diff_w) _callback.registration[id_mul] = _callback.Closure(data_mul_w) _callback.registration[id_diff] = _callback.Closure(data_diff_w) try: p_arg1[0] = rffi.cast(rffi.CHAR, 6) p_arg2[0] = rffi.cast(rffi.CHAR, 7) p_args[0] = p_arg1 p_args[1] = p_arg2 _callback.invoke(cif_descr, rffi.cast(rffi.VOIDP, p_res), rffi.cast(rffi.VOIDPP, p_args), rffi.cast(rffi.VOIDP, id_mul)) assert p_res[0] == 42 _callback.invoke(cif_descr, rffi.cast(rffi.VOIDP, p_res), rffi.cast(rffi.VOIDPP, p_args), rffi.cast(rffi.VOIDP, id_diff)) assert p_res[0] == 1 finally: lltype.free(cif_descr, flavor='raw') lltype.free(p_arg1, flavor='raw') lltype.free(p_arg2, flavor='raw') lltype.free(p_args, flavor='raw') lltype.free(p_res, flavor='raw')
def test_invoke(space): size = llmemory.raw_malloc_usage(llmemory.sizeof(CIF_DESCRIPTION, 2)) cif_descr = lltype.malloc(CIF_DESCRIPTION_P.TO, size, flavor='raw') p_arg1 = lltype.malloc(rffi.CCHARP.TO, 1, flavor='raw') p_arg2 = lltype.malloc(rffi.CCHARP.TO, 1, flavor='raw') p_args = lltype.malloc(rffi.CCHARPP.TO, 2, flavor='raw') p_res = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') w_proc_mul = space.execute("proc { |x, y| x * y }") w_proc_diff = space.execute("proc { |x, y| (x - y).abs }") w_callback_info = space.execute(""" int32 = FFI::Type::INT32 func_type = FFI::FunctionType.new(int32, [int32, int32]) """) data_mul_w = _callback.Data(space, w_proc_mul, w_callback_info) data_diff_w = _callback.Data(space, w_proc_diff, w_callback_info) id_mul = compute_unique_id(data_mul_w) id_diff = compute_unique_id(data_diff_w) _callback.registration[id_mul] = _callback.Closure(data_mul_w) _callback.registration[id_diff] = _callback.Closure(data_diff_w) try: p_arg1[0] = rffi.cast(rffi.CHAR, 6) p_arg2[0] = rffi.cast(rffi.CHAR, 7) p_args[0] = p_arg1 p_args[1] = p_arg2 _callback.invoke(cif_descr, rffi.cast(rffi.VOIDP, p_res), rffi.cast(rffi.VOIDPP, p_args), rffi.cast(rffi.VOIDP, id_mul)) assert p_res[0] == 42 _callback.invoke(cif_descr, rffi.cast(rffi.VOIDP, p_res), rffi.cast(rffi.VOIDPP, p_args), rffi.cast(rffi.VOIDP, id_diff)) assert p_res[0] == 1 finally: lltype.free(cif_descr, flavor='raw') lltype.free(p_arg1, flavor='raw') lltype.free(p_arg2, flavor='raw') lltype.free(p_args, flavor='raw') lltype.free(p_res, flavor='raw')
def fn(): return (compute_unique_id("foo"), compute_unique_id(u"bar"), compute_unique_id([1]), compute_unique_id({"foo": 3}), compute_unique_id(StringBuilder()), compute_unique_id(UnicodeBuilder()))
def repr_of_resop(self, op, ops_offset=None): if isinstance(op, AbstractInputArg): return self.repr_of_arg(op) if op.getopnum() == rop.DEBUG_MERGE_POINT: jd_sd = self.metainterp_sd.jitdrivers_sd[op.getarg(0).getint()] s = jd_sd.warmstate.get_location_str(op.getarglist()[3:]) s = s.replace(',', '.') # we use comma for argument splitting return "debug_merge_point(%d, %d, '%s')" % (op.getarg(1).getint(), op.getarg(2).getint(), s) if op.getopnum() == rop.JIT_DEBUG: args = op.getarglist() s = args[0]._get_str() s = s.replace(',', '.') # we use comma for argument splitting s2 = '' for box in args[1:]: if isinstance(box, ConstInt): s2 += ', %d' % box.getint() else: s2 += ', box' return "jit_debug('%s'%s)" % (s, s2) if ops_offset is None: offset = -1 else: final_op = op.get_box_replacement() offset = ops_offset.get(final_op, -1) if offset == -1: s_offset = "" else: s_offset = "+%d: " % offset args = ", ".join([self.repr_of_arg(op.getarg(i)) for i in range(op.numargs())]) if op.type != 'v': res = self.repr_of_arg(op) + " = " else: res = "" is_guard = op.is_guard() if op.getdescr() is not None: descr = op.getdescr() if is_guard and self.guard_number: hash = r_uint(compute_unique_id(descr)) r = "<Guard0x%x>" % hash else: r = self.repr_of_descr(descr) if args: args += ', descr=' + r else: args = "descr=" + r if is_guard and op.getfailargs() is not None: fail_args = ' [' + ", ".join([self.repr_of_arg(arg) for arg in op.getfailargs()]) + ']' else: fail_args = '' return s_offset + res + op.getopname() + '(' + args + ')' + fail_args
def immutable_unique_id(self, space): if self.user_overridden_class: return None s = space.unicode_w(self) if len(s) > 1: uid = compute_unique_id(s) else: # strings of len <= 1 are unique-ified if len(s) == 1: base = ~ord(s[0]) # negative base values else: base = 257 # empty unicode string: base value 257 uid = (base << IDTAG_SHIFT) | IDTAG_SPECIAL return space.wrap(uid)
def f(): from rpython.rtyper.lltypesystem import rffi alist = [A() for i in range(50)] idarray = lltype.malloc(rffi.SIGNEDP.TO, len(alist), flavor='raw') # Compute the id of all the elements of the list. The goal is # to not allocate memory, so that if the GC needs memory to # remember the ids, it will trigger some collections itself i = 0 while i < len(alist): idarray[i] = compute_unique_id(alist[i]) i += 1 j = 0 while j < 2: if j == 1: # allocate some stuff between the two iterations [A() for i in range(20)] i = 0 while i < len(alist): assert idarray[i] == compute_unique_id(alist[i]) i += 1 j += 1 lltype.free(idarray, flavor='raw') return 0
def immutable_unique_id(self, space): if self.user_overridden_class: return None s = space.str_w(self) if len(s) > 1: uid = compute_unique_id(s) else: # strings of len <= 1 are unique-ified if len(s) == 1: base = ord(s[0]) # base values 0-255 else: base = 256 # empty string: base value 256 uid = (base << IDTAG_SHIFT) | IDTAG_SPECIAL return space.wrap(uid)
def f(): from rpython.rtyper.lltypesystem import rffi alist = [A() for i in range(50)] idarray = lltype.malloc(rffi.SIGNEDP.TO, len(alist), flavor='raw') # Compute the id of all the elements of the list. The goal is # to not allocate memory, so that if the GC needs memory to # remember the ids, it will trigger some collections itself i = 0 while i < len(alist): idarray[i] = compute_unique_id(alist[i]) i += 1 j = 0 while j < 2: if j == 1: # allocate some stuff between the two iterations [A() for i in range(20)] i = 0 while i < len(alist): assert idarray[i] == compute_unique_id(alist[i]) i += 1 j += 1 lltype.free(idarray, flavor='raw') return 0
def immutable_unique_id(self, space): if self.user_overridden_class: return None s = space.bytes_w(self) if len(s) > 1: uid = compute_unique_id(s) else: # strings of len <= 1 are unique-ified if len(s) == 1: base = ord(s[0]) # base values 0-255 else: base = 256 # empty string: base value 256 uid = (base << IDTAG_SHIFT) | IDTAG_SPECIAL return space.newint(uid)
def immutable_unique_id(self, space): if self.user_overridden_class: return None s = space.unicode_w(self) if len(s) > 1: uid = compute_unique_id(s) else: # strings of len <= 1 are unique-ified if len(s) == 1: base = ~ord(s[0]) # negative base values else: base = 257 # empty unicode string: base value 257 uid = (base << IDTAG_SHIFT) | IDTAG_SPECIAL return space.newint(uid)
def __init__(self, space, ctype, w_callable, w_error, w_onerror): raw_closure = rffi.cast(rffi.CCHARP, clibffi.closureHeap.alloc()) W_CData.__init__(self, space, raw_closure, ctype) # if not space.is_true(space.callable(w_callable)): raise oefmt(space.w_TypeError, "expected a callable object, not %T", w_callable) self.w_callable = w_callable if not space.is_none(w_onerror): if not space.is_true(space.callable(w_onerror)): raise oefmt(space.w_TypeError, "expected a callable object for 'onerror', not %T", w_onerror) self.w_onerror = w_onerror # fresult = self.getfunctype().ctitem size = fresult.size if size > 0: if fresult.is_primitive_integer and size < SIZE_OF_FFI_ARG: size = SIZE_OF_FFI_ARG self.ll_error = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw', zero=True) if not space.is_none(w_error): convert_from_object_fficallback(fresult, self.ll_error, w_error) # self.unique_id = compute_unique_id(self) global_callback_mapping.set(self.unique_id, self) # cif_descr = self.getfunctype().cif_descr if not cif_descr: raise oefmt(space.w_NotImplementedError, "%s: callback with unsupported argument or " "return type or with '...'", self.getfunctype().name) with self as ptr: closure_ptr = rffi.cast(clibffi.FFI_CLOSUREP, ptr) unique_id = rffi.cast(rffi.VOIDP, self.unique_id) res = clibffi.c_ffi_prep_closure(closure_ptr, cif_descr.cif, invoke_callback, unique_id) if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK: raise OperationError(space.w_SystemError, space.wrap("libffi failed to build this callback")) # # We must setup the GIL here, in case the callback is invoked in # some other non-Pythonic thread. This is the same as cffi on # CPython. if space.config.translation.thread: from pypy.module.thread.os_thread import setup_threads setup_threads(space)
def _register_counter(self, tp, number, token): # YYY very minor leak -- we need the counters to stay alive # forever, just because we want to report them at the end # of the process struct = lltype.malloc(DEBUG_COUNTER, flavor='raw', track_allocation=False) struct.i = 0 struct.type = tp if tp == 'b' or tp == 'e': struct.number = number else: assert token struct.number = compute_unique_id(token) self.loop_run_counters.append(struct) return struct
def _register_counter(self, tp, number, token): # YYY very minor leak -- we need the counters to stay alive # forever, just because we want to report them at the end # of the process struct = lltype.malloc(DEBUG_COUNTER, flavor='raw', track_allocation=False) struct.i = 0 struct.type = tp if tp == 'b' or tp == 'e': struct.number = number else: assert token struct.number = compute_unique_id(token) self.loop_run_counters.append(struct) return struct
def start_new_trace(self, metainterp_sd, faildescr=None, entry_bridge=False, jd_name=""): # even if the logger is not enabled, increment the trace id self.trace_id += 1 if not jitlog_enabled(): return self.metainterp_sd = metainterp_sd content = [encode_le_addr(self.trace_id)] if faildescr: content.append(encode_str('bridge')) descrnmr = compute_unique_id(faildescr) content.append(encode_le_addr(descrnmr)) else: content.append(encode_str('loop')) content.append(encode_le_addr(int(entry_bridge))) content.append(encode_str(jd_name)) self._write_marked(MARK_START_TRACE, ''.join(content))
def __init__(self, callback_data): self.heap = clibffi.closureHeap.alloc() self.callback_data = callback_data w_callback_info = self.callback_data.w_callback_info space = self.callback_data.space self.uid = compute_unique_id(self) registration[self.uid] = self cls_ptr = rffi.cast(clibffi.FFI_CLOSUREP, self.heap) status = clibffi.c_ffi_prep_closure(cls_ptr, w_callback_info.cif_descr.cif, invoke, rffi.cast(rffi.VOIDP, self.uid)) if rffi.cast(lltype.Signed, status) != clibffi.FFI_OK: space = self.callback_data.space raise space.error(space.w_RuntimeError, "libffi failed to build this callback type")
def start_new_trace(self, metainterp_sd, faildescr=None, entry_bridge=False, jd_name=""): # even if the logger is not enabled, increment the trace id self.trace_id += 1 if not jitlog_enabled(): return self.metainterp_sd = metainterp_sd content = [encode_le_addr(self.trace_id)] if faildescr: content.append(encode_str('bridge')) descrnmr = compute_unique_id(faildescr) content.append(encode_le_addr(descrnmr)) else: content.append(encode_str('loop')) content.append(encode_le_addr(int(entry_bridge))) content.append(encode_str(jd_name)) self._write_marked(MARK_START_TRACE, ''.join(content))
def __init__(self, callback_data): self.heap = clibffi.closureHeap.alloc() self.callback_data = callback_data w_callback_info = self.callback_data.w_callback_info space = self.callback_data.space self.uid = compute_unique_id(self) registration[self.uid] = self cls_ptr = rffi.cast(clibffi.FFI_CLOSUREP, self.heap) status = clibffi.c_ffi_prep_closure(cls_ptr, w_callback_info.cif_descr.cif, invoke, rffi.cast(rffi.VOIDP, self.uid)) if rffi.cast(lltype.Signed, status) != clibffi.FFI_OK: space = self.callback_data.space raise space.error(space.w_RuntimeError, "libffi failed to build this callback type")
def getaddrstring(self, w_obj): w_id = self.newint_or_bigint(compute_unique_id(w_obj)) w_4 = self.newint(4) w_0x0F = self.newint(0x0F) i = 2 * rffi.sizeof(llmemory.Address) addrstring = [" "] * i while True: n = self.int_w(self.send(w_id, "&", [w_0x0F])) n += ord("0") if n > ord("9"): n += (ord("a") - ord("9") - 1) i -= 1 addrstring[i] = chr(n) if i == 0: break w_id = self.send(w_id, ">>", [w_4]) return "".join(addrstring)
def getaddrstring(self, w_obj): w_id = self.newint_or_bigint(compute_unique_id(w_obj)) w_4 = self.newint(4) w_0x0F = self.newint(0x0F) i = 2 * rffi.sizeof(llmemory.Address) addrstring = [" "] * i while True: n = self.int_w(self.send(w_id, "&", [w_0x0F])) n += ord("0") if n > ord("9"): n += (ord("a") - ord("9") - 1) i -= 1 addrstring[i] = chr(n) if i == 0: break w_id = self.send(w_id, ">>", [w_4]) return "".join(addrstring)
def f(): a2 = A() a3 = A() id1 = compute_unique_id(a1) id2 = compute_unique_id(a2) id3 = compute_unique_id(a3) llop.gc__collect(lltype.Void) error = 0 if id1 != compute_unique_id(a1): error += 1 if id2 != compute_unique_id(a2): error += 2 if id3 != compute_unique_id(a3): error += 4 return error
def f(): a2 = A() a3 = A() id1 = compute_unique_id(a1) id2 = compute_unique_id(a2) id3 = compute_unique_id(a3) llop.gc__collect(lltype.Void) error = 0 if id1 != compute_unique_id(a1): error += 1 if id2 != compute_unique_id(a2): error += 2 if id3 != compute_unique_id(a3): error += 4 return error
def wrap_debug_info(space, debug_info, is_bridge=False): memo = {} logops = debug_info.logger._make_log_operations(memo) if debug_info.asminfo is not None: ofs = debug_info.asminfo.ops_offset else: ofs = {} ops = debug_info.operations w_ops = wrap_oplist(space, logops, ops, ofs) jd_name = debug_info.get_jitdriver().name type = debug_info.type bridge_no = -1 w_green_key = space.w_nil if is_bridge: bridge_no = compute_unique_id(debug_info.fail_descr) else: w_green_key = wrap_greenkey(space, debug_info.get_jitdriver(), debug_info.greenkey, debug_info.get_greenkey_repr()) loop_no = debug_info.looptoken.number asminfo = debug_info.asminfo asmaddr = space.w_nil asmlen = space.w_nil if asminfo is not None: asmaddr = space.wrap_int(asminfo.asmaddr) asmlen = space.wrap_int(asminfo.asmlen) return space.wrap_list([ _assoc(space, "type", space.wrap_string(type)), _assoc(space, "ops", w_ops), _assoc(space, "jd_name", space.wrap_string(jd_name)), _assoc(space, "bridge no", space.wrap_int(bridge_no)), _assoc(space, "greenkey", w_green_key), _assoc(space, "loop no", space.wrap_int(loop_no)), _assoc(space, "asmaddr", asmaddr), _assoc(space, "asmlen", asmlen)])
def repr_of_resop(self, op, ops_offset=None): if op.getopnum() == rop.DEBUG_MERGE_POINT: jd_sd = self.metainterp_sd.jitdrivers_sd[op.getarg(0).getint()] s = jd_sd.warmstate.get_location_str(op.getarglist()[3:]) s = s.replace(',', '.') # we use comma for argument splitting return "debug_merge_point(%d, %d, '%s')" % (op.getarg(1).getint(), op.getarg(2).getint(), s) if ops_offset is None: offset = -1 else: offset = ops_offset.get(op, -1) if offset == -1: s_offset = "" else: s_offset = "+%d: " % offset args = ", ".join([self.repr_of_arg(op.getarg(i)) for i in range(op.numargs())]) if op.result is not None: res = self.repr_of_arg(op.result) + " = " else: res = "" is_guard = op.is_guard() if op.getdescr() is not None: descr = op.getdescr() if is_guard and self.guard_number: hash = compute_unique_id(descr) r = "<Guard0x%x>" % hash else: r = self.repr_of_descr(descr) if args: args += ', descr=' + r else: args = "descr=" + r if is_guard and op.getfailargs() is not None: fail_args = ' [' + ", ".join([self.repr_of_arg(arg) for arg in op.getfailargs()]) + ']' else: fail_args = '' return s_offset + res + op.getopname() + '(' + args + ')' + fail_args
def wrap_debug_info(space, debug_info, is_bridge=False): memo = {} logops = debug_info.logger._make_log_operations(memo) if debug_info.asminfo is not None: ofs = debug_info.asminfo.ops_offset else: ofs = {} ops = debug_info.operations w_ops = wrap_oplist(space, logops, ops, ofs) jd_name = debug_info.get_jitdriver().name type = debug_info.type bridge_no = -1 w_green_key = space.w_nil if is_bridge: bridge_no = compute_unique_id(debug_info.fail_descr) else: w_green_key = wrap_greenkey(space, debug_info.get_jitdriver(), debug_info.greenkey, debug_info.get_greenkey_repr()) loop_no = debug_info.looptoken.number asminfo = debug_info.asminfo asmaddr = space.w_nil asmlen = space.w_nil if asminfo is not None: asmaddr = space.wrap_int(asminfo.asmaddr) asmlen = space.wrap_int(asminfo.asmlen) return space.wrap_list([ _assoc(space, "type", space.wrap_string(type)), _assoc(space, "ops", w_ops), _assoc(space, "jd_name", space.wrap_string(jd_name)), _assoc(space, "bridge no", space.wrap_int(bridge_no)), _assoc(space, "greenkey", w_green_key), _assoc(space, "loop no", space.wrap_int(loop_no)), _assoc(space, "asmaddr", asmaddr), _assoc(space, "asmlen", asmlen) ])
def repr_rpython(box, typechars): return '%s/%s%d' % (box._get_hash_(), typechars, compute_unique_id(box))
def repr_of_descr(self): return 'TargetToken(%d)' % compute_unique_id(self)
def fn(s1, s2): return (compute_unique_id(s1), compute_unique_id(s2))
def repr_of_descr(self): return 'TargetToken(%d)' % compute_unique_id(self)
def externfn(node): llop.debug_print(lltype.Void, compute_unique_id(node), node.value, node.extra) return node.value * 2
def externfn(node): llop.debug_print(lltype.Void, compute_unique_id(node), node.value, node.extra) return node.value * 2
def fn(): a1 = A() a2 = A() return (compute_unique_id(a1), current_object_addr_as_int(a1), compute_unique_id(a2), current_object_addr_as_int(a2))