-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[swift-inspect] Add json and summary options to DumpRawMetadata #81186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,23 @@ | |
|
||
import ArgumentParser | ||
import SwiftRemoteMirror | ||
import Foundation | ||
|
||
private struct AllocatorTagTotal: Encodable { | ||
let name: String | ||
let tag: Int | ||
var totalBytes: Int | ||
} | ||
|
||
private struct Summary: Encodable { | ||
let totalBytesAllocated: Int | ||
let allocatorTags: [AllocatorTagTotal] | ||
} | ||
|
||
private struct RawMetadataOutput: Encodable { | ||
let allocationList: [swift_metadata_allocation_t]? | ||
let summary: Summary? | ||
} | ||
|
||
internal struct DumpRawMetadata: ParsableCommand { | ||
static let configuration = CommandConfiguration( | ||
|
@@ -22,8 +39,15 @@ internal struct DumpRawMetadata: ParsableCommand { | |
|
||
@OptionGroup() | ||
var backtraceOptions: BacktraceOptions | ||
|
||
@OptionGroup() | ||
var metadataOptions: MetadataOptions | ||
|
||
func run() throws { | ||
var allocatorTagTotals = [Int: AllocatorTagTotal]() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's drop There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah realized we can't easily get |
||
var total: Int = 0 | ||
var allocationList: [swift_metadata_allocation_t] = [] | ||
|
||
try inspect(options: options) { process in | ||
let stacks: [swift_reflection_ptr_t:[swift_reflection_ptr_t]]? = | ||
backtraceOptions.style == nil | ||
|
@@ -33,6 +57,18 @@ internal struct DumpRawMetadata: ParsableCommand { | |
try process.context.allocations.forEach { allocation in | ||
let name: String = process.context.name(allocation: allocation.tag) ?? "<unknown>" | ||
print("Metadata allocation at: \(hex: allocation.ptr) size: \(allocation.size) tag: \(allocation.tag) (\(name))") | ||
|
||
if metadataOptions.summary { | ||
if var allocatorTagTotal = allocatorTagTotals[Int(allocation.tag)] { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a fun shorthand way to write this. Assuming this dictionary is now typed
|
||
allocatorTagTotal.totalBytes += allocation.size | ||
allocatorTagTotals[Int(allocation.tag)] = allocatorTagTotal | ||
} else { | ||
allocatorTagTotals[Int(allocation.tag)] = AllocatorTagTotal(name: name, tag: Int(allocation.tag), totalBytes: allocation.size) | ||
} | ||
|
||
total += allocation.size | ||
} | ||
allocationList.append(allocation) | ||
if let style = backtraceOptions.style { | ||
if let stack = stacks?[allocation.ptr] { | ||
print(backtrace(stack, style: style, process.symbolicate)) | ||
|
@@ -42,5 +78,27 @@ internal struct DumpRawMetadata: ParsableCommand { | |
} | ||
} | ||
} | ||
|
||
if metadataOptions.json { | ||
let jsonStruct: RawMetadataOutput | ||
let allocatorTagArray = Array(allocatorTagTotals.values).sorted(by: {$0.totalBytes > $1.totalBytes}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you change the dictionary as suggested above, then you can grab the keys and values together and sort them like:
Then you can iterate like:
|
||
|
||
if metadataOptions.summary { | ||
let summaryStruct = Summary(totalBytesAllocated: total, allocatorTags: allocatorTagArray) | ||
jsonStruct = RawMetadataOutput(allocationList: allocationList, summary: summaryStruct) | ||
} else { | ||
jsonStruct = RawMetadataOutput(allocationList: allocationList, summary: nil) | ||
} | ||
try dumpJson(of: jsonStruct, outputFile: metadataOptions.outputFile) | ||
} else if metadataOptions.summary { | ||
let allocatorTagArray = Array(allocatorTagTotals.values).sorted(by: {$0.totalBytes > $1.totalBytes}) | ||
|
||
print("Metadata allocation summary:") | ||
for tag in allocatorTagArray { | ||
print("Tag: \(tag.tag) (\(tag.name)) Size: \(tag.totalBytes) bytes") | ||
} | ||
|
||
print("\nTotal bytes allocated: \(total)") | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why has this moved from the
metadataOptions
group?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MetadataOptions
was previouslyGenericMetadataOptions
and only provided options forswift-inspect --dump-generic-metadata
. This PR is proposing that three of the four options fromGenericMetadataOptions
(json
,summary', and
outputFile) be added to
swift-inspect --dump-raw-metadata. Rather than manually type these options out in [DumpRawMetadata.swift](https://github.com/swiftlang/swift/pull/81186/files#diff-bbb7ba64f4c92e0e341aa925f49f73da14ed9d4aeb92ea4f2e8c50f7c10cc129), I opted to share this set of
ParsableArguments`, hence the name change.However, this PR does not implement the pre-existing
mangled
option in--dump-raw-metadata
. Which is why I chose to remove it from this now more generally usedGenericMetadataOptions
.