• Brad King's avatar
    cmState: Avoid accumulating snapshot storage for backtraces · 1f6bd8a9
    Brad King authored
    Changes during post-3.3/pre-3.4 development refactored storage of most
    configure-time information, including variable bindings and function
    scopes.  All scopes (even short-lived) were kept persistently for
    possible future debugging features, causing huge accumulated memory
    usage.  This was mostly addressed by commit v3.4.1~4^2 (cmState: Avoid
    accumulating snapshot storage for short-lived scopes, 2015-11-24).
    
    Since then we still keep short-lived scopes when they are needed for a
    backtrace.  This is because since commit v3.4.0-rc1~378^2
    (cmListFileBacktrace: Implement in terms of cmState::Snapshot,
    2015-05-29) backtraces have been lightweight objects that simply point
    into the snapshot tree.  While the intention of this approach was to
    avoid duplicating the call stack file path strings, the cost turned out
    to be holding on to the entire call stack worth of scope snapshots,
    which is much worse.
    
    Furthermore, since commit v3.4.0-rc2~1^2 (cmIfCommand: Issue CMP0054
    warning with appropriate context, 2015-10-20) all conditions used in
    `if()` commands hold a backtrace for use in diagnostic messages.  Even
    though the backtrace is short-lived it still causes the scope snapshot
    to be kept.  This means that code like
    
        function(foo)
          if(0)
          endif()
        endfunction()
    
        foreach(i RANGE 1000000)
          foo()
        endforeach()
    
    accumulates storage for the function call scope snapshots.
    
    Fix this by partially reverting commit v3.4.0-rc1~378^2 and saving the
    entire call stack during cmListFileBacktrace construction.  This way
    we can avoid keeping short-lived scope snapshot storage in all cases.
    1f6bd8a9
cmState.cxx 59.6 KB