mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
!3460 BugFix on Cpuprofiler long time recording deadlock
Merge pull request !3460 from chenjingxiang/deadlock
This commit is contained in:
commit
1dfc6ef552
@ -295,6 +295,7 @@ void CpuProfiler::GetFrameStack(FrameIterator &it)
|
||||
{
|
||||
const CMap<struct MethodKey, struct FrameInfo> &stackInfo = generator_->GetStackInfo();
|
||||
bool topFrame = true;
|
||||
generator_->ResetFrameLength();
|
||||
for (; !it.Done(); it.Advance<>()) {
|
||||
auto method = it.CheckAndGetMethod();
|
||||
if (method == nullptr) {
|
||||
@ -328,10 +329,12 @@ void CpuProfiler::GetFrameStack(FrameIterator &it)
|
||||
return;
|
||||
}
|
||||
}
|
||||
generator_->PostFrame();
|
||||
}
|
||||
|
||||
bool CpuProfiler::GetFrameStackCallNapi(JSThread *thread)
|
||||
{
|
||||
[[maybe_unused]] CallNapiScope scope(generator_);
|
||||
const CMap<struct MethodKey, struct FrameInfo> &stackInfo = generator_->GetStackInfo();
|
||||
generator_->ClearNapiStack();
|
||||
bool topFrame = true;
|
||||
@ -371,6 +374,7 @@ bool CpuProfiler::GetFrameStackCallNapi(JSThread *thread)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
generator_->PostNapiFrame();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -483,17 +487,7 @@ void CpuProfiler::GetNativeStack(const FrameIterator &it, char *functionName, si
|
||||
|
||||
void CpuProfiler::GetStackBeforeCallNapi(JSThread *thread, const std::string &methodAddr)
|
||||
{
|
||||
generator_->SetBeforeGetCallNapiStackFlag(true);
|
||||
if (GetFrameStackCallNapi(thread)) {
|
||||
generator_->SetCallNapiFlag(true);
|
||||
generator_->SetAfterGetCallNapiStackFlag(true);
|
||||
if (generator_->SemWait(2) != 0) { // 2: signal 2
|
||||
LOG_ECMA(ERROR) << "sem_[2] wait failed";
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
generator_->SetBeforeGetCallNapiStackFlag(false);
|
||||
}
|
||||
GetFrameStackCallNapi(thread);
|
||||
RecordCallNapiInfo(methodAddr);
|
||||
}
|
||||
|
||||
|
@ -64,10 +64,26 @@ public:
|
||||
thread_->SetRuntimeState(oldState_);
|
||||
}
|
||||
private:
|
||||
bool oldState_;
|
||||
bool oldState_ = false;
|
||||
JSThread *thread_ = nullptr;
|
||||
};
|
||||
|
||||
class CallNapiScope {
|
||||
public:
|
||||
inline explicit CallNapiScope(SamplesRecord *generator)
|
||||
{
|
||||
generator_ = generator;
|
||||
generator_->SetFrameStackCallNapi(true);
|
||||
}
|
||||
|
||||
inline ~CallNapiScope()
|
||||
{
|
||||
generator_->SetFrameStackCallNapi(false);
|
||||
}
|
||||
private:
|
||||
SamplesRecord *generator_ = nullptr;
|
||||
};
|
||||
|
||||
class CpuProfiler {
|
||||
public:
|
||||
bool InHeaderOrTail(uint64_t pc, uint64_t entryBegin, uint64_t entryDuration, uint64_t headerSize,
|
||||
|
@ -45,6 +45,7 @@ SamplesRecord::SamplesRecord()
|
||||
if (tid != -1) {
|
||||
profileInfo_->tid = static_cast<uint64_t>(tid);
|
||||
}
|
||||
samplesQueue_ = new SamplesQueue();
|
||||
}
|
||||
|
||||
SamplesRecord::~SamplesRecord()
|
||||
@ -52,24 +53,23 @@ SamplesRecord::~SamplesRecord()
|
||||
if (fileHandle_.is_open()) {
|
||||
fileHandle_.close();
|
||||
}
|
||||
if (samplesQueue_ != nullptr) {
|
||||
delete samplesQueue_;
|
||||
}
|
||||
}
|
||||
|
||||
void SamplesRecord::AddSample(uint64_t sampleTimeStamp)
|
||||
void SamplesRecord::AddSample(FrameStackAndInfo *frame)
|
||||
{
|
||||
if (isBreakSample_.load()) {
|
||||
frameStackLength_ = 0;
|
||||
frameInfoTempLength_ = 0;
|
||||
return;
|
||||
}
|
||||
FrameInfoTempToMap();
|
||||
FrameInfoTempToMap(frame->frameInfoTemps, frame->frameInfoTempsLength);
|
||||
struct NodeKey nodeKey;
|
||||
struct CpuProfileNode methodNode;
|
||||
if (frameStackLength_ != 0) {
|
||||
frameStackLength_--;
|
||||
int frameStackLength = frame->frameStackLength;
|
||||
if (frameStackLength != 0) {
|
||||
frameStackLength--;
|
||||
}
|
||||
methodNode.id = 1;
|
||||
for (; frameStackLength_ >= 1; frameStackLength_--) {
|
||||
nodeKey.methodKey = frameStack_[frameStackLength_ - 1];
|
||||
for (; frameStackLength >= 1; frameStackLength--) {
|
||||
nodeKey.methodKey = frame->frameStack[frameStackLength - 1];
|
||||
methodNode.parentId = nodeKey.parentId = methodNode.id;
|
||||
auto result = nodeMap_.find(nodeKey);
|
||||
if (result == nodeMap_.end()) {
|
||||
@ -86,14 +86,14 @@ void SamplesRecord::AddSample(uint64_t sampleTimeStamp)
|
||||
}
|
||||
|
||||
int sampleNodeId = previousId_ == 0 ? 1 : methodNode.id;
|
||||
int timeDelta = static_cast<int>(sampleTimeStamp -
|
||||
int timeDelta = static_cast<int>(frame->timeStamp -
|
||||
(threadStartTime_ == 0 ? profileInfo_->startTime : threadStartTime_));
|
||||
StatisticStateTime(timeDelta, previousState_);
|
||||
previousState_ = nodeKey.methodKey.state;
|
||||
profileInfo_->nodes[sampleNodeId - 1].hitCount++;
|
||||
profileInfo_->samples.push_back(sampleNodeId);
|
||||
profileInfo_->timeDeltas.push_back(timeDelta);
|
||||
threadStartTime_ = sampleTimeStamp;
|
||||
threadStartTime_ = frame->timeStamp;
|
||||
}
|
||||
|
||||
void SamplesRecord::AddSampleCallNapi(uint64_t *sampleTimeStamp)
|
||||
@ -653,14 +653,14 @@ bool SamplesRecord::PushNapiStackInfo(const FrameInfoTemp &frameInfoTemp)
|
||||
return true;
|
||||
}
|
||||
|
||||
void SamplesRecord::FrameInfoTempToMap()
|
||||
void SamplesRecord::FrameInfoTempToMap(FrameInfoTemp *frameInfoTemps, int frameInfoTempLength)
|
||||
{
|
||||
if (frameInfoTempLength_ == 0) {
|
||||
if (frameInfoTempLength == 0) {
|
||||
return;
|
||||
}
|
||||
struct FrameInfo frameInfo;
|
||||
for (int i = 0; i < frameInfoTempLength_; ++i) {
|
||||
frameInfo.url = frameInfoTemps_[i].url;
|
||||
for (int i = 0; i < frameInfoTempLength; ++i) {
|
||||
frameInfo.url = frameInfoTemps[i].url;
|
||||
auto iter = scriptIdMap_.find(frameInfo.url);
|
||||
if (iter == scriptIdMap_.end()) {
|
||||
scriptIdMap_.emplace(frameInfo.url, scriptIdMap_.size() + 1);
|
||||
@ -668,13 +668,13 @@ void SamplesRecord::FrameInfoTempToMap()
|
||||
} else {
|
||||
frameInfo.scriptId = iter->second;
|
||||
}
|
||||
frameInfo.functionName = AddRunningState(frameInfoTemps_[i].functionName,
|
||||
frameInfoTemps_[i].methodKey.state,
|
||||
frameInfoTemps_[i].methodKey.deoptType);
|
||||
frameInfo.codeType = frameInfoTemps_[i].codeType;
|
||||
frameInfo.columnNumber = frameInfoTemps_[i].columnNumber;
|
||||
frameInfo.lineNumber = frameInfoTemps_[i].lineNumber;
|
||||
stackInfoMap_.emplace(frameInfoTemps_[i].methodKey, frameInfo);
|
||||
frameInfo.functionName = AddRunningState(frameInfoTemps[i].functionName,
|
||||
frameInfoTemps[i].methodKey.state,
|
||||
frameInfoTemps[i].methodKey.deoptType);
|
||||
frameInfo.codeType = frameInfoTemps[i].codeType;
|
||||
frameInfo.columnNumber = frameInfoTemps[i].columnNumber;
|
||||
frameInfo.lineNumber = frameInfoTemps[i].lineNumber;
|
||||
stackInfoMap_.emplace(frameInfoTemps[i].methodKey, frameInfo);
|
||||
}
|
||||
frameInfoTempLength_ = 0;
|
||||
}
|
||||
@ -719,4 +719,168 @@ void SamplesRecord::RecordCallNapiAddr(const std::string &methodAddr)
|
||||
{
|
||||
napiCallAddrVec_.emplace_back(methodAddr);
|
||||
}
|
||||
|
||||
void SamplesRecord::PostFrame()
|
||||
{
|
||||
samplesQueue_->PostFrame(frameInfoTemps_, frameStack_, frameInfoTempLength_, frameStackLength_);
|
||||
}
|
||||
|
||||
void SamplesRecord::PostNapiFrame()
|
||||
{
|
||||
samplesQueue_->PostNapiFrame(napiFrameInfoTemps_, napiFrameStack_);
|
||||
}
|
||||
|
||||
void SamplesRecord::ResetFrameLength()
|
||||
{
|
||||
frameStackLength_ = 0;
|
||||
frameInfoTempLength_ = 0;
|
||||
}
|
||||
|
||||
void SamplesRecord::SetFrameStackCallNapi(bool flag)
|
||||
{
|
||||
samplesQueue_->SetFrameStackCallNapi(flag);
|
||||
}
|
||||
|
||||
uint64_t SamplesRecord::GetCallTimeStamp()
|
||||
{
|
||||
return callTimeStamp_;
|
||||
}
|
||||
|
||||
void SamplesRecord::SetCallTimeStamp(uint64_t timeStamp)
|
||||
{
|
||||
callTimeStamp_ = timeStamp;
|
||||
}
|
||||
|
||||
// SamplesQueue
|
||||
void SamplesQueue::PostFrame(FrameInfoTemp *frameInfoTemps, MethodKey *frameStack,
|
||||
int frameInfoTempsLength, int frameStackLength)
|
||||
{
|
||||
if (GetFrameStackCallNapi()) {
|
||||
return;
|
||||
}
|
||||
os::memory::LockHolder holder(mtx_);
|
||||
if (!IsFull()) {
|
||||
// frameInfoTemps
|
||||
for (int i = 0; i < frameInfoTempsLength; i++) {
|
||||
CheckAndCopy(frameInfoTemps[i].functionName,
|
||||
sizeof(frameInfoTemps[i].functionName), frameInfoTemps[i].functionName);
|
||||
frames_[rear_].frameInfoTemps[i].columnNumber = frameInfoTemps[i].columnNumber;
|
||||
frames_[rear_].frameInfoTemps[i].lineNumber = frameInfoTemps[i].lineNumber;
|
||||
frames_[rear_].frameInfoTemps[i].scriptId = frameInfoTemps[i].scriptId;
|
||||
CheckAndCopy(frameInfoTemps[i].url,
|
||||
sizeof(frameInfoTemps[i].url), frameInfoTemps[i].url);
|
||||
frames_[rear_].frameInfoTemps[i].methodKey.methodIdentifier = frameInfoTemps[i].methodKey.methodIdentifier;
|
||||
frames_[rear_].frameInfoTemps[i].methodKey.state = frameInfoTemps[i].methodKey.state;
|
||||
frames_[rear_].frameInfoTemps[i].methodKey.napiCallCount = frameInfoTemps[i].methodKey.napiCallCount;
|
||||
}
|
||||
// frameStack
|
||||
for (int i = 0; i < frameStackLength; i++) {
|
||||
frames_[rear_].frameStack[i].methodIdentifier = frameStack[i].methodIdentifier;
|
||||
frames_[rear_].frameStack[i].state = frameStack[i].state;
|
||||
frames_[rear_].frameStack[i].napiCallCount = frameStack[i].napiCallCount;
|
||||
}
|
||||
// frameStackLength
|
||||
frames_[rear_].frameStackLength = frameStackLength;
|
||||
// frameInfoTempsLength
|
||||
frames_[rear_].frameInfoTempsLength = frameInfoTempsLength;
|
||||
// timeStamp
|
||||
frames_[rear_].timeStamp = SamplingProcessor::GetMicrosecondsTimeStamp();
|
||||
|
||||
rear_ = (rear_ + 1) % QUEUE_CAPACITY;
|
||||
}
|
||||
}
|
||||
|
||||
void SamplesQueue::PostNapiFrame(CVector<FrameInfoTemp> &napiFrameInfoTemps, CVector<MethodKey> &napiFrameStack)
|
||||
{
|
||||
os::memory::LockHolder holder(mtx_);
|
||||
if (!IsFull()) {
|
||||
int frameInfoTempsLength = napiFrameInfoTemps.size();
|
||||
int frameStackLength = napiFrameStack.size();
|
||||
// napiFrameInfoTemps
|
||||
for (int i = 0; i < frameInfoTempsLength; i++) {
|
||||
CheckAndCopy(frames_[rear_].frameInfoTemps[i].functionName,
|
||||
sizeof(frames_[rear_].frameInfoTemps[i].functionName), napiFrameInfoTemps[i].functionName);
|
||||
frames_[rear_].frameInfoTemps[i].columnNumber = napiFrameInfoTemps[i].columnNumber;
|
||||
frames_[rear_].frameInfoTemps[i].lineNumber = napiFrameInfoTemps[i].lineNumber;
|
||||
frames_[rear_].frameInfoTemps[i].scriptId = napiFrameInfoTemps[i].scriptId;
|
||||
CheckAndCopy(frames_[rear_].frameInfoTemps[i].url,
|
||||
sizeof(frames_[rear_].frameInfoTemps[i].url), napiFrameInfoTemps[i].url);
|
||||
frames_[rear_].frameInfoTemps[i].methodKey.methodIdentifier =
|
||||
napiFrameInfoTemps[i].methodKey.methodIdentifier;
|
||||
frames_[rear_].frameInfoTemps[i].methodKey.state = napiFrameInfoTemps[i].methodKey.state;
|
||||
frames_[rear_].frameInfoTemps[i].methodKey.napiCallCount = napiFrameInfoTemps[i].methodKey.napiCallCount;
|
||||
}
|
||||
// napiFrameStack
|
||||
for (int i = 0; i < frameStackLength; i++) {
|
||||
frames_[rear_].frameStack[i].methodIdentifier = napiFrameStack[i].methodIdentifier;
|
||||
frames_[rear_].frameStack[i].state = napiFrameStack[i].state;
|
||||
frames_[rear_].frameStack[i].napiCallCount = napiFrameStack[i].napiCallCount;
|
||||
}
|
||||
// frameStackLength
|
||||
frames_[rear_].frameStackLength = frameStackLength;
|
||||
// frameInfoTempsLength
|
||||
frames_[rear_].frameInfoTempsLength = frameInfoTempsLength;
|
||||
// timeStamp
|
||||
frames_[rear_].timeStamp = SamplingProcessor::GetMicrosecondsTimeStamp();
|
||||
|
||||
rear_ = (rear_ + 1) % QUEUE_CAPACITY;
|
||||
}
|
||||
}
|
||||
|
||||
FrameStackAndInfo *SamplesQueue::PopFrame()
|
||||
{
|
||||
os::memory::LockHolder holder(mtx_);
|
||||
if (!IsEmpty()) {
|
||||
FrameStackAndInfo *frame = &frames_[front_];
|
||||
front_ = (front_ + 1) % QUEUE_CAPACITY;
|
||||
return frame;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool SamplesQueue::IsEmpty()
|
||||
{
|
||||
return front_ == rear_;
|
||||
}
|
||||
|
||||
bool SamplesQueue::IsFull()
|
||||
{
|
||||
return (rear_ + 1) % QUEUE_CAPACITY == front_;
|
||||
}
|
||||
|
||||
int SamplesQueue::GetSize()
|
||||
{
|
||||
return (rear_ + QUEUE_CAPACITY - front_) % QUEUE_CAPACITY;
|
||||
}
|
||||
|
||||
int SamplesQueue::GetFront()
|
||||
{
|
||||
return front_;
|
||||
}
|
||||
|
||||
int SamplesQueue::GetRear()
|
||||
{
|
||||
return rear_;
|
||||
}
|
||||
|
||||
void SamplesQueue::SetFrameStackCallNapi(bool flag)
|
||||
{
|
||||
isFrameStackCallNapi.store(flag);
|
||||
}
|
||||
|
||||
bool SamplesQueue::GetFrameStackCallNapi()
|
||||
{
|
||||
return isFrameStackCallNapi.load();
|
||||
}
|
||||
|
||||
bool SamplesQueue::CheckAndCopy(char *dest, size_t length, const char *src) const
|
||||
{
|
||||
int srcLength = strlen(src);
|
||||
if (length <= static_cast<size_t>(srcLength) || strcpy_s(dest, srcLength + 1, src) != EOK) {
|
||||
LOG_ECMA(ERROR) << "SamplesQueue PostFrame strcpy_s failed, maybe srcLength more than destLength";
|
||||
return false;
|
||||
}
|
||||
dest[srcLength] = '\0';
|
||||
return true;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include "ecmascript/compiler/gate_meta_data.h"
|
||||
@ -27,11 +27,13 @@
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/jspandafile/method_literal.h"
|
||||
#include "ecmascript/mem/c_containers.h"
|
||||
#include "libpandabase/os/mutex.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
const int MAX_ARRAY_COUNT = 100; // 100:the maximum size of the array
|
||||
const int MAX_NODE_COUNT = 10000; // 10000:the maximum size of the array
|
||||
const int MIN_TIME_DELTA = 10; // 10: the minimum value of the time delta
|
||||
const int QUEUE_CAPACITY = 11; // the capacity of the circular queue is QUEUE_CAPACITY - 1
|
||||
const size_t NAPI_CALL_SETP = 2; // 2: step size of the variable napiCallIdx in while loop
|
||||
const size_t PRE_IDX_RANGE = 5; // 5: length of variable preIdx looping backward
|
||||
enum class RunningState : size_t {
|
||||
@ -119,12 +121,49 @@ struct FrameInfoTemp {
|
||||
struct MethodKey methodKey = {};
|
||||
};
|
||||
|
||||
struct FrameStackAndInfo {
|
||||
struct FrameInfoTemp frameInfoTemps[MAX_ARRAY_COUNT] = {};
|
||||
struct MethodKey frameStack[MAX_ARRAY_COUNT] = {};
|
||||
int frameInfoTempsLength;
|
||||
int frameStackLength;
|
||||
uint64_t timeStamp;
|
||||
};
|
||||
|
||||
class SamplesQueue {
|
||||
public:
|
||||
SamplesQueue() = default;
|
||||
~SamplesQueue() = default;
|
||||
|
||||
NO_COPY_SEMANTIC(SamplesQueue);
|
||||
NO_MOVE_SEMANTIC(SamplesQueue);
|
||||
|
||||
void PostFrame(FrameInfoTemp *frameInfoTemps, MethodKey *frameStack,
|
||||
int frameInfoTempsLength, int frameStackLength);
|
||||
void PostNapiFrame(CVector<FrameInfoTemp> &napiFrameInfoTemps, CVector<MethodKey> &napiFrameStack);
|
||||
FrameStackAndInfo *PopFrame();
|
||||
bool IsEmpty();
|
||||
bool IsFull();
|
||||
int GetSize();
|
||||
int GetFront();
|
||||
int GetRear();
|
||||
void SetFrameStackCallNapi(bool flag);
|
||||
bool GetFrameStackCallNapi();
|
||||
bool CheckAndCopy(char *dest, size_t length, const char *src) const;
|
||||
|
||||
private:
|
||||
FrameStackAndInfo frames_[QUEUE_CAPACITY] = {};
|
||||
int front_ = 0;
|
||||
int rear_ = 0;
|
||||
std::atomic_bool isFrameStackCallNapi = false;
|
||||
os::memory::Mutex mtx_;
|
||||
};
|
||||
|
||||
class SamplesRecord {
|
||||
public:
|
||||
SamplesRecord();
|
||||
virtual ~SamplesRecord();
|
||||
|
||||
void AddSample(uint64_t sampleTimeStamp);
|
||||
void AddSample(FrameStackAndInfo *frame);
|
||||
void AddSampleCallNapi(uint64_t *sampleTimeStamp);
|
||||
void StringifySampleData();
|
||||
int GetMethodNodeCount() const;
|
||||
@ -169,7 +208,14 @@ public:
|
||||
void FindSampleAndFinetune(size_t findIdx, size_t napiCallIdx, size_t &sampleIdx,
|
||||
uint64_t startSampleTime, uint64_t &sampleTime);
|
||||
void FinetuneTimeDeltas(size_t idx, uint64_t napiTime, uint64_t &sampleTime, bool isEndSample);
|
||||
void PostFrame();
|
||||
void PostNapiFrame();
|
||||
void ResetFrameLength();
|
||||
void SetFrameStackCallNapi(bool flag);
|
||||
uint64_t GetCallTimeStamp();
|
||||
void SetCallTimeStamp(uint64_t timeStamp);
|
||||
std::ofstream fileHandle_;
|
||||
SamplesQueue *samplesQueue_ {nullptr};
|
||||
|
||||
void SetEnableVMTag(bool flag)
|
||||
{
|
||||
@ -182,7 +228,7 @@ private:
|
||||
void StringifySamples();
|
||||
struct FrameInfo GetMethodInfo(struct MethodKey &methodKey);
|
||||
std::string AddRunningState(char *functionName, RunningState state, kungfu::DeoptType type);
|
||||
void FrameInfoTempToMap();
|
||||
void FrameInfoTempToMap(FrameInfoTemp *frameInfoTemps, int frameInfoTempLength);
|
||||
void NapiFrameInfoTempToMap();
|
||||
void StatisticStateTime(int timeDelta, RunningState state);
|
||||
|
||||
@ -214,6 +260,7 @@ private:
|
||||
CVector<uint64_t> napiCallTimeVec_;
|
||||
CVector<std::string> napiCallAddrVec_;
|
||||
bool enableVMTag_ {false};
|
||||
uint64_t callTimeStamp_ = 0;
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_SAMPLES_RECORD_H
|
@ -45,43 +45,27 @@ bool SamplingProcessor::Run([[maybe_unused]] uint32_t threadIndex)
|
||||
uint64_t endTime = startTime;
|
||||
generator_->SetThreadStartTime(startTime);
|
||||
while (generator_->GetIsStart()) {
|
||||
if (generator_->GetBeforeGetCallNapiStackFlag()) {
|
||||
generator_->SetBeforeGetCallNapiStackFlag(false);
|
||||
while (!generator_->GetAfterGetCallNapiStackFlag()) {
|
||||
usleep(10); // 10: sleep 10 us;
|
||||
}
|
||||
generator_->SetAfterGetCallNapiStackFlag(false);
|
||||
if (pthread_kill(pid_, SIGPROF) != 0) {
|
||||
LOG(ERROR, RUNTIME) << "pthread_kill signal failed";
|
||||
return false;
|
||||
}
|
||||
if (!generator_->GetCallNapiFlag()) {
|
||||
if (pthread_kill(pid_, SIGPROF) != 0) {
|
||||
LOG(ERROR, RUNTIME) << "pthread_kill signal failed";
|
||||
return false;
|
||||
}
|
||||
if (generator_->SemWait(0) != 0) {
|
||||
LOG_ECMA(ERROR) << "sem_[0] wait failed";
|
||||
return false;
|
||||
}
|
||||
startTime = GetMicrosecondsTimeStamp();
|
||||
int64_t ts = static_cast<int64_t>(interval_) - static_cast<int64_t>(startTime - endTime);
|
||||
endTime = startTime;
|
||||
if (ts > 0 && !generator_->GetBeforeGetCallNapiStackFlag() && !generator_->GetCallNapiFlag()) {
|
||||
usleep(ts);
|
||||
endTime = GetMicrosecondsTimeStamp();
|
||||
}
|
||||
if (generator_->GetMethodNodeCount() + generator_->GetframeStackLength() >= MAX_NODE_COUNT) {
|
||||
break;
|
||||
}
|
||||
generator_->AddSample(endTime);
|
||||
} else {
|
||||
if (generator_->GetMethodNodeCount() + generator_->GetNapiFrameStackLength() >= MAX_NODE_COUNT) {
|
||||
break;
|
||||
}
|
||||
generator_->AddSampleCallNapi(&endTime);
|
||||
generator_->SetCallNapiFlag(false);
|
||||
if (generator_->SemPost(2) != 0) { // 2: signal 2
|
||||
LOG_ECMA(ERROR) << "sem_[2] post failed";
|
||||
return false;
|
||||
}
|
||||
if (generator_->SemWait(0) != 0) {
|
||||
LOG_ECMA(ERROR) << "sem_[0] wait failed";
|
||||
return false;
|
||||
}
|
||||
startTime = GetMicrosecondsTimeStamp();
|
||||
int64_t ts = static_cast<int64_t>(interval_) - static_cast<int64_t>(startTime - endTime);
|
||||
endTime = startTime;
|
||||
if (ts > 0) {
|
||||
usleep(ts);
|
||||
endTime = GetMicrosecondsTimeStamp();
|
||||
}
|
||||
if (generator_->GetMethodNodeCount() + generator_->GetframeStackLength() >= MAX_NODE_COUNT) {
|
||||
break;
|
||||
}
|
||||
while (!generator_->samplesQueue_->IsEmpty()) {
|
||||
FrameStackAndInfo *frame = generator_->samplesQueue_->PopFrame();
|
||||
generator_->AddSample(frame);
|
||||
}
|
||||
generator_->SetIsBreakSampleFlag(false);
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ int FrameIterator::GetCallSiteDelta(uintptr_t returnAddr) const
|
||||
Method *FrameIterator::CheckAndGetMethod() const
|
||||
{
|
||||
auto function = GetFunction();
|
||||
if (function.IsJSFunctionBase() || function.IsJSProxy()) {
|
||||
if (function.CheckIsJSFunctionBase() || function.IsJSProxy()) {
|
||||
return ECMAObject::Cast(function.GetTaggedObject())->GetCallTarget();
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -966,6 +966,11 @@ inline bool JSTaggedValue::IsJSFunctionBase() const
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSFunctionBase();
|
||||
}
|
||||
|
||||
inline bool JSTaggedValue::CheckIsJSFunctionBase() const
|
||||
{
|
||||
return IsHeapObject() && GetTaggedObject() != nullptr && GetTaggedObject()->GetClass()->IsJSFunctionBase();
|
||||
}
|
||||
|
||||
inline bool JSTaggedValue::IsBoundFunction() const
|
||||
{
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsJsBoundFunction();
|
||||
|
@ -545,6 +545,7 @@ public:
|
||||
bool IsClassPrototype() const;
|
||||
bool IsJSFunction() const;
|
||||
bool IsJSFunctionBase() const;
|
||||
bool CheckIsJSFunctionBase() const;
|
||||
bool IsECMAObject() const;
|
||||
bool IsJSPrimitiveRef() const;
|
||||
bool IsJSPrimitive() const;
|
||||
|
@ -272,12 +272,10 @@ void DFXJSNApi::SetCpuSamplingInterval(const EcmaVM *vm, int interval)
|
||||
CpuProfiler *profiler = vm->GetProfiler();
|
||||
if (profiler == nullptr) {
|
||||
profiler = new CpuProfiler(vm, interval);
|
||||
profiler->SetCallNapiGetStack(false);
|
||||
const_cast<EcmaVM *>(vm)->SetProfiler(profiler);
|
||||
return;
|
||||
}
|
||||
profiler->SetCpuSamplingInterval(interval);
|
||||
profiler->SetCallNapiGetStack(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user