def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type, orig_inpargs, memo): forget_optimization_info(loop.operations) forget_optimization_info(loop.inputargs) vinfo = jitdriver_sd.virtualizable_info if vinfo is not None: vable = orig_inpargs[jitdriver_sd.index_of_virtualizable].getref_base() patch_new_loop_to_load_virtualizable_fields(loop, jitdriver_sd, vable) original_jitcell_token = loop.original_jitcell_token globaldata = metainterp_sd.globaldata original_jitcell_token.number = n = globaldata.loopnumbering globaldata.loopnumbering += 1 if not we_are_translated(): show_procedures(metainterp_sd, loop) loop.check_consistency() if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops, original_jitcell_token, loop.operations, type, greenkey) hooks.before_compile(debug_info) else: debug_info = None hooks = None operations = get_deep_immutable_oplist(loop.operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: loopname = jitdriver_sd.warmstate.get_location_str(greenkey) unique_id = jitdriver_sd.warmstate.get_unique_id(greenkey) asminfo = do_compile_loop(jitdriver_sd.index, unique_id, metainterp_sd, loop.inputargs, operations, original_jitcell_token, name=loopname, log=have_debug_prints(), memo=memo) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: debug_info.asminfo = asminfo hooks.after_compile(debug_info) metainterp_sd.stats.add_new_loop(loop) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new " + type) # if asminfo is not None: ops_offset = asminfo.ops_offset else: ops_offset = None metainterp_sd.logger_ops.log_loop(loop.inputargs, loop.operations, n, type, ops_offset, name=loopname) # if metainterp_sd.warmrunnerdesc is not None: # for tests metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive(original_jitcell_token)
def dump(self, memo): if have_debug_prints(): debug_start("jit-log-exported-state") debug_print("[" + ", ".join([x.repr_short(memo) for x in self.next_iteration_args]) + "]") for box in self.short_boxes: debug_print(" " + box.repr(memo)) debug_stop("jit-log-exported-state")
def _dump(self, addr, logname, backend=None): debug_start(logname) if have_debug_prints(): # if backend is not None: debug_print('BACKEND', backend) # from rpython.jit.backend.hlinfo import highleveljitinfo if highleveljitinfo.sys_executable: debug_print('SYS_EXECUTABLE', highleveljitinfo.sys_executable) else: debug_print('SYS_EXECUTABLE', '??') # HEX = '0123456789ABCDEF' dump = [] src = rffi.cast(rffi.CCHARP, addr) for p in range(self.get_relative_pos()): o = ord(src[p]) dump.append(HEX[o >> 4]) dump.append(HEX[o & 15]) debug_print('CODE_DUMP', '@%x' % addr, '+0 ', # backwards compatibility ''.join(dump)) # debug_stop(logname)
def f(x): debug_start("mycat") debug_print("foo", 2, "bar", x) debug_stop("mycat") debug_flush() # does nothing debug_offset() # should not explode at least return have_debug_prints()
def setup_once(self): # the address of the function called by 'new' gc_ll_descr = self.cpu.gc_ll_descr gc_ll_descr.initialize() if hasattr(gc_ll_descr, 'minimal_size_in_nursery'): self.gc_minimal_size_in_nursery = gc_ll_descr.minimal_size_in_nursery else: self.gc_minimal_size_in_nursery = 0 if hasattr(gc_ll_descr, 'gcheaderbuilder'): self.gc_size_of_header = gc_ll_descr.gcheaderbuilder.size_gc_header else: self.gc_size_of_header = WORD # for tests self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn) self.memset_addr = self.cpu.cast_ptr_to_int(memset_fn) self._build_failure_recovery(False, withfloats=False) self._build_failure_recovery(True, withfloats=False) self._build_wb_slowpath(False) self._build_wb_slowpath(True) self._build_wb_slowpath(False, for_frame=True) # only one of those self.build_frame_realloc_slowpath() if self.cpu.supports_floats: self._build_failure_recovery(False, withfloats=True) self._build_failure_recovery(True, withfloats=True) self._build_wb_slowpath(False, withfloats=True) self._build_wb_slowpath(True, withfloats=True) self._build_propagate_exception_path() if gc_ll_descr.get_malloc_slowpath_addr is not None: # generate few slowpaths for various cases self.malloc_slowpath = self._build_malloc_slowpath(kind='fixed') self.malloc_slowpath_varsize = self._build_malloc_slowpath( kind='var') if hasattr(gc_ll_descr, 'malloc_str'): self.malloc_slowpath_str = self._build_malloc_slowpath(kind='str') else: self.malloc_slowpath_str = None if hasattr(gc_ll_descr, 'malloc_unicode'): self.malloc_slowpath_unicode = self._build_malloc_slowpath( kind='unicode') else: self.malloc_slowpath_unicode = None self.cond_call_slowpath = [self._build_cond_call_slowpath(False, False), self._build_cond_call_slowpath(False, True), self._build_cond_call_slowpath(True, False), self._build_cond_call_slowpath(True, True)] self._build_stack_check_slowpath() self._build_release_gil(gc_ll_descr.gcrootmap) if not self._debug: # if self._debug is already set it means that someone called # set_debug by hand before initializing the assembler. Leave it # as it is debug_start('jit-backend-counts') self.set_debug(have_debug_prints()) debug_stop('jit-backend-counts') # when finishing, we only have one value at [0], the rest dies self.gcmap_for_finish = lltype.malloc(jitframe.GCMAP, 1, flavor='raw', track_allocation=False) self.gcmap_for_finish[0] = r_uint(1)
def entry_point(argv): x = "got:" debug_start("mycat") if have_debug_prints(): x += "b" debug_print("foo", r_longlong(2), "bar", 3) debug_start("cat2") if have_debug_prints(): x += "c" debug_print("baz") debug_stop("cat2") if have_debug_prints(): x += "d" debug_print("bok") debug_stop("mycat") if have_debug_prints(): x += "a" debug_print("toplevel") debug_print("some int", rffi.cast(rffi.INT, 3)) debug_flush() os.write(1, x + "." + str(debug_offset()) + '.\n') return 0
def log_loop_from_trace(self, trace, memo): if not have_debug_prints(): return inputargs, ops = self._unpack_trace(trace) debug_start("jit-log-noopt") debug_print("# Traced loop or bridge with", len(ops), "ops") logops = self._log_operations(inputargs, ops, None, memo) debug_stop("jit-log-noopt") return logops
def entry_point(argv): x = "got:" debug_start ("mycat") if have_debug_prints(): x += "b" debug_print ("foo", r_longlong(2), "bar", 3) debug_start ("cat2") if have_debug_prints(): x += "c" debug_print ("baz") debug_stop ("cat2") if have_debug_prints(): x += "d" debug_print ("bok") debug_stop ("mycat") if have_debug_prints(): x += "a" debug_print("toplevel") debug_print("some int", rffi.cast(rffi.INT, 3)) debug_flush() os.write(1, x + "." + str(debug_offset()) + '.\n') return 0
def log_abort_loop(self, trace, memo=None): debug_start("jit-abort-log") if not have_debug_prints(): return inputargs, operations = self._unpack_trace(trace) logops = self._log_operations(inputargs, operations, ops_offset=None, memo=memo) debug_stop("jit-abort-log") return logops
def get_location_str(greenkey): if not have_debug_prints(): return missing greenargs = unwrap_greenkey(greenkey) fn = support.maybe_on_top_of_llinterp(rtyper, get_location_ptr) llres = fn(*greenargs) if not we_are_translated() and isinstance(llres, str): return llres return hlstr(llres)
def log_abort_loop(self, trace, memo=None): debug_start("jit-abort-log") if not have_debug_prints(): debug_stop("jit-abort-log") return inputargs, operations = self._unpack_trace(trace) logops = self._log_operations(inputargs, operations, ops_offset=None, memo=memo) debug_stop("jit-abort-log") return logops
def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputargs, operations, original_loop_token, memo): forget_optimization_info(operations) forget_optimization_info(inputargs) if not we_are_translated(): show_procedures(metainterp_sd) seen = dict.fromkeys(inputargs) TreeLoop.check_consistency_of_branch(operations, seen) debug_info = None hooks = None if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks if hooks.are_hooks_enabled(): debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops, original_loop_token, operations, 'bridge', fail_descr=faildescr) hooks.before_compile_bridge(debug_info) else: hooks = None operations = get_deep_immutable_oplist(operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") log = have_debug_prints() or jl.jitlog_enabled() try: asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs, operations, original_loop_token, log, memo) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: debug_info.asminfo = asminfo hooks.after_compile_bridge(debug_info) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new bridge") # if asminfo is not None: ops_offset = asminfo.ops_offset else: ops_offset = None metainterp_sd.logger_ops.log_bridge(inputargs, operations, None, faildescr, ops_offset, memo=memo) # #if metainterp_sd.warmrunnerdesc is not None: # for tests # metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive( # original_loop_token) return asminfo
def _log_operations(self, inputargs, operations, ops_offset): if not have_debug_prints(): return if ops_offset is None: ops_offset = {} if inputargs is not None: args = ", ".join([self.repr_of_arg(arg) for arg in inputargs]) debug_print('[' + args + ']') for i in range(len(operations)): op = operations[i] debug_print(self.repr_of_resop(operations[i], ops_offset)) if op.getopnum() == rop.LABEL: self._log_inputarg_setup_ops(op) if ops_offset and None in ops_offset: offset = ops_offset[None] debug_print("+%d: --end of the loop--" % offset)
def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputargs, operations, original_loop_token, memo): forget_optimization_info(operations) forget_optimization_info(inputargs) if not we_are_translated(): show_procedures(metainterp_sd) seen = dict.fromkeys(inputargs) TreeLoop.check_consistency_of_branch(operations, seen) if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops, original_loop_token, operations, 'bridge', fail_descr=faildescr) hooks.before_compile_bridge(debug_info) else: hooks = None debug_info = None operations = get_deep_immutable_oplist(operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") log = have_debug_prints() or jl.jitlog_enabled() try: asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs, operations, original_loop_token, log, memo) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: debug_info.asminfo = asminfo hooks.after_compile_bridge(debug_info) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new bridge") # if asminfo is not None: ops_offset = asminfo.ops_offset else: ops_offset = None metainterp_sd.logger_ops.log_bridge(inputargs, operations, None, faildescr, ops_offset, memo=memo) # #if metainterp_sd.warmrunnerdesc is not None: # for tests # metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive( # original_loop_token) return asminfo
def dump_storage(storage, liveboxes): "For profiling only." debug_start("jit-resume") return # XXX refactor if needed if have_debug_prints(): debug_print('Log storage', compute_unique_id(storage)) frameinfo = storage.rd_frame_info_list while frameinfo is not None: try: jitcodename = frameinfo.jitcode.name except AttributeError: jitcodename = str(compute_unique_id(frameinfo.jitcode)) debug_print('\tjitcode/pc', jitcodename, frameinfo.pc, 'at', compute_unique_id(frameinfo)) frameinfo = frameinfo.prev numb = storage.rd_numb while numb: debug_print( '\tnumb', str([untag(numb.nums[i]) for i in range(len(numb.nums))]), 'at', compute_unique_id(numb)) numb = numb.prev for const in storage.rd_consts: debug_print('\tconst', const.repr_rpython()) for box in liveboxes: if box is None: debug_print('\tbox', 'None') else: debug_print('\tbox', box.repr_rpython()) if storage.rd_virtuals is not None: for virtual in storage.rd_virtuals: if virtual is None: debug_print('\t\t', 'None') else: virtual.debug_prints() if storage.rd_pendingfields: debug_print('\tpending setfields') for i in range(len(storage.rd_pendingfields)): lldescr = storage.rd_pendingfields[i].lldescr num = storage.rd_pendingfields[i].num fieldnum = storage.rd_pendingfields[i].fieldnum itemindex = storage.rd_pendingfields[i].itemindex debug_print("\t\t", str(lldescr), str(untag(num)), str(untag(fieldnum)), itemindex) debug_stop("jit-resume")
def _log_operations(self, inputargs, operations, ops_offset=None, memo=None): if not have_debug_prints(): return if ops_offset is None: ops_offset = {} if inputargs is not None: args = ", ".join([self.repr_of_arg(arg) for arg in inputargs]) debug_print('[' + args + ']') for i in range(len(operations)): #op = operations[i] debug_print(self.repr_of_resop(operations[i], ops_offset)) #if op.getopnum() == rop.LABEL: # self._log_inputarg_setup_ops(op) if ops_offset and None in ops_offset: offset = ops_offset[None] debug_print("+%d: --end of the loop--" % offset)
def _dump(self, addr, logname, backend=None): debug_start(logname) if have_debug_prints(): # if backend is not None: debug_print("BACKEND", backend) # from rpython.jit.backend.hlinfo import highleveljitinfo if highleveljitinfo.sys_executable: debug_print("SYS_EXECUTABLE", highleveljitinfo.sys_executable) else: debug_print("SYS_EXECUTABLE", "??") # dump = self.copy_core_dump(addr) debug_print("CODE_DUMP", "@%x" % addr, "+0 ", dump) # backwards compatibility # debug_stop(logname)
def _dump(self, addr, logname, backend=None): debug_start(logname) if have_debug_prints(): # if backend is not None: debug_print('BACKEND', backend) # from rpython.jit.backend.hlinfo import highleveljitinfo if highleveljitinfo.sys_executable: debug_print('SYS_EXECUTABLE', highleveljitinfo.sys_executable) else: debug_print('SYS_EXECUTABLE', '??') # dump = self.copy_core_dump(addr) debug_print('CODE_DUMP', '@%x' % addr, '+0 ', # backwards compatibility dump) # debug_stop(logname)
def _dump(self, addr, logname, backend=None): debug_start(logname) if have_debug_prints(): # if backend is not None: debug_print("BACKEND", backend) # from rpython.jit.backend.hlinfo import highleveljitinfo if highleveljitinfo.sys_executable: debug_print("SYS_EXECUTABLE", highleveljitinfo.sys_executable) else: debug_print("SYS_EXECUTABLE", "??") # HEX = "0123456789ABCDEF" dump = [] src = rffi.cast(rffi.CCHARP, addr) for p in range(self.get_relative_pos()): o = ord(src[p]) dump.append(HEX[o >> 4]) dump.append(HEX[o & 15]) debug_print("CODE_DUMP", "@%x" % addr, "+0 ", "".join(dump)) # backwards compatibility # debug_stop(logname)
def semispace_collect(self, size_changing=False): debug_start("gc-collect") debug_print() debug_print(".----------- Full collection ------------------") start_usage = self.free - self.tospace debug_print("| used before collection: ", start_usage, "bytes") #start_time = time.time() #llop.debug_print(lltype.Void, 'semispace_collect', int(size_changing)) # Switch the spaces. We copy everything over to the empty space # (self.fromspace at the beginning of the collection), and clear the old # one (self.tospace at the beginning). Their purposes will be reversed # for the next collection. tospace = self.fromspace fromspace = self.tospace self.fromspace = fromspace self.tospace = tospace self.top_of_space = tospace + self.space_size scan = self.free = tospace self.starting_full_collect() self.collect_roots() self.copy_pending_finalizers(self.copy) scan = self.scan_copied(scan) if self.objects_with_light_finalizers.non_empty(): self.deal_with_objects_with_light_finalizers() if self.objects_with_finalizers.non_empty(): scan = self.deal_with_objects_with_finalizers(scan) if self.objects_with_weakrefs.non_empty(): self.invalidate_weakrefs() self.update_objects_with_id() self.finished_full_collect() self.debug_check_consistency() if not size_changing: llarena.arena_reset(fromspace, self.space_size, True) self.record_red_zone() self.execute_finalizers() #llop.debug_print(lltype.Void, 'collected', self.space_size, size_changing, self.top_of_space - self.free) if have_debug_prints(): #end_time = time.time() #elapsed_time = end_time - start_time #self.total_collection_time += elapsed_time self.total_collection_count += 1 #total_program_time = end_time - self.program_start_time end_usage = self.free - self.tospace debug_print("| used after collection: ", end_usage, "bytes") debug_print("| freed: ", start_usage - end_usage, "bytes") debug_print("| size of each semispace: ", self.space_size, "bytes") debug_print("| fraction of semispace now used: ", end_usage * 100.0 / self.space_size, "%") #ct = self.total_collection_time cc = self.total_collection_count debug_print("| number of semispace_collects: ", cc) #debug_print("| i.e.: ", # cc / total_program_time, "per second") #debug_print("| total time in semispace_collect: ", # ct, "seconds") #debug_print("| i.e.: ", # ct * 100.0 / total_program_time, "%") debug_print("`----------------------------------------------") debug_stop("gc-collect")
def op_have_debug_prints(): return debug.have_debug_prints()
def sweep_rawmalloced_objects(self, generation): # free all the rawmalloced objects of the specified generation # that have not been marked if generation == 2: objects = self.gen2_rawmalloced_objects # generation 2 sweep: if A points to an object object B that # moves from gen2 to gen3, it's possible that A no longer points # to any gen2 object. In this case, A remains a bit too long in # last_generation_root_objects, but this will be fixed by the # next collect_last_generation_roots(). elif generation == 3: objects = self.gen3_rawmalloced_objects # generation 3 sweep: remove from last_generation_root_objects # all the objects that we are about to free gen3roots = self.last_generation_root_objects newgen3roots = self.AddressStack() while gen3roots.non_empty(): obj = gen3roots.pop() if not (self.header(obj).tid & GCFLAG_UNVISITED): newgen3roots.append(obj) gen3roots.delete() self.last_generation_root_objects = newgen3roots else: ll_assert(False, "bogus 'generation'") return 0 # to please the flowspace surviving_objects = self.AddressStack() # Help the flow space alive_count = alive_size = dead_count = dead_size = 0 debug = have_debug_prints() while objects.non_empty(): obj = objects.pop() tid = self.header(obj).tid if tid & GCFLAG_UNVISITED: if debug: dead_count += 1 dead_size += raw_malloc_usage(self.get_size_incl_hash(obj)) addr = obj - self.gcheaderbuilder.size_gc_header llmemory.raw_free(addr) else: if debug: alive_count += 1 alive_size += raw_malloc_usage(self.get_size_incl_hash(obj)) if generation == 3: surviving_objects.append(obj) elif generation == 2: ll_assert((tid & GCFLAG_AGE_MASK) < GCFLAG_AGE_MAX, "wrong age for generation 2 object") tid += GCFLAG_AGE_ONE if (tid & GCFLAG_AGE_MASK) == GCFLAG_AGE_MAX: # the object becomes part of generation 3 self.gen3_rawmalloced_objects.append(obj) # GCFLAG_NO_HEAP_PTRS not set yet, conservatively self.last_generation_root_objects.append(obj) else: # the object stays in generation 2 tid |= GCFLAG_UNVISITED surviving_objects.append(obj) self.header(obj).tid = tid objects.delete() if generation == 2: self.gen2_rawmalloced_objects = surviving_objects elif generation == 3: self.gen3_rawmalloced_objects = surviving_objects debug_print("| [hyb] gen", generation, "nonmoving now alive: ", alive_size, "bytes in", alive_count, "objs") debug_print("| [hyb] gen", generation, "nonmoving freed: ", dead_size, "bytes in", dead_count, "objs") return alive_size
def semispace_collect(self, size_changing=False): debug_start("gc-collect") debug_print() debug_print(".----------- Full collection ------------------") start_usage = self.free - self.tospace debug_print("| used before collection: ", start_usage, "bytes") #start_time = time.time() #llop.debug_print(lltype.Void, 'semispace_collect', int(size_changing)) # Switch the spaces. We copy everything over to the empty space # (self.fromspace at the beginning of the collection), and clear the old # one (self.tospace at the beginning). Their purposes will be reversed # for the next collection. tospace = self.fromspace fromspace = self.tospace self.fromspace = fromspace self.tospace = tospace self.top_of_space = tospace + self.space_size scan = self.free = tospace self.starting_full_collect() self.collect_roots() if self.run_finalizers.non_empty(): self.update_run_finalizers() scan = self.scan_copied(scan) if self.objects_with_light_finalizers.non_empty(): self.deal_with_objects_with_light_finalizers() if self.objects_with_finalizers.non_empty(): scan = self.deal_with_objects_with_finalizers(scan) if self.objects_with_weakrefs.non_empty(): self.invalidate_weakrefs() self.update_objects_with_id() self.finished_full_collect() self.debug_check_consistency() if not size_changing: llarena.arena_reset(fromspace, self.space_size, True) self.record_red_zone() self.execute_finalizers() #llop.debug_print(lltype.Void, 'collected', self.space_size, size_changing, self.top_of_space - self.free) if have_debug_prints(): #end_time = time.time() #elapsed_time = end_time - start_time #self.total_collection_time += elapsed_time self.total_collection_count += 1 #total_program_time = end_time - self.program_start_time end_usage = self.free - self.tospace debug_print("| used after collection: ", end_usage, "bytes") debug_print("| freed: ", start_usage - end_usage, "bytes") debug_print("| size of each semispace: ", self.space_size, "bytes") debug_print("| fraction of semispace now used: ", end_usage * 100.0 / self.space_size, "%") #ct = self.total_collection_time cc = self.total_collection_count debug_print("| number of semispace_collects: ", cc) #debug_print("| i.e.: ", # cc / total_program_time, "per second") #debug_print("| total time in semispace_collect: ", # ct, "seconds") #debug_print("| i.e.: ", # ct * 100.0 / total_program_time, "%") debug_print("`----------------------------------------------") debug_stop("gc-collect")
def print_stats(self): debug_start("jit-summary") if have_debug_prints(): self._print_stats() debug_stop("jit-summary")
def _log_operations(self, inputargs, operations, ops_offset): if not have_debug_prints(): return None logops = self._make_log_operations() logops._log_operations(inputargs, operations, ops_offset) return logops
def sweep_rawmalloced_objects(self, generation): # free all the rawmalloced objects of the specified generation # that have not been marked if generation == 2: objects = self.gen2_rawmalloced_objects # generation 2 sweep: if A points to an object object B that # moves from gen2 to gen3, it's possible that A no longer points # to any gen2 object. In this case, A remains a bit too long in # last_generation_root_objects, but this will be fixed by the # next collect_last_generation_roots(). elif generation == 3: objects = self.gen3_rawmalloced_objects # generation 3 sweep: remove from last_generation_root_objects # all the objects that we are about to free gen3roots = self.last_generation_root_objects newgen3roots = self.AddressStack() while gen3roots.non_empty(): obj = gen3roots.pop() if not (self.header(obj).tid & GCFLAG_UNVISITED): newgen3roots.append(obj) gen3roots.delete() self.last_generation_root_objects = newgen3roots else: ll_assert(False, "bogus 'generation'") return 0 # to please the flowspace surviving_objects = self.AddressStack() # Help the flow space alive_count = alive_size = dead_count = dead_size = 0 debug = have_debug_prints() while objects.non_empty(): obj = objects.pop() tid = self.header(obj).tid if tid & GCFLAG_UNVISITED: if debug: dead_count+=1 dead_size+=raw_malloc_usage(self.get_size_incl_hash(obj)) addr = obj - self.gcheaderbuilder.size_gc_header llmemory.raw_free(addr) else: if debug: alive_count+=1 alive_size+=raw_malloc_usage(self.get_size_incl_hash(obj)) if generation == 3: surviving_objects.append(obj) elif generation == 2: ll_assert((tid & GCFLAG_AGE_MASK) < GCFLAG_AGE_MAX, "wrong age for generation 2 object") tid += GCFLAG_AGE_ONE if (tid & GCFLAG_AGE_MASK) == GCFLAG_AGE_MAX: # the object becomes part of generation 3 self.gen3_rawmalloced_objects.append(obj) # GCFLAG_NO_HEAP_PTRS not set yet, conservatively self.last_generation_root_objects.append(obj) else: # the object stays in generation 2 tid |= GCFLAG_UNVISITED surviving_objects.append(obj) self.header(obj).tid = tid objects.delete() if generation == 2: self.gen2_rawmalloced_objects = surviving_objects elif generation == 3: self.gen3_rawmalloced_objects = surviving_objects debug_print("| [hyb] gen", generation, "nonmoving now alive: ", alive_size, "bytes in", alive_count, "objs") debug_print("| [hyb] gen", generation, "nonmoving freed: ", dead_size, "bytes in", dead_count, "objs") return alive_size
def log_loop_from_trace(self, trace, memo): if not have_debug_prints(): return inputargs, ops = self._unpack_trace(trace) self.log_loop(inputargs, ops, memo=memo)
def _log_operations(self, inputargs, operations, ops_offset, memo=None): if not have_debug_prints(): return None logops = self._make_log_operations(memo) logops._log_operations(inputargs, operations, ops_offset, memo) return logops