• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (c) 2021 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  #include "ecmascript/tooling/agent/heapprofiler_impl.h"
17  
18  namespace panda::ecmascript::tooling {
Dispatch(const DispatchRequest & request)19  void HeapProfilerImpl::DispatcherImpl::Dispatch(const DispatchRequest &request)
20  {
21      static std::unordered_map<std::string, AgentHandler> dispatcherTable {
22          { "addInspectedHeapObject", &HeapProfilerImpl::DispatcherImpl::AddInspectedHeapObject },
23          { "collectGarbage", &HeapProfilerImpl::DispatcherImpl::CollectGarbage },
24          { "enable", &HeapProfilerImpl::DispatcherImpl::Enable },
25          { "disable", &HeapProfilerImpl::DispatcherImpl::Disable },
26          { "getHeapObjectId", &HeapProfilerImpl::DispatcherImpl::GetHeapObjectId },
27          { "getObjectByHeapObjectId", &HeapProfilerImpl::DispatcherImpl::GetObjectByHeapObjectId },
28          { "getSamplingProfile", &HeapProfilerImpl::DispatcherImpl::GetSamplingProfile },
29          { "startSampling", &HeapProfilerImpl::DispatcherImpl::StartSampling },
30          { "startTrackingHeapObjects", &HeapProfilerImpl::DispatcherImpl::StartTrackingHeapObjects },
31          { "stopSampling", &HeapProfilerImpl::DispatcherImpl::StopSampling },
32          { "stopTrackingHeapObjects", &HeapProfilerImpl::DispatcherImpl::StopTrackingHeapObjects },
33          { "takeHeapSnapshot", &HeapProfilerImpl::DispatcherImpl::TakeHeapSnapshot }
34      };
35  
36      const std::string &method = request.GetMethod();
37      LOG(DEBUG, DEBUGGER) << "dispatch [" << method << "] to HeapProfilerImpl";
38      auto entry = dispatcherTable.find(method);
39      if (entry != dispatcherTable.end() && entry->second != nullptr) {
40          (this->*(entry->second))(request);
41      } else {
42          SendResponse(request, DispatchResponse::Fail("Unknown method: " + method));
43      }
44  }
45  
AddInspectedHeapObject(const DispatchRequest & request)46  void HeapProfilerImpl::DispatcherImpl::AddInspectedHeapObject(const DispatchRequest &request)
47  {
48      std::unique_ptr<AddInspectedHeapObjectParams> params = AddInspectedHeapObjectParams::Create(request.GetParams());
49      if (params == nullptr) {
50          SendResponse(request, DispatchResponse::Fail("wrong params"));
51          return;
52      }
53      DispatchResponse response = heapprofiler_->AddInspectedHeapObject(*params);
54      SendResponse(request, response);
55  }
56  
CollectGarbage(const DispatchRequest & request)57  void HeapProfilerImpl::DispatcherImpl::CollectGarbage(const DispatchRequest &request)
58  {
59      DispatchResponse response = heapprofiler_->CollectGarbage();
60      SendResponse(request, response);
61  }
62  
Enable(const DispatchRequest & request)63  void HeapProfilerImpl::DispatcherImpl::Enable(const DispatchRequest &request)
64  {
65      DispatchResponse response = heapprofiler_->Enable();
66      SendResponse(request, response);
67  }
68  
Disable(const DispatchRequest & request)69  void HeapProfilerImpl::DispatcherImpl::Disable(const DispatchRequest &request)
70  {
71      DispatchResponse response = heapprofiler_->Disable();
72      SendResponse(request, response);
73  }
74  
GetHeapObjectId(const DispatchRequest & request)75  void HeapProfilerImpl::DispatcherImpl::GetHeapObjectId(const DispatchRequest &request)
76  {
77      std::unique_ptr<GetHeapObjectIdParams> params = GetHeapObjectIdParams::Create(request.GetParams());
78      if (params == nullptr) {
79          SendResponse(request, DispatchResponse::Fail("wrong params"));
80          return;
81      }
82  
83      HeapSnapshotObjectId objectId;
84      DispatchResponse response = heapprofiler_->GetHeapObjectId(*params, &objectId);
85      GetHeapObjectIdReturns result(std::move(objectId));
86      SendResponse(request, response, result);
87  }
88  
GetObjectByHeapObjectId(const DispatchRequest & request)89  void HeapProfilerImpl::DispatcherImpl::GetObjectByHeapObjectId(const DispatchRequest &request)
90  {
91      std::unique_ptr<GetObjectByHeapObjectIdParams> params = GetObjectByHeapObjectIdParams::Create(request.GetParams());
92      if (params == nullptr) {
93          SendResponse(request, DispatchResponse::Fail("wrong params"));
94          return;
95      }
96  
97      std::unique_ptr<RemoteObject> remoteObjectResult;
98      DispatchResponse response = heapprofiler_->GetObjectByHeapObjectId(*params, &remoteObjectResult);
99      GetObjectByHeapObjectIdReturns result(std::move(remoteObjectResult));
100      SendResponse(request, response, result);
101  }
102  
GetSamplingProfile(const DispatchRequest & request)103  void HeapProfilerImpl::DispatcherImpl::GetSamplingProfile(const DispatchRequest &request)
104  {
105      std::unique_ptr<SamplingHeapProfile> profile;
106      DispatchResponse response = heapprofiler_->GetSamplingProfile(&profile);
107      // The return value type of GetSamplingProfile is the same as of StopSampling.
108      StopSamplingReturns result(std::move(profile));
109      SendResponse(request, response, result);
110  }
111  
StartSampling(const DispatchRequest & request)112  void HeapProfilerImpl::DispatcherImpl::StartSampling(const DispatchRequest &request)
113  {
114      std::unique_ptr<StartSamplingParams> params = StartSamplingParams::Create(request.GetParams());
115      if (params == nullptr) {
116          SendResponse(request, DispatchResponse::Fail("wrong params"));
117          return;
118      }
119      DispatchResponse response = heapprofiler_->StartSampling(*params);
120      SendResponse(request, response);
121  }
122  
StartTrackingHeapObjects(const DispatchRequest & request)123  void HeapProfilerImpl::DispatcherImpl::StartTrackingHeapObjects(const DispatchRequest &request)
124  {
125      std::unique_ptr<StartTrackingHeapObjectsParams> params =
126          StartTrackingHeapObjectsParams::Create(request.GetParams());
127      if (params == nullptr) {
128          SendResponse(request, DispatchResponse::Fail("wrong params"));
129          return;
130      }
131      DispatchResponse response = heapprofiler_->StartTrackingHeapObjects(*params);
132      SendResponse(request, response);
133  }
134  
135  
StopSampling(const DispatchRequest & request)136  void HeapProfilerImpl::DispatcherImpl::StopSampling(const DispatchRequest &request)
137  {
138      std::unique_ptr<SamplingHeapProfile> profile;
139      DispatchResponse response = heapprofiler_->StopSampling(&profile);
140      StopSamplingReturns result(std::move(profile));
141      SendResponse(request, response, result);
142  }
143  
StopTrackingHeapObjects(const DispatchRequest & request)144  void HeapProfilerImpl::DispatcherImpl::StopTrackingHeapObjects(const DispatchRequest &request)
145  {
146      std::unique_ptr<StopTrackingHeapObjectsParams> params = StopTrackingHeapObjectsParams::Create(request.GetParams());
147      if (params == nullptr) {
148          SendResponse(request, DispatchResponse::Fail("wrong params"));
149          return;
150      }
151      DispatchResponse response = heapprofiler_->StopTrackingHeapObjects(*params);
152      SendResponse(request, response);
153  }
154  
TakeHeapSnapshot(const DispatchRequest & request)155  void HeapProfilerImpl::DispatcherImpl::TakeHeapSnapshot(const DispatchRequest &request)
156  {
157      std::unique_ptr<StopTrackingHeapObjectsParams> params = StopTrackingHeapObjectsParams::Create(request.GetParams());
158      if (params == nullptr) {
159          SendResponse(request, DispatchResponse::Fail("wrong params"));
160          return;
161      }
162      DispatchResponse response = heapprofiler_->TakeHeapSnapshot(*params);
163      SendResponse(request, response);
164  }
165  
AllowNotify() const166  bool HeapProfilerImpl::Frontend::AllowNotify() const
167  {
168      return channel_ != nullptr;
169  }
170  
AddHeapSnapshotChunk(char * data,int32_t size)171  void HeapProfilerImpl::Frontend::AddHeapSnapshotChunk(char *data, int32_t size)
172  {
173      if (!AllowNotify()) {
174          return;
175      }
176  
177      tooling::AddHeapSnapshotChunk addHeapSnapshotChunk;
178      addHeapSnapshotChunk.GetChunk().resize(size);
179      for (int32_t i = 0; i < size; ++i) {
180          addHeapSnapshotChunk.GetChunk()[i] = data[i];
181      }
182  
183      channel_->SendNotification(addHeapSnapshotChunk);
184  }
185  
ReportHeapSnapshotProgress(int32_t done,int32_t total)186  void HeapProfilerImpl::Frontend::ReportHeapSnapshotProgress(int32_t done, int32_t total)
187  {
188      if (!AllowNotify()) {
189          return;
190      }
191  
192      tooling::ReportHeapSnapshotProgress reportHeapSnapshotProgress;
193      reportHeapSnapshotProgress.SetDone(done).SetTotal(total);
194      if (done >= total) {
195          reportHeapSnapshotProgress.SetFinished(true);
196      }
197      channel_->SendNotification(reportHeapSnapshotProgress);
198  }
199  
HeapStatsUpdate(HeapStat * updateData,int32_t count)200  void HeapProfilerImpl::Frontend::HeapStatsUpdate(HeapStat* updateData, int32_t count)
201  {
202      if (!AllowNotify()) {
203          return;
204      }
205      std::vector<int32_t> statsDiff;
206      for (int32_t i = 0; i < count; ++i) {
207          statsDiff.emplace_back(updateData[i].index_);
208          statsDiff.emplace_back(updateData[i].count_);
209          statsDiff.emplace_back(updateData[i].size_);
210      }
211      tooling::HeapStatsUpdate heapStatsUpdate;
212      heapStatsUpdate.SetStatsUpdate(std::move(statsDiff));
213      channel_->SendNotification(heapStatsUpdate);
214  }
215  
LastSeenObjectId(int32_t lastSeenObjectId)216  void HeapProfilerImpl::Frontend::LastSeenObjectId(int32_t lastSeenObjectId)
217  {
218      if (!AllowNotify()) {
219          return;
220      }
221  
222      tooling::LastSeenObjectId lastSeenObjectIdEvent;
223      lastSeenObjectIdEvent.SetLastSeenObjectId(lastSeenObjectId);
224      int64_t timestamp = 0;
225      struct timeval tv = {0, 0};
226      gettimeofday(&tv, nullptr);
227      const int THOUSAND = 1000;
228      timestamp = static_cast<int64_t>(tv.tv_usec + tv.tv_sec * THOUSAND * THOUSAND);
229      lastSeenObjectIdEvent.SetTimestamp(timestamp);
230      channel_->SendNotification(lastSeenObjectIdEvent);
231  }
232  
ResetProfiles()233  void HeapProfilerImpl::Frontend::ResetProfiles()
234  {
235      if (!AllowNotify()) {
236          return;
237      }
238  }
239  
AddInspectedHeapObject(const AddInspectedHeapObjectParams & params)240  DispatchResponse HeapProfilerImpl::AddInspectedHeapObject([[maybe_unused]] const AddInspectedHeapObjectParams &params)
241  {
242      LOG(ERROR, DEBUGGER) << "AddInspectedHeapObject not support now.";
243      return DispatchResponse::Ok();
244  }
245  
CollectGarbage()246  DispatchResponse HeapProfilerImpl::CollectGarbage()
247  {
248      LOG(ERROR, DEBUGGER) << "CollectGarbage not support now.";
249      return DispatchResponse::Ok();
250  }
251  
Enable()252  DispatchResponse HeapProfilerImpl::Enable()
253  {
254      LOG(ERROR, DEBUGGER) << "Enable not support now.";
255      return DispatchResponse::Ok();
256  }
257  
Disable()258  DispatchResponse HeapProfilerImpl::Disable()
259  {
260      LOG(ERROR, DEBUGGER) << "Disable not support now.";
261      return DispatchResponse::Ok();
262  }
263  
GetHeapObjectId(const GetHeapObjectIdParams & params,HeapSnapshotObjectId * objectId)264  DispatchResponse HeapProfilerImpl::GetHeapObjectId([[maybe_unused]] const GetHeapObjectIdParams &params,
265      HeapSnapshotObjectId *objectId)
266  {
267      ASSERT(objectId != nullptr);
268      *objectId = 0;
269      LOG(ERROR, DEBUGGER) << "GetHeapObjectId not support now.";
270      return DispatchResponse::Ok();
271  }
272  
GetObjectByHeapObjectId(const GetObjectByHeapObjectIdParams & params,std::unique_ptr<RemoteObject> * remoteObjectResult)273  DispatchResponse HeapProfilerImpl::GetObjectByHeapObjectId([[maybe_unused]] const GetObjectByHeapObjectIdParams &params,
274      [[maybe_unused]] std::unique_ptr<RemoteObject> *remoteObjectResult)
275  {
276      LOG(ERROR, DEBUGGER) << "GetObjectByHeapObjectId not support now.";
277      return DispatchResponse::Ok();
278  }
279  
GetSamplingProfile(std::unique_ptr<SamplingHeapProfile> * profile)280  DispatchResponse HeapProfilerImpl::GetSamplingProfile([[maybe_unused]]std::unique_ptr<SamplingHeapProfile> *profile)
281  {
282      LOG(ERROR, DEBUGGER) << "GetSamplingProfile not support now.";
283      return DispatchResponse::Ok();
284  }
285  
StartSampling(const StartSamplingParams & params)286  DispatchResponse HeapProfilerImpl::StartSampling([[maybe_unused]]const StartSamplingParams &params)
287  {
288      LOG(ERROR, DEBUGGER) << "StartSampling not support now.";
289      return DispatchResponse::Ok();
290  }
291  
StartTrackingHeapObjects(const StartTrackingHeapObjectsParams & params)292  DispatchResponse HeapProfilerImpl::StartTrackingHeapObjects(
293      [[maybe_unused]] const StartTrackingHeapObjectsParams &params)
294  {
295      bool result = panda::DFXJSNApi::StartHeapTracking(vm_, INTERVAL, true, &stream_);
296      if (result) {
297          return DispatchResponse::Ok();
298      } else {
299          return DispatchResponse::Fail("StartHeapTracking fail");
300      }
301  }
302  
StopSampling(std::unique_ptr<SamplingHeapProfile> * profile)303  DispatchResponse HeapProfilerImpl::StopSampling([[maybe_unused]]std::unique_ptr<SamplingHeapProfile> *profile)
304  {
305      LOG(ERROR, DEBUGGER) << "StopSampling not support now.";
306      return DispatchResponse::Ok();
307  }
308  
StopTrackingHeapObjects(const StopTrackingHeapObjectsParams & params)309  DispatchResponse HeapProfilerImpl::StopTrackingHeapObjects(const StopTrackingHeapObjectsParams &params)
310  {
311      bool result = false;
312      if (params.GetReportProgress()) {
313          HeapProfilerProgress progress(&frontend_);
314          result = panda::DFXJSNApi::StopHeapTracking(vm_, &stream_, &progress);
315      } else {
316          result = panda::DFXJSNApi::StopHeapTracking(vm_, &stream_, nullptr);
317      }
318      if (result) {
319          return DispatchResponse::Ok();
320      } else {
321          return DispatchResponse::Fail("StopHeapTracking fail");
322      }
323  }
324  
TakeHeapSnapshot(const StopTrackingHeapObjectsParams & params)325  DispatchResponse HeapProfilerImpl::TakeHeapSnapshot(const StopTrackingHeapObjectsParams &params)
326  {
327      if (params.GetReportProgress()) {
328          HeapProfilerProgress progress(&frontend_);
329          panda::DFXJSNApi::DumpHeapSnapshot(vm_, 0, &stream_, &progress, true);
330      } else {
331          panda::DFXJSNApi::DumpHeapSnapshot(vm_, 0, &stream_, nullptr, true);
332      }
333      return DispatchResponse::Ok();
334  }
335  }  // namespace panda::ecmascript::tooling
336