def put_in_dict()

in dev/stackdiff-dtrace.py [0:0]


def put_in_dict(path):
    # Our input looks something like:
    #
    # =====
    # This will collect stack shots of allocations and print it when you exit dtrace.
    # So go ahead, run your tests and then press Ctrl+C in this window to see the aggregated result
    # =====
    # DEBUG: After waiting 1 times, we quiesced to unfreeds=744
    # test_1_reqs_1000_conn.total_allocations: 490000
    # test_1_reqs_1000_conn.total_allocated_bytes: 42153000
    # test_1_reqs_1000_conn.remaining_allocations: 0
    # DEBUG: [["total_allocations": 490000, "total_allocated_bytes": 42153000, ...
    #
    # (truncated)
    #
    #               libsystem_malloc.dylib`malloc_zone_malloc
    #               libswiftCore.dylib`swift_slowAlloc+0x28
    #               libswiftCore.dylib`swift_allocObject+0x27
    #               test_1_reqs_1000_conn`closure #3 in SelectableEventLoop.run()+0x166
    #               test_1_reqs_1000_conn`SelectableEventLoop.run()+0x234
    #               test_1_reqs_1000_conn`closure #1 in static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:selectorFactory:initializer:)+0x12e
    #               test_1_reqs_1000_conn`partial apply for closure #1 in static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:selectorFactory:initializer:)+0x25
    #               test_1_reqs_1000_conn`thunk for @escaping @callee_guaranteed (@guaranteed NIOThread) -> ()+0xf
    #               test_1_reqs_1000_conn`partial apply for thunk for @escaping @callee_guaranteed (@guaranteed NIOThread) -> ()+0x11
    #               test_1_reqs_1000_conn`closure #1 in static ThreadOpsPosix.run(handle:args:detachThread:)+0x1c9
    #               libsystem_pthread.dylib`_pthread_start+0xe0
    #               libsystem_pthread.dylib`thread_start+0xf
    #             85945
    #
    #               libsystem_malloc.dylib`malloc_zone_malloc
    #               libswiftCore.dylib`swift_slowAlloc+0x28
    #               libswiftCore.dylib`swift_allocObject+0x27
    # (truncated)
    dictionary = collections.defaultdict(list)
    with open(path, "r") as f:
        current_stack = []
        for line in f:
            if not line.startswith(" "):
                # All lines we're intereted in are indented so ignore this one.
                pass
            elif re.match(num_regex, line):
                # The line contains just a number. This must be the end of a
                # stack, i.e. the number of allocations.

                # Build a key for the current stack. Each line looks
                # like: 'libswiftCore.dylib`swift_allocObject+0x27'. We want
                # everything before the '+'. We only take at most the first 8
                # lines for the key so that we group 'similar' stacks in our
                # output.
                key = "\n".join(line.split("+")[0] for line in current_stack[:8])

                # Record this stack and reset our state to build a new one.
                dictionary[key].append( (int(line), "\n".join(current_stack)) )
                current_stack = []
            else:
                # This line doesn't contain just a number. This might be an
                # entry in the current stack.
                stripped = line.strip()
                if stripped != "":
                    current_stack.append(stripped)

    return dictionary