To know the allocated memory at function termination.

        ..versionadded:: 4.1

        This property might return None if the function is still running.

        This function should help to show memory leaks or ram greedy code.
350465
def memory_used(self):
        
        if self._end_memory:
            memory_used = self._end_memory - self._start_memory
            return memory_used
        else:
            return None
426542
def _find_current_fn_call(co, lasti):
  """"""
  qj._DEBUG_QJ and qj.LOG_FN('co = {}'.format(co))

  if sys.version_info[0] < 3:
    stack = _build_instruction_stack(co, lasti)
  else:
    stack = _build_instruction_stack3(co, lasti)

  source_lines, source_offset = inspect.getsourcelines(co)
  source_lines = [l.strip() for l in source_lines]

  # Apply stack effects backwards until we arrive at the stack entries for a complete function call
  fn_stack = _collect_pops(stack[:-1], stack[-1].stack_depth, [], 0)

  if not fn_stack and stack[-1].stack_depth == 0:
    # The function call took 0 arguments, so return early with a special string.
    return '<empty log>'

  qj._DEBUG_QJ and qj.LOG_FN('collected fn_stack:\n%s\n\n' % '\n'.join(str(se) for se in fn_stack))

  # Prepare to annotate the stack with extra symbols, and filter out MAKE_FUNCTION and MAKE_CLOSURE calls, which are no longer needed.
  annotate_stack = [se for se in fn_stack if not se.opname.startswith('MAKE_')]
  annotate_stack.reverse()
  _annotate_fn_args(annotate_stack, stack[-1].opname, stack[-1].oparg, -1, False)

  qj._DEBUG_QJ and qj.LOG_FN('annotated fn_stack:\n%s\n\n' % '\n'.join(str(se) for se in fn_stack))

  # Find the range of lines to search over.
  min_l = stack[-1].curr_l
  max_l = stack[0].curr_l
  for se in fn_stack:
    min_l = min(min_l, se.curr_l)
    max_l = max(max_l, se.curr_l)

  qj._DEBUG_QJ and qj.LOG_FN('source lines range: %d -> %d (indices: %d, %d)' % (min_l, max_l, min_l - source_offset, max_l - source_offset + 1))
  source_chunk = ' '.join(
      [l for l in source_lines[min_l - source_offset:max_l - source_offset + 1] if l and not l.startswith('#')])

  qj._DEBUG_QJ and qj.LOG_FN('source_chunk: %r' % source_chunk)

  # Build up all of the tokens for the function call.
  tokens = []
  for se in fn_stack:
    opname = se.opname
    for oparg_repr in se.oparg_repr[::-1]:
      # Clean up the tokens
      if not oparg_repr:
        continue
      oparg_repr = re.escape(oparg_repr.replace('\n', '\\n'))
      tokens.append(oparg_repr)

  tokens.reverse()
  qj._DEBUG_QJ and qj.LOG_FN('extracted tokens: {}'.format(tokens))
  if qj._DEBUG_QJ:
    assert tokens

  # Add tokens for the function call we're extracting.
  tokens = ['\\('] + tokens + ['\\)']

  reg = '\b*?.*?\b*?'.join(tokens)
  qj._DEBUG_QJ and qj.LOG_FN(reg)

  # Search for the function call using the full set of tokens.
  # Expand the search with source lines after the current set if we don't find a match.
  shortest_match = None
  match_attempts = 0
  max_match_attempts = 10
  while not shortest_match and match_attempts < max_match_attempts:
    (shortest_match, _, _) = (
        _find_earliest_shortest_match(source_chunk, reg, 0, len(source_chunk), num_attempts=10))
    if not shortest_match:
      match_attempts += 1

      min_l -= 1
      prev_line = ''
      while not prev_line and min_l - source_offset >= 0 and min_l - source_offset < len(source_lines):
        prev_line = source_lines[min_l - source_offset]
        if prev_line.startswith('#'):
          prev_line = ''
        if not prev_line:
          min_l -= 1
      prev_line += ' ' if prev_line else ''
      source_chunk = prev_line + source_chunk

      max_l += 1
      next_line = ''
      while not next_line and max_l - source_offset >= 0 and max_l - source_offset < len(source_lines):
        next_line = source_lines[max_l - source_offset]
        if next_line.startswith('#'):
          next_line = ''
        if not next_line:
          max_l += 1
      next_line = (' ' if next_line else '') + next_line
      source_chunk += next_line

  # Return the string for the function call
  if qj._DEBUG_QJ:
    assert shortest_match
  if shortest_match is not None:
    match = shortest_match.group(0)
    if qj._DEBUG_QJ:
      assert match.startswith('(') and match.endswith(')')
    # Do some parentheses cleanup.
    if match.startswith('('):
      match = match[1:]
    lparens = match.count('(')
    rparens = match.count(')')
    if lparens > rparens:
      match += ')' * (lparens - rparens)
    elif lparens < rparens:
      rparens_to_remove = rparens - lparens
      while len(match) and match[-1] == ')' and rparens_to_remove > 0:
        match = match[:-1]
        rparens_to_remove -= 1
    match = match.strip()
    return match
  else:
    return ''
