Skip to content

Commit

Permalink
JavascriptProfile
Browse files Browse the repository at this point in the history
  • Loading branch information
nakosung committed Feb 20, 2016
1 parent af04cbb commit 4557053
Show file tree
Hide file tree
Showing 4 changed files with 272 additions and 169 deletions.
169 changes: 0 additions & 169 deletions Plugins/UnrealJS/Source/V8/Private/JavascriptIsolate_Private.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,6 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
ExportMemory(ObjectTemplate);

ExportMisc(ObjectTemplate);

ExportProfiler(ObjectTemplate);
}

~FJavascriptIsolateImplementation()
Expand Down Expand Up @@ -796,173 +794,6 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
ReadOnly);
}

static Local<Object> Visit(Isolate* isolate, const v8::CpuProfileNode* node)
{
static TMap<const v8::CpuProfileNode*, Handle<Object>> Visited;

if (!isolate)
{
Visited.Empty();
return Local<Object>();
}
auto Existing = Visited.Find(node);
if (Existing) return *Existing;

FIsolateHelper I(isolate);

auto Out = Object::New(isolate);

Visited.Add(node, Out);

Out->Set(I.Keyword("ScriptResourceName"), node->GetScriptResourceName());
Out->Set(I.Keyword("FunctionName"), node->GetFunctionName());
Out->Set(I.Keyword("HitCount"), Integer::NewFromUnsigned(isolate,node->GetHitCount()));
Out->Set(I.Keyword("LineNumber"), Integer::New(isolate,node->GetLineNumber()));
Out->Set(I.Keyword("ColumnNumber"), Integer::New(isolate,node->GetColumnNumber()));
Out->Set(I.Keyword("ScriptId"), Integer::New(isolate, node->GetScriptId()));

{
uint32_t Num = node->GetHitLineCount();
TArray<v8::CpuProfileNode::LineTick> Buffer;
Buffer.AddDefaulted(Num);
node->GetLineTicks(Buffer.GetData(), Num);

auto Arr = Array::New(isolate, Num);
for (uint32_t Index = 0; Index < Num; ++Index)
{
const auto& info = Buffer[Index];
auto item = Object::New(isolate);
item->Set(I.Keyword("line"), Integer::New(isolate,info.line));
item->Set(I.Keyword("hit_count"), Integer::New(isolate, info.hit_count));
Arr->Set(Index, item);
}
Out->Set(I.Keyword("LineTicks"), Arr);
}

auto BailOutReason = node->GetBailoutReason();
if (BailOutReason)
{
Out->Set(I.Keyword("BailOutReason"), I.Keyword(BailOutReason));
}

{
const auto& deopt = node->GetDeoptInfos();
uint32_t Num = deopt.size();
if (Num)
{
auto Arr = Array::New(isolate, deopt.size());
for (uint32_t Index = 0; Index < Num; ++Index)
{
const auto& info = deopt[Index];
FString out;
for (const auto& frame : info.stack)
{
out.Append(FString::Printf(TEXT("%d:%d "), (int)frame.script_id, (int)frame.position));
}
auto item = Object::New(isolate);
item->Set(I.Keyword("reason"), I.Keyword(deopt[Index].deopt_reason));
item->Set(I.Keyword("stack"), I.String(out));
Arr->Set(Index, item);
}
Out->Set(I.Keyword("DeoptInfos"), Arr);
}
}

uint32_t Num = node->GetChildrenCount();
if (Num)
{
auto Arr = Array::New(isolate, Num);
for (uint32_t Index = 0; Index < Num; ++Index)
{
Arr->Set(Index, Visit(isolate, node->GetChild(Index)));
}
Out->Set(I.Keyword("Children"), Arr);
}
return Out;
};

void ExportProfiler(Local<ObjectTemplate> global_templ)
{
FIsolateHelper I(isolate_);

Local<FunctionTemplate> Template = I.FunctionTemplate();

auto add_fn = [&](const char* name, FunctionCallback fn) {
Template->PrototypeTemplate()->Set(I.Keyword(name), I.FunctionTemplate(fn));
};

add_fn("SetSamplingInterval", [](const FunctionCallbackInfo<Value>& info)
{
FIsolateHelper I(info.GetIsolate());

auto profiler = info.GetIsolate()->GetCpuProfiler();

if (info.Length() == 1)
{
profiler->SetSamplingInterval(info[0]->IntegerValue());
}
});

add_fn("StartProfiling", [](const FunctionCallbackInfo<Value>& info)
{
FIsolateHelper I(info.GetIsolate());

auto profiler = info.GetIsolate()->GetCpuProfiler();

if (info.Length() == 2)
{
profiler->StartProfiling(info[0].As<String>(), info[1]->BooleanValue());
info.GetReturnValue().Set(true);
}
});

add_fn("StopProfiling", [](const FunctionCallbackInfo<Value>& info)
{
auto isolate = info.GetIsolate();
FIsolateHelper I(isolate);

auto profiler = isolate->GetCpuProfiler();

if (info.Length() == 1)
{
auto Profile = profiler->StopProfiling(info[0].As<String>());
if (!Profile) return;

auto Out = Object::New(isolate);
Out->Set(I.Keyword("Root"), Visit(isolate, Profile->GetTopDownRoot()));
Out->Set(I.Keyword("Title"), Profile->GetTitle());

{
uint32_t Num = Profile->GetSamplesCount();
if (Num)
{
auto Arr = Array::New(isolate, Num);
for (uint32_t Index = 0; Index < Num; ++Index)
{
Arr->Set(Index, Visit(isolate, Profile->GetSample(Index)));
}
Out->Set(I.Keyword("Samples"), Arr);
}
}


// cleanup
Visit(nullptr, nullptr);

info.GetReturnValue().Set(Out);

Profile->Delete();
}
});

global_templ->Set(
I.Keyword("v8"),
// Create an instance
Template->GetFunction()->NewInstance(),
// Do not modify!
ReadOnly);
}

