mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
add heapProfiler and getBackTrace napi
Signed-off-by: shikai <shikai25@huawei.com>
This commit is contained in:
parent
bb19fcf0ab
commit
7a9e23bcf4
1
BUILD.gn
1
BUILD.gn
@ -370,6 +370,7 @@ ecma_source = [
|
||||
"ecmascript/mem/space.cpp",
|
||||
"ecmascript/mem/verification.cpp",
|
||||
"ecmascript/napi/jsnapi.cpp",
|
||||
"ecmascript/napi/dfx_jsnapi.cpp",
|
||||
"ecmascript/object_factory.cpp",
|
||||
"ecmascript/object_operator.cpp",
|
||||
"ecmascript/platform/platform.cpp",
|
||||
|
@ -230,4 +230,13 @@ CString ErrorHelper::BuildNativeEcmaStackTrace(JSThread *thread)
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::string ErrorHelper::BuildNativeAndJsBackStackTrace(JSThread *thread)
|
||||
{
|
||||
CString data = BuildNativeEcmaStackTrace(thread);
|
||||
std::string temp = CstringConvertToString(data);
|
||||
std::string result = nullptr;
|
||||
result += temp;
|
||||
return result;
|
||||
}
|
||||
} // namespace panda::ecmascript::base
|
||||
|
@ -33,6 +33,7 @@ public:
|
||||
|
||||
static CString BuildNativeEcmaStackTrace(JSThread *thread);
|
||||
|
||||
static std::string BuildNativeAndJsBackStackTrace(JSThread *thread);
|
||||
private:
|
||||
static CString DecodeFunctionName(const CString &name);
|
||||
static JSHandle<EcmaString> BuildEcmaStackTrace(JSThread *thread);
|
||||
|
@ -285,7 +285,7 @@ bool CpuProfiler::CheckFileName(const std::string &fileName, std::string &absolu
|
||||
|
||||
CVector<char> resolvedPath(PATH_MAX);
|
||||
realpath(fileName.c_str(), resolvedPath.data());
|
||||
std::ifstream file(resolvedPath.data());
|
||||
std::ofstream file(resolvedPath.data());
|
||||
if (!file.good()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ HeapProfiler::~HeapProfiler()
|
||||
jsonSerializer_ = nullptr;
|
||||
}
|
||||
|
||||
bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath, bool isVmMode)
|
||||
bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const std::string &filePath, bool isVmMode)
|
||||
{
|
||||
[[maybe_unused]] bool heapClean = ForceFullGC(thread);
|
||||
ASSERT(heapClean);
|
||||
@ -68,7 +68,7 @@ bool HeapProfiler::StartHeapTracking(JSThread *thread, double timeInterval, bool
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HeapProfiler::StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const CString &path)
|
||||
bool HeapProfiler::StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const std::string &path)
|
||||
{
|
||||
if (heapTracker_ == nullptr) {
|
||||
return false;
|
||||
@ -93,7 +93,7 @@ bool HeapProfiler::StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, con
|
||||
return jsonSerializer_->Serialize(snapShot, realPath.second);
|
||||
}
|
||||
|
||||
std::pair<bool, CString> HeapProfiler::FilePathValid(const CString &filePath)
|
||||
std::pair<bool, CString> HeapProfiler::FilePathValid(const std::string &filePath)
|
||||
{
|
||||
if (filePath.size() > PATH_MAX) {
|
||||
return std::make_pair(false, "");
|
||||
@ -106,7 +106,7 @@ std::pair<bool, CString> HeapProfiler::FilePathValid(const CString &filePath)
|
||||
return std::make_pair(false, "");
|
||||
}
|
||||
|
||||
CString HeapProfiler::GenDumpFileName(DumpFormat dumpFormat)
|
||||
std::string HeapProfiler::GenDumpFileName(DumpFormat dumpFormat)
|
||||
{
|
||||
CString filename("hprof_");
|
||||
switch (dumpFormat) {
|
||||
@ -124,7 +124,7 @@ CString HeapProfiler::GenDumpFileName(DumpFormat dumpFormat)
|
||||
break;
|
||||
}
|
||||
filename.append(".heapsnapshot");
|
||||
return filename;
|
||||
return CstringConvertToString(filename);
|
||||
}
|
||||
|
||||
CString HeapProfiler::GetTimeStamp()
|
||||
|
@ -44,11 +44,11 @@ public:
|
||||
/**
|
||||
* dump the specific snapshot in target format
|
||||
*/
|
||||
bool DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &path, bool isVmMode = true);
|
||||
bool DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const std::string &path, bool isVmMode = true);
|
||||
void AddSnapShot(HeapSnapShot *snapshot);
|
||||
|
||||
bool StartHeapTracking(JSThread *thread, double timeInterval, bool isVmMode = true) override;
|
||||
bool StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const CString &filePath) override;
|
||||
bool StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const std::string &filePath) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -60,8 +60,8 @@ private:
|
||||
* make a new heap snapshot and put it into a container eg, vector
|
||||
*/
|
||||
HeapSnapShot *MakeHeapSnapShot(JSThread *thread, SampleType sampleType, bool isVmMode = true);
|
||||
std::pair<bool, CString> FilePathValid(const CString &filePath);
|
||||
CString GenDumpFileName(DumpFormat dumpFormat);
|
||||
std::pair<bool, CString> FilePathValid(const std::string &filePath);
|
||||
std::string GenDumpFileName(DumpFormat dumpFormat);
|
||||
CString GetTimeStamp();
|
||||
void ClearSnapShot();
|
||||
|
||||
|
@ -18,8 +18,17 @@
|
||||
#include "ecmascript/mem/heap.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
HeapProfilerInterface *HeapProfilerInterface::heapProfile_ = nullptr;
|
||||
HeapProfilerInterface *HeapProfilerInterface::GetInstance(JSThread *thread)
|
||||
{
|
||||
if (HeapProfilerInterface::heapProfile_ == nullptr) {
|
||||
heapProfile_ = HeapProfilerInterface::CreateHeapProfiler(thread);
|
||||
}
|
||||
return HeapProfilerInterface::heapProfile_;
|
||||
}
|
||||
|
||||
void HeapProfilerInterface::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat,
|
||||
const CString &filePath, bool isVmMode)
|
||||
const std::string &filePath, bool isVmMode)
|
||||
{
|
||||
LOG(ERROR, RUNTIME) << "HeapProfilerInterface::DumpHeapSnapshot";
|
||||
const Heap *heap = thread->GetEcmaVM()->GetHeap();
|
||||
|
@ -24,8 +24,9 @@ enum class DumpFormat { JSON, BINARY, OTHER };
|
||||
|
||||
class HeapProfilerInterface {
|
||||
public:
|
||||
static HeapProfilerInterface *GetInstance(JSThread *thread);
|
||||
static void DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat,
|
||||
const CString &filePath, bool isVmMode = true);
|
||||
const std::string &filePath, bool isVmMode = true);
|
||||
|
||||
static HeapProfilerInterface *CreateHeapProfiler(JSThread *thread);
|
||||
static void Destroy(JSThread *thread, HeapProfilerInterface *heapProfiler);
|
||||
@ -34,10 +35,12 @@ public:
|
||||
virtual ~HeapProfilerInterface() = default;
|
||||
|
||||
virtual bool StartHeapTracking(JSThread *thread, double timeInterval, bool isVmMode = true) = 0;
|
||||
virtual bool StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const CString &filePath) = 0;
|
||||
virtual bool StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const std::string &filePath) = 0;
|
||||
|
||||
NO_MOVE_SEMANTIC(HeapProfilerInterface);
|
||||
NO_COPY_SEMANTIC(HeapProfilerInterface);
|
||||
private:
|
||||
static HeapProfilerInterface *heapProfile_;
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_HPROF_HEAP_PROFILER_INTERFACE_H
|
||||
|
@ -123,4 +123,14 @@ CString ConvertToString(JSTaggedValue key)
|
||||
|
||||
return ConvertToString(EcmaString::ConstCast(desc.GetTaggedObject()));
|
||||
}
|
||||
|
||||
std::string CstringConvertToString(const CString &str)
|
||||
{
|
||||
std::string res;
|
||||
res.reserve(str.size());
|
||||
for (auto c : str) {
|
||||
res.push_back(c);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -39,6 +39,7 @@ float CStringToF(const CString &str);
|
||||
double CStringToD(const CString &str);
|
||||
|
||||
CString ConvertToString(const std::string &str);
|
||||
std::string CstringConvertToString(const CString &str);
|
||||
|
||||
// '\u0000' is skip according to holdZero
|
||||
CString ConvertToString(const ecmascript::EcmaString *s, StringConvertedUsage usage = StringConvertedUsage::PRINT);
|
||||
|
70
ecmascript/napi/dfx_jsnapi.cpp
Normal file
70
ecmascript/napi/dfx_jsnapi.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecmascript/napi/include/dfx_jsnapi.h"
|
||||
#include "ecmascript/ecma_module.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/hprof/heap_profiler.h"
|
||||
namespace panda {
|
||||
using ecmascript::CString;
|
||||
using ecmascript::EcmaString;
|
||||
using ecmascript::JSTaggedValue;
|
||||
template<typename T>
|
||||
using JSHandle = ecmascript::JSHandle<T>;
|
||||
|
||||
void DFXJSNApi::DumpHeapSnapShot(EcmaVM *vm, int dumpFormat, const std::string &path, bool isVmMode)
|
||||
{
|
||||
if (dumpFormat == 0) {
|
||||
ecmascript::HeapProfilerInterface::DumpHeapSnapShot(vm->GetJSThread(), ecmascript::DumpFormat::JSON,
|
||||
path, isVmMode);
|
||||
} else if (dumpFormat == 1) {
|
||||
ecmascript::HeapProfilerInterface::DumpHeapSnapShot(vm->GetJSThread(), ecmascript::DumpFormat::BINARY,
|
||||
path, isVmMode);
|
||||
} else if (dumpFormat == 2) { // 2: enum is 2
|
||||
ecmascript::HeapProfilerInterface::DumpHeapSnapShot(vm->GetJSThread(), ecmascript::DumpFormat::OTHER,
|
||||
path, isVmMode);
|
||||
}
|
||||
}
|
||||
|
||||
std::string DFXJSNApi::BuildNativeAndJsBackStackTrace(EcmaVM *vm)
|
||||
{
|
||||
std::string result = ecmascript::base::ErrorHelper::BuildNativeAndJsBackStackTrace(vm->GetJSThread());
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DFXJSNApi::StartHeapTracking(EcmaVM *vm, double timeInterval, bool isVmMode)
|
||||
{
|
||||
ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(vm->GetJSThread());
|
||||
return heapProfile->StartHeapTracking(vm->GetJSThread(), timeInterval, isVmMode);
|
||||
}
|
||||
|
||||
bool DFXJSNApi::StopHeapTracking(EcmaVM *vm, int dumpFormat, const std::string &filePath)
|
||||
{
|
||||
bool result = false;
|
||||
ecmascript::HeapProfilerInterface *heapProfile = ecmascript::HeapProfilerInterface::GetInstance(vm->GetJSThread());
|
||||
if (dumpFormat == 0) {
|
||||
result = heapProfile->StopHeapTracking(vm->GetJSThread(), ecmascript::DumpFormat::JSON, filePath);
|
||||
}
|
||||
if (dumpFormat == 1) {
|
||||
result = heapProfile->StopHeapTracking(vm->GetJSThread(), ecmascript::DumpFormat::BINARY, filePath);
|
||||
}
|
||||
if (dumpFormat == 2) { // 2: enum is 2
|
||||
result = heapProfile->StopHeapTracking(vm->GetJSThread(), ecmascript::DumpFormat::OTHER, filePath);
|
||||
}
|
||||
const ecmascript::Heap *heap = vm->GetJSThread()->GetEcmaVM()->GetHeap();
|
||||
const_cast<ecmascript::RegionFactory *>(heap->GetRegionFactory())->Delete(heapProfile);
|
||||
return result;
|
||||
}
|
||||
}
|
42
ecmascript/napi/include/dfx_jsnapi.h
Normal file
42
ecmascript/napi/include/dfx_jsnapi.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_NAPI_INCLUDE_DFX_JSNAPI_H
|
||||
#define ECMASCRIPT_NAPI_INCLUDE_DFX_JSNAPI_H
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ecmascript/common.h"
|
||||
#include "libpandabase/macros.h"
|
||||
|
||||
namespace panda {
|
||||
namespace ecmascript {
|
||||
class EcmaVM;
|
||||
}
|
||||
class DFXJSNApi;
|
||||
using EcmaVM = ecmascript::EcmaVM;
|
||||
|
||||
class PUBLIC_API DFXJSNApi {
|
||||
public:
|
||||
static void DumpHeapSnapShot(EcmaVM *vm, int dumpFormat, const std::string &path, bool isVmMode = true);
|
||||
static std::string BuildNativeAndJsBackStackTrace(EcmaVM *vm);
|
||||
static bool StartHeapTracking(EcmaVM *vm, double timeInterval, bool isVmMode = true);
|
||||
static bool StopHeapTracking(EcmaVM *vm, int dumpFormat, const std::string &filePath);
|
||||
};
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user