948792
def malloc_diff(func):
    
    def _f(*args, **kwargs):
        print("\n<<<---")
        tracemalloc.start()
        snapshot1 = tracemalloc.take_snapshot()
        res = func(*args, **kwargs)
        snapshot2 = tracemalloc.take_snapshot()
        top_stats = snapshot2.compare_to(snapshot1, 'lineno')
        print("[ Top 10 differences]")
        for stat in top_stats[:10]:
            print(stat)
        print("--->>>\n")
        return res
    return _f
41776
def usage(self):
        ''''''
        retval, stderr, stdout = _pysam_dispatch(
            self.collection,
            self.dispatch,
            is_usage=True,
            catch_stdout=True)
        # some tools write usage to stderr, such as mpileup
        if stderr:
            return stderr
        else:
            return stdout
1144864
def name(self):
        

        if self._name is not None:
            return self._name

        if not self.blocks:
            return None

        if not self.blocks[0].instructions:
            return None

        if not self.blocks[0].instructions[0].labels:
            return None

        lbl = self.blocks[0].instructions[0].labels[0]

        if isinstance(lbl, FunctionLabel):
            return lbl.function_name

        return None
109117
def emit_end(MEMORY=None):
    
    output = []
    output.extend(AT_END)

    if REQUIRES.intersection(MEMINITS) or '__MEM_INIT' in INITS:
        output.append(OPTIONS.heap_start_label.value + ':')
        output.append('; Defines DATA END\n' + 'ZXBASIC_USER_DATA_END EQU ZXBASIC_MEM_HEAP + ZXBASIC_HEAP_SIZE')
    else:
        output.append('; Defines DATA END --> HEAP size is 0\n' + 'ZXBASIC_USER_DATA_END EQU ZXBASIC_MEM_HEAP')

    output.append('; Defines USER DATA Length in bytes\n' +
                  'ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA')

    if OPTIONS.autorun.value:
        output.append('END %s' % START_LABEL)
    else:
        output.append('END')

    return output
810030
def trace_memory_usage(self, frame, event, arg):
        """"""
        if event in ('line', 'return') and frame.f_code in self.code_map:
                lineno = frame.f_lineno
                if event == 'return':
                    lineno += 1
                entry = self.code_map[frame.f_code].setdefault(lineno, [])
                entry.append(_get_memory(os.getpid()))

        return self.trace_memory_usage
1059804
def name(function):
    
    if isinstance(function, types.FunctionType):
        return function.__name__
    else:
        return str(function)
587299
def output(self):
        
        if (self._output is None) or (len(self._output) == 0):
            result = None
        else:
            result = self._output.pop(0)
        return result