void ExportMisc(Local<ObjectTemplate> global_templ)
{
FIsolateHelper I(isolate_);
Expand Down
178 changes: 178 additions & 0 deletions Plugins/UnrealJS/Source/V8/Private/JavascriptProfile.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#include "V8PCH.h"
#include "JavascriptProfile.h"
#include "Config.h"
#include "Translator.h"
#include "Helpers.h"
#include "JavascriptLibrary.h"

using namespace v8;

void UJavascriptProfile::BeginDestroy()
{
Super::BeginDestroy();

if (Profile)
{
reinterpret_cast<CpuProfile*>(Profile)->Delete();
Profile = nullptr;
}
}

FJavascriptProfileNode UJavascriptProfile::GetTopDownRoot()
{
FJavascriptProfileNode out;

if (Profile)
{
out.Node = reinterpret_cast<CpuProfile*>(Profile)->GetTopDownRoot();
}

return out;
}

int32 UJavascriptProfile::GetSamplesCount()
{
if (Profile)
{
return reinterpret_cast<CpuProfile*>(Profile)->GetSamplesCount();
}

return 0;
}

FJavascriptProfileNode UJavascriptProfile::GetSample(int32 index)
{
FJavascriptProfileNode out;

if (Profile)
{
out.Node = reinterpret_cast<CpuProfile*>(Profile)->GetSample(index);
}

return out;
}

float UJavascriptProfile::GetSampleTimestamp(int32 index)
{
if (Profile)
{
return (float)reinterpret_cast<CpuProfile*>(Profile)->GetSampleTimestamp(index);
}

return -1;
}

void UJavascriptProfile::Start(const FString& Title, bool bRecordSamples)
{
auto isolate = Isolate::GetCurrent();

FIsolateHelper I(isolate);
auto profiler = isolate->GetCpuProfiler();

profiler->StartProfiling(I.String(Title), bRecordSamples);
}

UJavascriptProfile* UJavascriptProfile::Stop(const FString& Title)
{
auto isolate = Isolate::GetCurrent();

FIsolateHelper I(isolate);
auto profiler = isolate->GetCpuProfiler();

auto Profile = profiler->StopProfiling(I.String(Title));

auto instance = NewObject<UJavascriptProfile>();
instance->Profile = Profile;
return instance;
}

void UJavascriptProfile::SetSamplingInterval(int32 us)
{
auto isolate = Isolate::GetCurrent();

FIsolateHelper I(isolate);
auto profiler = isolate->GetCpuProfiler();

profiler->SetSamplingInterval(us);
}

void UJavascriptProfile::SetIdle(bool is_idle)
{
auto isolate = Isolate::GetCurrent();

FIsolateHelper I(isolate);
auto profiler = isolate->GetCpuProfiler();

profiler->SetIdle(is_idle);
}

FString UJavascriptLibrary::GetFunctionName(FJavascriptProfileNode Node)
{
return StringFromV8(reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetFunctionName());
}
int32 UJavascriptLibrary::GetScriptId(FJavascriptProfileNode Node)
{
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetScriptId();
}
FString UJavascriptLibrary::GetScriptResourceName(FJavascriptProfileNode Node)
{
return StringFromV8(reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetScriptResourceName());
}
int32 UJavascriptLibrary::GetLineNumber(FJavascriptProfileNode Node)
{
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetLineNumber();
}
int32 UJavascriptLibrary::GetColumnNumber(FJavascriptProfileNode Node)
{
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetColumnNumber();
}
int32 UJavascriptLibrary::GetHitLineCount(FJavascriptProfileNode Node)
{
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetHitLineCount();
}
FString UJavascriptLibrary::GetBailoutReason(FJavascriptProfileNode Node)
{
return ANSI_TO_TCHAR(reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetBailoutReason());
}
int32 UJavascriptLibrary::GetHitCount(FJavascriptProfileNode Node)
{
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetHitCount();
}
int32 UJavascriptLibrary::GetCallUid(FJavascriptProfileNode Node)
{
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetCallUid();
}
int32 UJavascriptLibrary::GetNodeId(FJavascriptProfileNode Node)
{
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetNodeId();
}
int32 UJavascriptLibrary::GetChildrenCount(FJavascriptProfileNode Node)
{
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetChildrenCount();
}
FJavascriptProfileNode UJavascriptLibrary::GetChild(FJavascriptProfileNode Node, int32 index)
{
FJavascriptProfileNode out;
out.Node = reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetChild(index);
return out;
}
int32 UJavascriptLibrary::GetDeoptInfosCount(FJavascriptProfileNode Node, int32 index)
{
const auto& infos = reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetDeoptInfos();
return infos.size();
}
FString UJavascriptLibrary::GetDeoptInfo_Reason(FJavascriptProfileNode Node, int32 index)
{
const auto& infos = reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetDeoptInfos();
return ANSI_TO_TCHAR(infos[index].deopt_reason);
}
FString UJavascriptLibrary::GetDeoptInfo_Stack(FJavascriptProfileNode Node, int32 index)
{
FString out;
const auto& infos = reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetDeoptInfos();
for (const auto& frame : infos[index].stack)
{
out.Append(FString::Printf(TEXT("%d:%d"), frame.script_id, frame.position));
}
return out;
}
Loading

0 comments on commit 4557053

Please sign in to comment.