1/* Copyright (C) 2021 Free Software Foundation, Inc.
2   Contributed by Oracle.
3
4   This file is part of GNU Binutils.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, 51 Franklin Street - Fifth Floor, Boston,
19   MA 02110-1301, USA.  */
20
21#include "config.h"
22#include <assert.h>
23#include <string.h>
24
25#include "util.h"
26#include "HeapData.h"
27
28void
29HeapData::init ()
30{
31  allocBytes = 0;
32  leakBytes = 0;
33  allocCnt = 0;
34  leakCnt = 0;
35  stackId = 0;
36  histType = Histable::HEAPCALLSTACK;
37  peakMemUsage = 0;
38  timestamp = 0;
39  pid = 0;
40  userExpId = 0;
41  aSmallestBytes = _10TB;
42  aLargestBytes = 0;
43  a0KB1KBCnt = 0;
44  a1KB8KBCnt = 0;
45  a8KB32KBCnt = 0;
46  a32KB128KBCnt = 0;
47  a128KB256KBCnt = 0;
48  a256KB512KBCnt = 0;
49  a512KB1000KBCnt = 0;
50  a1000KB10MBCnt = 0;
51  a10MB100MBCnt = 0;
52  a100MB1GBCnt = 0;
53  a1GB10GBCnt = 0;
54  a10GB100GBCnt = 0;
55  a100GB1TBCnt = 0;
56  a1TB10TBCnt = 0;
57
58  lSmallestBytes = _10TB;
59  lLargestBytes = 0;
60  l0KB1KBCnt = 0;
61  l1KB8KBCnt = 0;
62  l8KB32KBCnt = 0;
63  l32KB128KBCnt = 0;
64  l128KB256KBCnt = 0;
65  l256KB512KBCnt = 0;
66  l512KB1000KBCnt = 0;
67  l1000KB10MBCnt = 0;
68  l10MB100MBCnt = 0;
69  l100MB1GBCnt = 0;
70  l1GB10GBCnt = 0;
71  l10GB100GBCnt = 0;
72  l100GB1TBCnt = 0;
73  l1TB10TBCnt = 0;
74}
75
76HeapData::HeapData (char *sName)
77{
78  stackName = dbe_strdup (sName);
79  peakStackIds = new Vector<uint64_t>;
80  peakTimestamps = new Vector<hrtime_t>;
81  init ();
82}
83
84HeapData::HeapData (HeapData *hData)
85{
86  stackName = dbe_strdup (hData->stackName);
87  stackId = hData->stackId;
88  histType = hData->histType;
89  allocBytes = hData->allocBytes;
90  leakBytes = hData->leakBytes;
91  allocCnt = hData->allocCnt;
92  leakCnt = hData->leakCnt;
93  peakMemUsage = hData->peakMemUsage;
94  timestamp = hData->timestamp;
95  pid = hData->getPid ();
96  userExpId = hData->getUserExpId ();
97  peakStackIds = new Vector<uint64_t>;
98  Vector<uint64_t> *sIds = hData->peakStackIds;
99  uint64_t sId;
100  if (sIds != NULL)
101    for (int i = 0; i < sIds->size (); i++)
102      {
103	sId = sIds->fetch (i);
104	peakStackIds->append (sId);
105      }
106
107  peakTimestamps = new Vector<hrtime_t>;
108  Vector<hrtime_t> *pts = hData->peakTimestamps;
109  hrtime_t ts;
110  if (pts != NULL)
111    for (int i = 0; i < pts->size (); i++)
112      {
113	ts = pts->fetch (i);
114	peakTimestamps->append (ts);
115      }
116
117  aSmallestBytes = hData->aSmallestBytes;
118  aLargestBytes = hData->aLargestBytes;
119  a0KB1KBCnt = hData->a0KB1KBCnt;
120  a1KB8KBCnt = hData->a1KB8KBCnt;
121  a8KB32KBCnt = hData->a8KB32KBCnt;
122  a32KB128KBCnt = hData->a32KB128KBCnt;
123  a128KB256KBCnt = hData->a128KB256KBCnt;
124  a256KB512KBCnt = hData->a256KB512KBCnt;
125  a512KB1000KBCnt = hData->a512KB1000KBCnt;
126  a1000KB10MBCnt = hData->a1000KB10MBCnt;
127  a10MB100MBCnt = hData->a10MB100MBCnt;
128  a100MB1GBCnt = hData->a100MB1GBCnt;
129  a1GB10GBCnt = hData->a1GB10GBCnt;
130  a10GB100GBCnt = hData->a10GB100GBCnt;
131  a100GB1TBCnt = hData->a100GB1TBCnt;
132  a1TB10TBCnt = hData->a1TB10TBCnt;
133
134  lSmallestBytes = hData->lSmallestBytes;
135  lLargestBytes = hData->lLargestBytes;
136  l0KB1KBCnt = hData->l0KB1KBCnt;
137  l1KB8KBCnt = hData->l1KB8KBCnt;
138  l8KB32KBCnt = hData->l8KB32KBCnt;
139  l32KB128KBCnt = hData->l32KB128KBCnt;
140  l128KB256KBCnt = hData->l128KB256KBCnt;
141  l256KB512KBCnt = hData->l256KB512KBCnt;
142  l512KB1000KBCnt = hData->l512KB1000KBCnt;
143  l1000KB10MBCnt = hData->l1000KB10MBCnt;
144  l10MB100MBCnt = hData->l10MB100MBCnt;
145  l100MB1GBCnt = hData->l100MB1GBCnt;
146  l1GB10GBCnt = hData->l1GB10GBCnt;
147  l10GB100GBCnt = hData->l10GB100GBCnt;
148  l100GB1TBCnt = hData->l100GB1TBCnt;
149  l1TB10TBCnt = hData->l1TB10TBCnt;
150}
151
152HeapData::~HeapData ()
153{
154  free (stackName);
155  delete peakStackIds;
156  delete peakTimestamps;
157}
158
159Histable*
160HeapData::convertto (Histable_type type, Histable*)
161{
162  return type == histType ? this : NULL;
163}
164
165char*
166HeapData::get_name (Histable::NameFormat /*_nfmt*/)
167{
168  return stackName;
169}
170
171char*
172HeapData::get_raw_name (Histable::NameFormat /*_nfmt*/)
173{
174  return stackName;
175}
176
177void
178HeapData::set_name (char* _name)
179{
180  free (stackName);
181  stackName = dbe_strdup (_name);
182}
183
184void
185HeapData::setPeakMemUsage (int64_t pmu, uint64_t sId, hrtime_t ts, int procId, int uei)
186{
187  if (peakMemUsage < pmu)
188    {
189      peakMemUsage = pmu;
190      peakStackIds->reset ();
191      peakStackIds->append (sId);
192      peakTimestamps->reset ();
193      peakTimestamps->append (ts);
194      pid = procId;
195      userExpId = uei;
196    }
197  else if (peakMemUsage == pmu)
198    {
199      for (int i = 0; i < peakStackIds->size (); i++)
200	{
201	  uint64_t curSId = peakStackIds->fetch (i);
202	  if (curSId == sId)
203	    return;
204	}
205      peakStackIds->append (sId);
206      peakTimestamps->append (ts);
207      pid = procId;
208      userExpId = uei;
209    }
210}
211
212void
213HeapData::setAllocStat (int64_t nb)
214{
215  if (aSmallestBytes > nb)
216    aSmallestBytes = nb;
217  if (aLargestBytes < nb)
218    aLargestBytes = nb;
219  if (nb >= 0 && nb <= _1KB)
220    a0KB1KBCnt++;
221  else if (nb <= _8KB)
222    a1KB8KBCnt++;
223  else if (nb <= _32KB)
224    a8KB32KBCnt++;
225  else if (nb <= _128KB)
226    a32KB128KBCnt++;
227  else if (nb <= _256KB)
228    a128KB256KBCnt++;
229  else if (nb <= _512KB)
230    a256KB512KBCnt++;
231  else if (nb <= _1000KB)
232    a512KB1000KBCnt++;
233  else if (nb <= _10MB)
234    a1000KB10MBCnt++;
235  else if (nb <= _100MB)
236    a10MB100MBCnt++;
237  else if (nb <= _1GB)
238    a100MB1GBCnt++;
239  else if (nb <= _10GB)
240    a1GB10GBCnt++;
241  else if (nb <= _100GB)
242    a10GB100GBCnt++;
243  else if (nb <= _1TB)
244    a100GB1TBCnt++;
245  else if (nb <= _10TB)
246    a1TB10TBCnt++;
247}
248
249void
250HeapData::setLeakStat (int64_t nb)
251{
252  if (lSmallestBytes > nb)
253    lSmallestBytes = nb;
254  if (lLargestBytes < nb)
255    lLargestBytes = nb;
256  if (nb >= 0 && nb <= _1KB)
257    l0KB1KBCnt++;
258  else if (nb <= _8KB)
259    l1KB8KBCnt++;
260  else if (nb <= _32KB)
261    l8KB32KBCnt++;
262  else if (nb <= _128KB)
263    l32KB128KBCnt++;
264  else if (nb <= _256KB)
265    l128KB256KBCnt++;
266  else if (nb <= _512KB)
267    l256KB512KBCnt++;
268  else if (nb <= _1000KB)
269    l512KB1000KBCnt++;
270  else if (nb <= _10MB)
271    l1000KB10MBCnt++;
272  else if (nb <= _100MB)
273    l10MB100MBCnt++;
274  else if (nb <= _1GB)
275    l100MB1GBCnt++;
276  else if (nb <= _10GB)
277    l1GB10GBCnt++;
278  else if (nb <= _100GB)
279    l10GB100GBCnt++;
280  else if (nb <= _1TB)
281    l100GB1TBCnt++;
282  else if (nb <= _10TB)
283    l1TB10TBCnt++;
284}
285