1/*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef ECMASCRIPT_DFX_HPROF_HEAP_TRACKER_H
17#define ECMASCRIPT_DFX_HPROF_HEAP_TRACKER_H
18
19#include <atomic>
20#include <cstdint>
21#include <thread>
22
23#include "ecmascript/dfx/hprof/file_stream.h"
24#include "ecmascript/mem/tagged_object.h"
25
26#include "libpandabase/macros.h"
27
28namespace panda::ecmascript {
29class HeapSnapshot;
30
31class HeapTrackerSample {
32public:
33    HeapTrackerSample(HeapSnapshot *snapshot, double timeInterval, Stream *stream)
34        : timeInterval_(timeInterval), snapshot_(snapshot), stream_(stream)
35    {
36    }
37
38    ~HeapTrackerSample()
39    {
40        isInterrupt_ = true;
41    }
42
43    void Start()
44    {
45        isInterrupt_ = false;
46        thread_ = std::thread(&HeapTrackerSample::Run, this);
47    }
48
49    void Stop()
50    {
51        isInterrupt_ = true;
52        if (thread_.joinable()) {
53            thread_.join();
54        }
55    }
56
57    void Run();
58
59    NO_COPY_SEMANTIC(HeapTrackerSample);
60    NO_MOVE_SEMANTIC(HeapTrackerSample);
61
62private:
63    std::thread thread_;
64    std::atomic_bool isInterrupt_ = true;
65    double timeInterval_ = 0;
66    HeapSnapshot *snapshot_;
67    Stream *stream_ {nullptr};
68};
69
70class HeapTracker {
71public:
72    HeapTracker(HeapSnapshot *snapshot, double timeInterval, Stream *stream)
73        : snapshot_(snapshot), sample_(snapshot, timeInterval, stream) {}
74    ~HeapTracker() = default;
75
76    void StartTracing()
77    {
78        sample_.Start();
79    }
80
81    void StopTracing()
82    {
83        sample_.Stop();
84    }
85
86    HeapSnapshot* GetHeapSnapshot() const
87    {
88        return snapshot_;
89    }
90
91    void AllocationEvent(TaggedObject *address, size_t size);
92    void MoveEvent(uintptr_t address, TaggedObject *forwardAddress, size_t size);
93
94    NO_COPY_SEMANTIC(HeapTracker);
95    NO_MOVE_SEMANTIC(HeapTracker);
96
97private:
98    HeapSnapshot *snapshot_;
99    HeapTrackerSample sample_;
100    TaggedObject *prevAllocation_ {nullptr};
101};
102}  // namespace panda::ecmascript
103#endif  // ECMASCRIPT_DFX_HPROF_HEAP_TRACKER_H
104