| # Copyright 2022 The Fuchsia Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| import json | |
| class VMO(object): | |
| def __init__(self, v, names): | |
| self.koid = int(v[0]) | |
| self.name = names[v[1]] | |
| self.parent_koid = int(v[2]) | |
| self.committed_bytes = int(v[3]) | |
| self.allocated_bytes = int(v[4]) | |
| def __hash__(self): | |
| return hash((self.koid, self.name)) | |
| def __eq__(self, other): | |
| return self.koid == other.koid and self.name == other.name | |
| def __ne__(self, other): | |
| return not self.__eq__(other) | |
| def __repr__(self): | |
| return "VMO %d (%s)" % (self.koid, self.name) | |
| class Process(object): | |
| def __init__(self, p, vmos): | |
| self.koid = int(p[0]) | |
| self.name = p[1] | |
| self.vmos = [vmos[int(v)] for v in p[2]] | |
| def __hash__(self): | |
| return hash((self.koid, self.name)) | |
| def __eq__(self, other): | |
| return self.koid == other.koid and self.name == other.name | |
| def __ne__(self, other): | |
| return not self.__eq__(other) | |
| def __str__(self): | |
| return self.full_name | |
| def __repr__(self): | |
| return self.__str__() | |
| @property | |
| def full_name(self): | |
| return "%s[%d]" % (self.name, self.koid) | |
| class Kernel(object): | |
| def __init__(self, k): | |
| self.wired = k["wired"] | |
| self.total_heap = k["total_heap"] | |
| self.mmu = k["mmu"] | |
| self.ipc = k["ipc"] | |
| self.other = k["other"] | |
| self.vmo = k["vmo"] | |
| class Snapshot(object): | |
| @classmethod | |
| def FromJSON(cls, snap_json): | |
| return Snapshot(snap_json) | |
| @classmethod | |
| def FromJSONFile(cls, snap_file): | |
| return cls.FromJSON(json.load(snap_file)) | |
| @classmethod | |
| def FromJSONString(cls, snap_string): | |
| return cls.FromJSON(json.loads(snap_string)) | |
| @classmethod | |
| def FromJSONFilename(cls, snap_filename): | |
| with open(snap_filename) as snap_file: | |
| return cls.FromJSONFile(snap_file) | |
| def __init__(self, snap_json): | |
| vmo_names = snap_json["VmoNames"] | |
| self.kernel = Kernel(snap_json["Kernel"]) | |
| self.vmos = {v[0]: VMO(v, vmo_names) for v in snap_json["Vmos"][1:]} | |
| self.processes = { | |
| p[0]: Process(p, self.vmos) for p in snap_json["Processes"][1:] | |
| } | |
| vmo_bytes = 0 | |
| for v in self.vmos.values(): | |
| vmo_bytes += v.committed_bytes | |
| self.orphaned = self.kernel.vmo - vmo_bytes |