1087189
def function_is_noop(function_node: ast.FunctionDef) -> bool:
    
    return all(node_is_noop(n) for n in function_node.body)
530459
def current_line_num(self):
        '''
        '''
        if self.is_optimized_out():
            return None
        f_trace = self.field('f_trace')
        if long(f_trace) != 0:
            # we have a non-NULL f_trace:
            return self.f_lineno
        else:
            #try:
            return self.co.addr2line(self.f_lasti)
1322050
def get_memory_size(self):
        """"""
        n = sys.getsizeof(self)
        n += sys.getsizeof(self.padding)
        n += total_size(self.start_addr)
        n += total_size(self._buf)
        n += sys.getsizeof(self._offset)
        return n
672310
def visit_FunctionDeclaration(self, node):
        """"""
        scope = self.memory.stack.current.current.copy()
        args = [parameter.variable.identifier.name for parameter in node.parameters]

        for i in islice(scope, len(args)):
            self.memory.stack.current.current.pop(i)
            self.memory[args[i]] = scope[i]

        return self.visit(node.body)
774011
def _decrement_current_byte(self):
        
        # If the current byte is uninitialized, then decrementing it will make it the max cell size
        # Otherwise, if it's already at the minimum cell size, then it will also make it the max cell size
        if self.tape[self.pointer] is None or self.tape[self.pointer] == self.MIN_CELL_SIZE:
            self.tape[self.pointer] = self.MAX_CELL_SIZE
        else:  # decrement it
            self.tape[self.pointer] -= 1
1332298
def ended(self):
        """"""
        self._end_time = time.time()

        if setting(key='memory_profile', expected_type=bool):
            self._end_memory = get_free_memory()
280944
def clean(self):
        
        if not self.deallocated:
            #Release/deallocate the pointer in fortran.
            method = self._deallocator()
            if method is not None:
                dealloc = static_symbol("ftypes_dealloc", method, self.libpath, True)
                if dealloc is None:
                    return
                arrtype = ndpointer(dtype=int, ndim=1, shape=(len(self.indices),), flags="F")
                dealloc.argtypes = [c_void_p, c_int_p, arrtype]
                nindices = require(array([i.value for i in self.indices]), int, "F")
                dealloc(byref(self.pointer), c_int(len(self.indices)), nindices)

        self.deallocated = True
991136
def leave_scope(self):
        
        def entry_size(entry):
            """ For local variables and params, returns the real variable or
            local array size in bytes
            """
            if entry.scope == SCOPE.global_ or \
                    entry.is_aliased:  # aliases or global variables = 0
                return 0

            if entry.class_ != CLASS.array:
                return entry.size

            return entry.memsize

        for v in self.table[self.current_scope].values(filter_by_opt=False):
            if not v.accessed:
                if v.scope == SCOPE.parameter:
                    kind = 'Parameter'
                    v.accessed = True  # HINT: Parameters must always be present even if not used!
                    warning_not_used(v.lineno, v.name, kind=kind)

        entries = sorted(self.table[self.current_scope].values(filter_by_opt=True), key=entry_size)
        offset = 0

        for entry in entries:  # Symbols of the current level
            if entry.class_ is CLASS.unknown:
                self.move_to_global_scope(entry.name)

            if entry.class_ in (CLASS.function, CLASS.label, CLASS.type_):
                continue

            # Local variables offset
            if entry.class_ == CLASS.var and entry.scope == SCOPE.local:
                if entry.alias is not None:  # alias of another variable?
                    if entry.offset is None:
                        entry.offset = entry.alias.offset
                    else:
                        entry.offset = entry.alias.offset - entry.offset
                else:
                    offset += entry_size(entry)
                    entry.offset = offset

            if entry.class_ == CLASS.array and entry.scope == SCOPE.local:
                entry.offset = entry_size(entry) + offset
                offset = entry.offset

        self.mangle = self[self.current_scope].parent_mangle
        self.table.pop()
        global_.LOOPS = global_.META_LOOPS.pop()
        return offset