Repository: jlfwong/speedscope (ts)

Issue:
XCode Instruments 16 breaks Deep Copy format import
Here's a sample Deep Copy from Instruments 16, which seems to have slightly different spacing:


```
Weight	Self Weight	Symbol Names
2.18 s  100.0%	0 s	 node (98674)
1.98 s  90.8%	0 s	  start
1.98 s   0.0%	0 s	   node::Start(int, char**)
1.98 s   0.0%	0 s	    node::LoadSnapshotDataAndRun(node::SnapshotData const**, node::InitializationResult const*)
1.98 s   0.0%	0 s	     node::NodeMainInstance::Run()
```

Pull request:
Add support for Instruments 16 Time Profile Deep Copy
fix #481 

I generated profile using simple program, however, the capture profile is actually different than earlier instruments that's why there's new test snapshot

Patch:
diff --git a/sample/profiles/Instruments/16.0/simple-time-profile-deep-copy.txt b/sample/profiles/Instruments/16.0/simple-time-profile-deep-copy.txt
new file mode 100644
index 0000000..79ba908
--- /dev/null
+++ b/sample/profiles/Instruments/16.0/simple-time-profile-deep-copy.txt
@@ -0,0 +1,95 @@
+Weight	Self Weight	Symbol Names
+4.93 s  100.0%	0 s	   start
+4.93 s  99.9%	0 s	    main
+2.45 s   0.0%	846.00 ms	     delta()
+797.00 ms   0.0%	786.00 ms	      alpha()
+9.00 ms   0.0%	0 s	       leakMemory()
+8.00 ms   0.0%	1.00 ms	        szone_malloc_should_clear
+6.00 ms   0.0%	4.00 ms	         small_malloc_should_clear
+2.00 ms   0.0%	2.00 ms	          small_malloc_from_free_list
+1.00 ms   0.0%	1.00 ms	         small_malloc_from_free_list
+1.00 ms   0.0%	1.00 ms	        _malloc_zone_malloc
+2.00 ms   0.0%	2.00 ms	       _malloc_zone_malloc
+795.00 ms   0.0%	778.00 ms	      beta()
+14.00 ms   0.0%	1.00 ms	       leakMemory()
+11.00 ms   0.0%	2.00 ms	        szone_malloc_should_clear
+9.00 ms   0.0%	3.00 ms	         small_malloc_should_clear
+5.00 ms   0.0%	5.00 ms	          small_malloc_from_free_list
+1.00 ms   0.0%	1.00 ms	          rack_get_thread_index
+1.00 ms   0.0%	1.00 ms	        nanov2_malloc_type
+1.00 ms   0.0%	1.00 ms	        DYLD-STUB$$malloc
+2.00 ms   0.0%	2.00 ms	       nanov2_malloc_type
+1.00 ms   0.0%	1.00 ms	       _malloc_zone_malloc
+10.00 ms   0.0%	0 s	      leakMemory()
+7.00 ms   0.0%	3.00 ms	       szone_malloc_should_clear
+4.00 ms   0.0%	3.00 ms	        small_malloc_should_clear
+1.00 ms   0.0%	0 s	         mvm_allocate_pages_plat
+1.00 ms   0.0%	1.00 ms	          _kernelrpc_mach_vm_map_trap
+2.00 ms   0.0%	2.00 ms	       small_malloc_should_clear
+1.00 ms   0.0%	1.00 ms	       _malloc_zone_malloc
+3.00 ms   0.0%	3.00 ms	      _malloc_zone_malloc
+838.00 ms   0.0%	827.00 ms	     gamma()
+9.00 ms   0.0%	1.00 ms	      leakMemory()
+5.00 ms   0.0%	0 s	       szone_malloc_should_clear
+4.00 ms   0.0%	1.00 ms	        small_malloc_should_clear
+3.00 ms   0.0%	3.00 ms	         small_malloc_from_free_list
+1.00 ms   0.0%	1.00 ms	        rack_get_thread_index
+1.00 ms   0.0%	1.00 ms	       small_malloc_should_clear
+1.00 ms   0.0%	1.00 ms	       _malloc_zone_malloc
+1.00 ms   0.0%	1.00 ms	       nanov2_malloc_type
+2.00 ms   0.0%	2.00 ms	      _malloc_zone_malloc
+834.00 ms   0.0%	824.00 ms	     beta()
+9.00 ms   0.0%	0 s	      leakMemory()
+7.00 ms   0.0%	0 s	       szone_malloc_should_clear
+6.00 ms   0.0%	1.00 ms	        small_malloc_should_clear
+4.00 ms   0.0%	4.00 ms	         small_malloc_from_free_list
+1.00 ms   0.0%	1.00 ms	         rack_get_thread_index
+1.00 ms   0.0%	1.00 ms	        rack_get_thread_index
+1.00 ms   0.0%	1.00 ms	       nanov2_malloc_type
+1.00 ms   0.0%	1.00 ms	       small_malloc_should_clear
+1.00 ms   0.0%	1.00 ms	      _malloc_zone_malloc
+803.00 ms   0.0%	788.00 ms	     alpha()
+14.00 ms   0.0%	0 s	      leakMemory()
+11.00 ms   0.0%	1.00 ms	       szone_malloc_should_clear
+10.00 ms   0.0%	3.00 ms	        small_malloc_should_clear
+5.00 ms   0.0%	5.00 ms	         small_malloc_from_free_list
+2.00 ms   0.0%	2.00 ms	         rack_get_thread_index
+1.00 ms   0.0%	1.00 ms	       nanov2_malloc_type
+1.00 ms   0.0%	1.00 ms	       small_malloc_should_clear
+1.00 ms   0.0%	1.00 ms	       _malloc_zone_malloc
+1.00 ms   0.0%	1.00 ms	      _malloc_zone_malloc
+4.00 ms   0.1%	0 s	    dyld4::start(dyld4::KernelArgs*, void*, void*)::$_0::operator()() const
+4.00 ms   0.1%	0 s	     dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*)
+3.00 ms   0.0%	0 s	      dyld4::JustInTimeLoader::loadDependents(Diagnostics&, dyld4::RuntimeState&, dyld4::Loader::LoadOptions const&)
+3.00 ms   0.0%	0 s	       mach_o::Header::forEachLinkedDylib(void (char const*, mach_o::LinkedDylibAttributes, mach_o::Version32, mach_o::Version32, bool&) block_pointer) const
+3.00 ms   0.0%	0 s	        mach_o::Header::forEachLoadCommand(void (load_command const*, bool&) block_pointer) const
+3.00 ms   0.0%	0 s	         invocation function for block in mach_o::Header::forEachLinkedDylib(void (char const*, mach_o::LinkedDylibAttributes, mach_o::Version32, mach_o::Version32, bool&) block_pointer) const
+3.00 ms   0.0%	0 s	          invocation function for block in dyld4::JustInTimeLoader::loadDependents(Diagnostics&, dyld4::RuntimeState&, dyld4::Loader::LoadOptions const&)
+3.00 ms   0.0%	0 s	           dyld4::Loader::getLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&)
+3.00 ms   0.0%	0 s	            dyld4::Loader::forEachPath(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer)
+3.00 ms   0.0%	0 s	             dyld4::ProcessConfig::PathOverrides::forEachPathVariant(char const*, dyld3::Platform, bool, bool, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) const
+3.00 ms   0.0%	0 s	              dyld4::Loader::forEachResolvedAtPathVar(dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, dyld4::ProcessConfig::PathOverrides::Type, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer)
+3.00 ms   0.0%	0 s	               invocation function for block in dyld4::Loader::getLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&)
+3.00 ms   0.0%	0 s	                dyld4::Loader::makeDyldCacheLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, unsigned int, mach_o::Layout const*)
+3.00 ms   0.0%	0 s	                 dyld4::RuntimeState::findPrebuiltLoader(char const*) const
+3.00 ms   0.0%	0 s	                  dyld4::PrebuiltLoader::isValid(dyld4::RuntimeState const&) const
+3.00 ms   0.0%	0 s	                   dyld4::PrebuiltLoader::invalidateInIsolation(dyld4::RuntimeState const&) const
+3.00 ms   0.0%	0 s	                    dyld4::ProcessConfig::PathOverrides::forEachPathVariant(char const*, dyld3::Platform, bool, bool, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) const
+3.00 ms   0.0%	0 s	                     invocation function for block in dyld4::PrebuiltLoader::invalidateInIsolation(dyld4::RuntimeState const&) const
+3.00 ms   0.0%	0 s	                      dyld4::SyscallDelegate::fileExists(char const*, dyld4::FileID*, int*) const
+3.00 ms   0.0%	0 s	                       dyld3::stat(char const*, stat*)
+3.00 ms   0.0%	3.00 ms	                        stat
+1.00 ms   0.0%	0 s	      dyld4::APIs::runAllInitializersForMain()
+1.00 ms   0.0%	0 s	       dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const
+1.00 ms   0.0%	0 s	        dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const::$_0::operator()() const
+1.00 ms   0.0%	0 s	         dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&, dyld3::Array<dyld4::Loader const*>&) const
+1.00 ms   0.0%	0 s	          dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&, dyld3::Array<dyld4::Loader const*>&) const
+1.00 ms   0.0%	0 s	           dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&, dyld3::Array<dyld4::Loader const*>&) const
+1.00 ms   0.0%	0 s	            dyld4::PrebuiltLoader::runInitializers(dyld4::RuntimeState&) const
+1.00 ms   0.0%	0 s	             dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const
+1.00 ms   0.0%	0 s	              dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const
+1.00 ms   0.0%	0 s	               dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const
+1.00 ms   0.0%	0 s	                dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const
+1.00 ms   0.0%	0 s	                 invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const
+1.00 ms   0.0%	0 s	                  invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const
+1.00 ms   0.0%	1.00 ms	                   _GLOBAL__sub_I_stdlib_typed_new.cpp
\ No newline at end of file
diff --git a/src/import/instruments.ts b/src/import/instruments.ts
index 31f3344..720fc1a 100644
--- a/src/import/instruments.ts
+++ b/src/import/instruments.ts
@@ -38,12 +38,14 @@ interface PastedTimeProfileRow {
   Weight?: string
   'Source Path'?: string
   'Symbol Name'?: string
+  'Symbol Names'?: string
 }
 
 interface PastedAllocationsProfileRow {
   'Bytes Used'?: string
   'Source Path'?: string
   'Symbol Name'?: string
+  'Symbol Names'?: string
 }
 
 interface FrameInfoWithWeight extends FrameInfo {
@@ -108,9 +110,12 @@ export function importFromInstrumentsDeepCopy(contents: TextFileContent): Profil
 
   const stack: FrameInfoWithWeight[] = []
   let cumulativeValue: number = 0
+  let leadingFirstRowSpaces: number = rows[0]['Symbol Names']
+    ? rows[0]['Symbol Names'].lastIndexOf(' ') + 1
+    : 0
 
   for (let row of rows) {
-    const symbolName = row['Symbol Name']
+    const symbolName = row['Symbol Name'] || row['Symbol Names']?.slice(leadingFirstRowSpaces)
     if (!symbolName) continue
     const trimmedSymbolName = symbolName.trim()
     let stackDepth = symbolName.length - trimmedSymbolName.length


Test patch:
diff --git a/src/import/__snapshots__/instruments.test.ts.snap b/src/import/__snapshots__/instruments.test.ts.snap
index df768b6..fc22b32 100644
--- a/src/import/__snapshots__/instruments.test.ts.snap
+++ b/src/import/__snapshots__/instruments.test.ts.snap
@@ -654,6 +654,504 @@ Object {
 }
 `;
 
+exports[`importFromInstrumentsDeepCopy time profile, version 16 1`] = `
+Object {
+  "frames": Array [
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":start",
+      "line": undefined,
+      "name": "start",
+      "selfWeight": 0,
+      "totalWeight": 4479,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":main",
+      "line": undefined,
+      "name": "main",
+      "selfWeight": 0,
+      "totalWeight": 4475,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":delta()",
+      "line": undefined,
+      "name": "delta()",
+      "selfWeight": 395,
+      "totalWeight": 2000,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":alpha()",
+      "line": undefined,
+      "name": "alpha()",
+      "selfWeight": 1574,
+      "totalWeight": 1600,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":leakMemory()",
+      "line": undefined,
+      "name": "leakMemory()",
+      "selfWeight": 2,
+      "totalWeight": 65,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":szone_malloc_should_clear",
+      "line": undefined,
+      "name": "szone_malloc_should_clear",
+      "selfWeight": 7,
+      "totalWeight": 49,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":small_malloc_should_clear",
+      "line": undefined,
+      "name": "small_malloc_should_clear",
+      "selfWeight": 20,
+      "totalWeight": 44,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":small_malloc_from_free_list",
+      "line": undefined,
+      "name": "small_malloc_from_free_list",
+      "selfWeight": 20,
+      "totalWeight": 20,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":_malloc_zone_malloc",
+      "line": undefined,
+      "name": "_malloc_zone_malloc",
+      "selfWeight": 14,
+      "totalWeight": 14,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":beta()",
+      "line": undefined,
+      "name": "beta()",
+      "selfWeight": 1602,
+      "totalWeight": 1629,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":rack_get_thread_index",
+      "line": undefined,
+      "name": "rack_get_thread_index",
+      "selfWeight": 6,
+      "totalWeight": 6,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":nanov2_malloc_type",
+      "line": undefined,
+      "name": "nanov2_malloc_type",
+      "selfWeight": 6,
+      "totalWeight": 6,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":DYLD-STUB$$malloc",
+      "line": undefined,
+      "name": "DYLD-STUB$$malloc",
+      "selfWeight": 1,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":mvm_allocate_pages_plat",
+      "line": undefined,
+      "name": "mvm_allocate_pages_plat",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":_kernelrpc_mach_vm_map_trap",
+      "line": undefined,
+      "name": "_kernelrpc_mach_vm_map_trap",
+      "selfWeight": 1,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":gamma()",
+      "line": undefined,
+      "name": "gamma()",
+      "selfWeight": 827,
+      "totalWeight": 838,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::start(dyld4::KernelArgs*, void*, void*)::$_0::operator()() const",
+      "line": undefined,
+      "name": "dyld4::start(dyld4::KernelArgs*, void*, void*)::$_0::operator()() const",
+      "selfWeight": 0,
+      "totalWeight": 4,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*)",
+      "line": undefined,
+      "name": "dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*)",
+      "selfWeight": 0,
+      "totalWeight": 4,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::JustInTimeLoader::loadDependents(Diagnostics&, dyld4::RuntimeState&, dyld4::Loader::LoadOptions const&)",
+      "line": undefined,
+      "name": "dyld4::JustInTimeLoader::loadDependents(Diagnostics&, dyld4::RuntimeState&, dyld4::Loader::LoadOptions const&)",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":mach_o::Header::forEachLinkedDylib(void (char const*, mach_o::LinkedDylibAttributes, mach_o::Version32, mach_o::Version32, bool&) block_pointer) const",
+      "line": undefined,
+      "name": "mach_o::Header::forEachLinkedDylib(void (char const*, mach_o::LinkedDylibAttributes, mach_o::Version32, mach_o::Version32, bool&) block_pointer) const",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":mach_o::Header::forEachLoadCommand(void (load_command const*, bool&) block_pointer) const",
+      "line": undefined,
+      "name": "mach_o::Header::forEachLoadCommand(void (load_command const*, bool&) block_pointer) const",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":invocation function for block in mach_o::Header::forEachLinkedDylib(void (char const*, mach_o::LinkedDylibAttributes, mach_o::Version32, mach_o::Version32, bool&) block_pointer) const",
+      "line": undefined,
+      "name": "invocation function for block in mach_o::Header::forEachLinkedDylib(void (char const*, mach_o::LinkedDylibAttributes, mach_o::Version32, mach_o::Version32, bool&) block_pointer) const",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":invocation function for block in dyld4::JustInTimeLoader::loadDependents(Diagnostics&, dyld4::RuntimeState&, dyld4::Loader::LoadOptions const&)",
+      "line": undefined,
+      "name": "invocation function for block in dyld4::JustInTimeLoader::loadDependents(Diagnostics&, dyld4::RuntimeState&, dyld4::Loader::LoadOptions const&)",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::Loader::getLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&)",
+      "line": undefined,
+      "name": "dyld4::Loader::getLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&)",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::Loader::forEachPath(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer)",
+      "line": undefined,
+      "name": "dyld4::Loader::forEachPath(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer)",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::ProcessConfig::PathOverrides::forEachPathVariant(char const*, dyld3::Platform, bool, bool, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) const",
+      "line": undefined,
+      "name": "dyld4::ProcessConfig::PathOverrides::forEachPathVariant(char const*, dyld3::Platform, bool, bool, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) const",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::Loader::forEachResolvedAtPathVar(dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, dyld4::ProcessConfig::PathOverrides::Type, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer)",
+      "line": undefined,
+      "name": "dyld4::Loader::forEachResolvedAtPathVar(dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, dyld4::ProcessConfig::PathOverrides::Type, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer)",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":invocation function for block in dyld4::Loader::getLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&)",
+      "line": undefined,
+      "name": "invocation function for block in dyld4::Loader::getLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&)",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::Loader::makeDyldCacheLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, unsigned int, mach_o::Layout const*)",
+      "line": undefined,
+      "name": "dyld4::Loader::makeDyldCacheLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, unsigned int, mach_o::Layout const*)",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::RuntimeState::findPrebuiltLoader(char const*) const",
+      "line": undefined,
+      "name": "dyld4::RuntimeState::findPrebuiltLoader(char const*) const",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::PrebuiltLoader::isValid(dyld4::RuntimeState const&) const",
+      "line": undefined,
+      "name": "dyld4::PrebuiltLoader::isValid(dyld4::RuntimeState const&) const",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::PrebuiltLoader::invalidateInIsolation(dyld4::RuntimeState const&) const",
+      "line": undefined,
+      "name": "dyld4::PrebuiltLoader::invalidateInIsolation(dyld4::RuntimeState const&) const",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":invocation function for block in dyld4::PrebuiltLoader::invalidateInIsolation(dyld4::RuntimeState const&) const",
+      "line": undefined,
+      "name": "invocation function for block in dyld4::PrebuiltLoader::invalidateInIsolation(dyld4::RuntimeState const&) const",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::SyscallDelegate::fileExists(char const*, dyld4::FileID*, int*) const",
+      "line": undefined,
+      "name": "dyld4::SyscallDelegate::fileExists(char const*, dyld4::FileID*, int*) const",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld3::stat(char const*, stat*)",
+      "line": undefined,
+      "name": "dyld3::stat(char const*, stat*)",
+      "selfWeight": 0,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":stat",
+      "line": undefined,
+      "name": "stat",
+      "selfWeight": 3,
+      "totalWeight": 3,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::APIs::runAllInitializersForMain()",
+      "line": undefined,
+      "name": "dyld4::APIs::runAllInitializersForMain()",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const",
+      "line": undefined,
+      "name": "dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const::$_0::operator()() const",
+      "line": undefined,
+      "name": "dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const::$_0::operator()() const",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&, dyld3::Array<dyld4::Loader const*>&) const",
+      "line": undefined,
+      "name": "dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&, dyld3::Array<dyld4::Loader const*>&) const",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::PrebuiltLoader::runInitializers(dyld4::RuntimeState&) const",
+      "line": undefined,
+      "name": "dyld4::PrebuiltLoader::runInitializers(dyld4::RuntimeState&) const",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const",
+      "line": undefined,
+      "name": "dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const",
+      "line": undefined,
+      "name": "dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const",
+      "line": undefined,
+      "name": "dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const",
+      "line": undefined,
+      "name": "dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const",
+      "line": undefined,
+      "name": "invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const",
+      "line": undefined,
+      "name": "invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const",
+      "selfWeight": 0,
+      "totalWeight": 1,
+    },
+    Frame {
+      "col": undefined,
+      "file": undefined,
+      "key": ":_GLOBAL__sub_I_stdlib_typed_new.cpp",
+      "line": undefined,
+      "name": "_GLOBAL__sub_I_stdlib_typed_new.cpp",
+      "selfWeight": 1,
+      "totalWeight": 1,
+    },
+  ],
+  "name": "simple-time-profile-deep-copy.txt",
+  "stacks": Array [
+    "start;main;delta();alpha();leakMemory();szone_malloc_should_clear;small_malloc_should_clear;small_malloc_from_free_list 2.00ms",
+    "start;main;delta();alpha();leakMemory();szone_malloc_should_clear;small_malloc_should_clear 4.00ms",
+    "start;main;delta();alpha();leakMemory();szone_malloc_should_clear;small_malloc_from_free_list 1.00ms",
+    "start;main;delta();alpha();leakMemory();szone_malloc_should_clear 1.00ms",
+    "start;main;delta();alpha();leakMemory();_malloc_zone_malloc 1.00ms",
+    "start;main;delta();alpha();_malloc_zone_malloc 2.00ms",
+    "start;main;delta();alpha() 786.00ms",
+    "start;main;delta();beta();leakMemory();szone_malloc_should_clear;small_malloc_should_clear;small_malloc_from_free_list 5.00ms",
+    "start;main;delta();beta();leakMemory();szone_malloc_should_clear;small_malloc_should_clear;rack_get_thread_index 1.00ms",
+    "start;main;delta();beta();leakMemory();szone_malloc_should_clear;small_malloc_should_clear 3.00ms",
+    "start;main;delta();beta();leakMemory();szone_malloc_should_clear 2.00ms",
+    "start;main;delta();beta();leakMemory();nanov2_malloc_type 1.00ms",
+    "start;main;delta();beta();leakMemory();DYLD-STUB$$malloc 1.00ms",
+    "start;main;delta();beta();leakMemory() 1.00ms",
+    "start;main;delta();beta();nanov2_malloc_type 2.00ms",
+    "start;main;delta();beta();_malloc_zone_malloc 1.00ms",
+    "start;main;delta();beta() 778.00ms",
+    "start;main;delta();leakMemory();szone_malloc_should_clear;small_malloc_should_clear;mvm_allocate_pages_plat;_kernelrpc_mach_vm_map_trap 1.00ms",
+    "start;main;delta();leakMemory();szone_malloc_should_clear;small_malloc_should_clear 3.00ms",
+    "start;main;delta();leakMemory();szone_malloc_should_clear 3.00ms",
+    "start;main;delta();leakMemory();small_malloc_should_clear 2.00ms",
+    "start;main;delta();leakMemory();_malloc_zone_malloc 1.00ms",
+    "start;main;delta();_malloc_zone_malloc 3.00ms",
+    "start;main;delta() 395.00ms",
+    "start;main;gamma();leakMemory();szone_malloc_should_clear;small_malloc_should_clear;small_malloc_from_free_list 3.00ms",
+    "start;main;gamma();leakMemory();szone_malloc_should_clear;small_malloc_should_clear 1.00ms",
+    "start;main;gamma();leakMemory();szone_malloc_should_clear;rack_get_thread_index 1.00ms",
+    "start;main;gamma();leakMemory();small_malloc_should_clear 1.00ms",
+    "start;main;gamma();leakMemory();_malloc_zone_malloc 1.00ms",
+    "start;main;gamma();leakMemory();nanov2_malloc_type 1.00ms",
+    "start;main;gamma();leakMemory() 1.00ms",
+    "start;main;gamma();_malloc_zone_malloc 2.00ms",
+    "start;main;gamma() 827.00ms",
+    "start;main;beta();leakMemory();szone_malloc_should_clear;small_malloc_should_clear;small_malloc_from_free_list 4.00ms",
+    "start;main;beta();leakMemory();szone_malloc_should_clear;small_malloc_should_clear;rack_get_thread_index 1.00ms",
+    "start;main;beta();leakMemory();szone_malloc_should_clear;small_malloc_should_clear 1.00ms",
+    "start;main;beta();leakMemory();szone_malloc_should_clear;rack_get_thread_index 1.00ms",
+    "start;main;beta();leakMemory();nanov2_malloc_type 1.00ms",
+    "start;main;beta();leakMemory();small_malloc_should_clear 1.00ms",
+    "start;main;beta();_malloc_zone_malloc 1.00ms",
+    "start;main;beta() 824.00ms",
+    "start;main;alpha();leakMemory();szone_malloc_should_clear;small_malloc_should_clear;small_malloc_from_free_list 5.00ms",
+    "start;main;alpha();leakMemory();szone_malloc_should_clear;small_malloc_should_clear;rack_get_thread_index 2.00ms",
+    "start;main;alpha();leakMemory();szone_malloc_should_clear;small_malloc_should_clear 3.00ms",
+    "start;main;alpha();leakMemory();szone_malloc_should_clear 1.00ms",
+    "start;main;alpha();leakMemory();nanov2_malloc_type 1.00ms",
+    "start;main;alpha();leakMemory();small_malloc_should_clear 1.00ms",
+    "start;main;alpha();leakMemory();_malloc_zone_malloc 1.00ms",
+    "start;main;alpha();_malloc_zone_malloc 1.00ms",
+    "start;main;alpha() 788.00ms",
+    "start;dyld4::start(dyld4::KernelArgs*, void*, void*)::$_0::operator()() const;dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*);dyld4::JustInTimeLoader::loadDependents(Diagnostics&, dyld4::RuntimeState&, dyld4::Loader::LoadOptions const&);mach_o::Header::forEachLinkedDylib(void (char const*, mach_o::LinkedDylibAttributes, mach_o::Version32, mach_o::Version32, bool&) block_pointer) const;mach_o::Header::forEachLoadCommand(void (load_command const*, bool&) block_pointer) const;invocation function for block in mach_o::Header::forEachLinkedDylib(void (char const*, mach_o::LinkedDylibAttributes, mach_o::Version32, mach_o::Version32, bool&) block_pointer) const;invocation function for block in dyld4::JustInTimeLoader::loadDependents(Diagnostics&, dyld4::RuntimeState&, dyld4::Loader::LoadOptions const&);dyld4::Loader::getLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&);dyld4::Loader::forEachPath(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer);dyld4::ProcessConfig::PathOverrides::forEachPathVariant(char const*, dyld3::Platform, bool, bool, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) const;dyld4::Loader::forEachResolvedAtPathVar(dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, dyld4::ProcessConfig::PathOverrides::Type, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer);invocation function for block in dyld4::Loader::getLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&);dyld4::Loader::makeDyldCacheLoader(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, unsigned int, mach_o::Layout const*);dyld4::RuntimeState::findPrebuiltLoader(char const*) const;dyld4::PrebuiltLoader::isValid(dyld4::RuntimeState const&) const;dyld4::PrebuiltLoader::invalidateInIsolation(dyld4::RuntimeState const&) const;dyld4::ProcessConfig::PathOverrides::forEachPathVariant(char const*, dyld3::Platform, bool, bool, bool&, void (char const*, dyld4::ProcessConfig::PathOverrides::Type, bool&) block_pointer) const;invocation function for block in dyld4::PrebuiltLoader::invalidateInIsolation(dyld4::RuntimeState const&) const;dyld4::SyscallDelegate::fileExists(char const*, dyld4::FileID*, int*) const;dyld3::stat(char const*, stat*);stat 3.00ms",
+    "start;dyld4::start(dyld4::KernelArgs*, void*, void*)::$_0::operator()() const;dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*);dyld4::APIs::runAllInitializersForMain();dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const;dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const::$_0::operator()() const;dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&, dyld3::Array<dyld4::Loader const*>&) const;dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&, dyld3::Array<dyld4::Loader const*>&) const;dyld4::Loader::runInitializersBottomUp(dyld4::RuntimeState&, dyld3::Array<dyld4::Loader const*>&, dyld3::Array<dyld4::Loader const*>&) const;dyld4::PrebuiltLoader::runInitializers(dyld4::RuntimeState&) const;dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const;dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const;dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const;dyld3::MachOFile::forEachLoadCommand(Diagnostics&, void (load_command const*, bool&) block_pointer) const;invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const;invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const;_GLOBAL__sub_I_stdlib_typed_new.cpp 1.00ms",
+  ],
+}
+`;
+
+exports[`importFromInstrumentsDeepCopy time profile, version 16: indexToView 1`] = `0`;
+
+exports[`importFromInstrumentsDeepCopy time profile, version 16: profileGroup.name 1`] = `"simple-time-profile-deep-copy.txt"`;
+
 exports[`importFromInstrumentsDeepCopy time profile: indexToView 1`] = `0`;
 
 exports[`importFromInstrumentsDeepCopy time profile: profileGroup.name 1`] = `"simple-time-profile-deep-copy.txt"`;
diff --git a/src/import/instruments.test.ts b/src/import/instruments.test.ts
index 2546298..ddfe6de 100644
--- a/src/import/instruments.test.ts
+++ b/src/import/instruments.test.ts
@@ -12,6 +12,12 @@ describe('importFromInstrumentsDeepCopy', () => {
     )
   })
 
+  test('time profile, version 16', async () => {
+    await checkProfileSnapshot(
+      './sample/profiles/Instruments/16.0/simple-time-profile-deep-copy.txt',
+    )
+  })
+
   test('allocations profile', async () => {
     await checkProfileSnapshot(
       './sample/profiles/Instruments/7.3.1/random-allocations-deep-copy.txt',