heap_snapshot.cc 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // Copyright (c) 2018 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/common/heap_snapshot.h"
  5. #include "base/containers/span.h"
  6. #include "base/files/file.h"
  7. #include "base/memory/raw_ptr.h"
  8. #include "v8/include/v8-profiler.h"
  9. #include "v8/include/v8.h"
  10. namespace {
  11. class HeapSnapshotOutputStream : public v8::OutputStream {
  12. public:
  13. explicit HeapSnapshotOutputStream(base::File* file) : file_(file) {
  14. DCHECK(file_);
  15. }
  16. bool IsComplete() const { return is_complete_; }
  17. // v8::OutputStream
  18. int GetChunkSize() override { return 65536; }
  19. void EndOfStream() override { is_complete_ = true; }
  20. v8::OutputStream::WriteResult WriteAsciiChunk(char* data, int size) override {
  21. const uint8_t* udata = reinterpret_cast<const uint8_t*>(data);
  22. const size_t usize = static_cast<size_t>(std::max(0, size));
  23. // SAFETY: since WriteAsciiChunk() only gives us data + size, our
  24. // UNSAFE_BUFFERS macro call is unavoidable here. It can be removed
  25. // if/when v8 changes WriteAsciiChunk() to pass a v8::MemorySpan.
  26. const auto data_span = UNSAFE_BUFFERS(base::span(udata, usize));
  27. return file_->WriteAtCurrentPosAndCheck(data_span) ? kContinue : kAbort;
  28. }
  29. private:
  30. raw_ptr<base::File> file_ = nullptr;
  31. bool is_complete_ = false;
  32. };
  33. } // namespace
  34. namespace electron {
  35. bool TakeHeapSnapshot(v8::Isolate* isolate, base::File* file) {
  36. DCHECK(isolate);
  37. DCHECK(file);
  38. if (!file->IsValid())
  39. return false;
  40. auto* snapshot = isolate->GetHeapProfiler()->TakeHeapSnapshot();
  41. if (!snapshot)
  42. return false;
  43. HeapSnapshotOutputStream stream(file);
  44. snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON);
  45. const_cast<v8::HeapSnapshot*>(snapshot)->Delete();
  46. return stream.IsComplete();
  47. }
  48. } // namespace electron