Skip to content

Commit 4557053

Browse files
committed
JavascriptProfile
1 parent af04cbb commit 4557053

File tree

4 files changed

+272
-169
lines changed

4 files changed

+272
-169
lines changed

Plugins/UnrealJS/Source/V8/Private/JavascriptIsolate_Private.cpp

Lines changed: 0 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,6 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
338338
ExportMemory(ObjectTemplate);
339339

340340
ExportMisc(ObjectTemplate);
341-
342-
ExportProfiler(ObjectTemplate);
343341
}
344342

345343
~FJavascriptIsolateImplementation()
@@ -796,173 +794,6 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
796794
ReadOnly);
797795
}
798796

799-
static Local<Object> Visit(Isolate* isolate, const v8::CpuProfileNode* node)
800-
{
801-
static TMap<const v8::CpuProfileNode*, Handle<Object>> Visited;
802-
803-
if (!isolate)
804-
{
805-
Visited.Empty();
806-
return Local<Object>();
807-
}
808-
auto Existing = Visited.Find(node);
809-
if (Existing) return *Existing;
810-
811-
FIsolateHelper I(isolate);
812-
813-
auto Out = Object::New(isolate);
814-
815-
Visited.Add(node, Out);
816-
817-
Out->Set(I.Keyword("ScriptResourceName"), node->GetScriptResourceName());
818-
Out->Set(I.Keyword("FunctionName"), node->GetFunctionName());
819-
Out->Set(I.Keyword("HitCount"), Integer::NewFromUnsigned(isolate,node->GetHitCount()));
820-
Out->Set(I.Keyword("LineNumber"), Integer::New(isolate,node->GetLineNumber()));
821-
Out->Set(I.Keyword("ColumnNumber"), Integer::New(isolate,node->GetColumnNumber()));
822-
Out->Set(I.Keyword("ScriptId"), Integer::New(isolate, node->GetScriptId()));
823-
824-
{
825-
uint32_t Num = node->GetHitLineCount();
826-
TArray<v8::CpuProfileNode::LineTick> Buffer;
827-
Buffer.AddDefaulted(Num);
828-
node->GetLineTicks(Buffer.GetData(), Num);
829-
830-
auto Arr = Array::New(isolate, Num);
831-
for (uint32_t Index = 0; Index < Num; ++Index)
832-
{
833-
const auto& info = Buffer[Index];
834-
auto item = Object::New(isolate);
835-
item->Set(I.Keyword("line"), Integer::New(isolate,info.line));
836-
item->Set(I.Keyword("hit_count"), Integer::New(isolate, info.hit_count));
837-
Arr->Set(Index, item);
838-
}
839-
Out->Set(I.Keyword("LineTicks"), Arr);
840-
}
841-
842-
auto BailOutReason = node->GetBailoutReason();
843-
if (BailOutReason)
844-
{
845-
Out->Set(I.Keyword("BailOutReason"), I.Keyword(BailOutReason));
846-
}
847-
848-
{
849-
const auto& deopt = node->GetDeoptInfos();
850-
uint32_t Num = deopt.size();
851-
if (Num)
852-
{
853-
auto Arr = Array::New(isolate, deopt.size());
854-
for (uint32_t Index = 0; Index < Num; ++Index)
855-
{
856-
const auto& info = deopt[Index];
857-
FString out;
858-
for (const auto& frame : info.stack)
859-
{
860-
out.Append(FString::Printf(TEXT("%d:%d "), (int)frame.script_id, (int)frame.position));
861-
}
862-
auto item = Object::New(isolate);
863-
item->Set(I.Keyword("reason"), I.Keyword(deopt[Index].deopt_reason));
864-
item->Set(I.Keyword("stack"), I.String(out));
865-
Arr->Set(Index, item);
866-
}
867-
Out->Set(I.Keyword("DeoptInfos"), Arr);
868-
}
869-
}
870-
871-
uint32_t Num = node->GetChildrenCount();
872-
if (Num)
873-
{
874-
auto Arr = Array::New(isolate, Num);
875-
for (uint32_t Index = 0; Index < Num; ++Index)
876-
{
877-
Arr->Set(Index, Visit(isolate, node->GetChild(Index)));
878-
}
879-
Out->Set(I.Keyword("Children"), Arr);
880-
}
881-
return Out;
882-
};
883-
884-
void ExportProfiler(Local<ObjectTemplate> global_templ)
885-
{
886-
FIsolateHelper I(isolate_);
887-
888-
Local<FunctionTemplate> Template = I.FunctionTemplate();
889-
890-
auto add_fn = [&](const char* name, FunctionCallback fn) {
891-
Template->PrototypeTemplate()->Set(I.Keyword(name), I.FunctionTemplate(fn));
892-
};
893-
894-
add_fn("SetSamplingInterval", [](const FunctionCallbackInfo<Value>& info)
895-
{
896-
FIsolateHelper I(info.GetIsolate());
897-
898-
auto profiler = info.GetIsolate()->GetCpuProfiler();
899-
900-
if (info.Length() == 1)
901-
{
902-
profiler->SetSamplingInterval(info[0]->IntegerValue());
903-
}
904-
});
905-
906-
add_fn("StartProfiling", [](const FunctionCallbackInfo<Value>& info)
907-
{
908-
FIsolateHelper I(info.GetIsolate());
909-
910-
auto profiler = info.GetIsolate()->GetCpuProfiler();
911-
912-
if (info.Length() == 2)
913-
{
914-
profiler->StartProfiling(info[0].As<String>(), info[1]->BooleanValue());
915-
info.GetReturnValue().Set(true);
916-
}
917-
});
918-
919-
add_fn("StopProfiling", [](const FunctionCallbackInfo<Value>& info)
920-
{
921-
auto isolate = info.GetIsolate();
922-
FIsolateHelper I(isolate);
923-
924-
auto profiler = isolate->GetCpuProfiler();
925-
926-
if (info.Length() == 1)
927-
{
928-
auto Profile = profiler->StopProfiling(info[0].As<String>());
929-
if (!Profile) return;
930-
931-
auto Out = Object::New(isolate);
932-
Out->Set(I.Keyword("Root"), Visit(isolate, Profile->GetTopDownRoot()));
933-
Out->Set(I.Keyword("Title"), Profile->GetTitle());
934-
935-
{
936-
uint32_t Num = Profile->GetSamplesCount();
937-
if (Num)
938-
{
939-
auto Arr = Array::New(isolate, Num);
940-
for (uint32_t Index = 0; Index < Num; ++Index)
941-
{
942-
Arr->Set(Index, Visit(isolate, Profile->GetSample(Index)));
943-
}
944-
Out->Set(I.Keyword("Samples"), Arr);
945-
}
946-
}
947-
948-
949-
// cleanup
950-
Visit(nullptr, nullptr);
951-
952-
info.GetReturnValue().Set(Out);
953-
954-
Profile->Delete();
955-
}
956-
});
957-
958-
global_templ->Set(
959-
I.Keyword("v8"),
960-
// Create an instance
961-
Template->GetFunction()->NewInstance(),
962-
// Do not modify!
963-
ReadOnly);
964-
}
965-
966797
void ExportMisc(Local<ObjectTemplate> global_templ)
967798
{
968799
FIsolateHelper I(isolate_);
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#include "V8PCH.h"
2+
#include "JavascriptProfile.h"
3+
#include "Config.h"
4+
#include "Translator.h"
5+
#include "Helpers.h"
6+
#include "JavascriptLibrary.h"
7+
8+
using namespace v8;
9+
10+
void UJavascriptProfile::BeginDestroy()
11+
{
12+
Super::BeginDestroy();
13+
14+
if (Profile)
15+
{
16+
reinterpret_cast<CpuProfile*>(Profile)->Delete();
17+
Profile = nullptr;
18+
}
19+
}
20+
21+
FJavascriptProfileNode UJavascriptProfile::GetTopDownRoot()
22+
{
23+
FJavascriptProfileNode out;
24+
25+
if (Profile)
26+
{
27+
out.Node = reinterpret_cast<CpuProfile*>(Profile)->GetTopDownRoot();
28+
}
29+
30+
return out;
31+
}
32+
33+
int32 UJavascriptProfile::GetSamplesCount()
34+
{
35+
if (Profile)
36+
{
37+
return reinterpret_cast<CpuProfile*>(Profile)->GetSamplesCount();
38+
}
39+
40+
return 0;
41+
}
42+
43+
FJavascriptProfileNode UJavascriptProfile::GetSample(int32 index)
44+
{
45+
FJavascriptProfileNode out;
46+
47+
if (Profile)
48+
{
49+
out.Node = reinterpret_cast<CpuProfile*>(Profile)->GetSample(index);
50+
}
51+
52+
return out;
53+
}
54+
55+
float UJavascriptProfile::GetSampleTimestamp(int32 index)
56+
{
57+
if (Profile)
58+
{
59+
return (float)reinterpret_cast<CpuProfile*>(Profile)->GetSampleTimestamp(index);
60+
}
61+
62+
return -1;
63+
}
64+
65+
void UJavascriptProfile::Start(const FString& Title, bool bRecordSamples)
66+
{
67+
auto isolate = Isolate::GetCurrent();
68+
69+
FIsolateHelper I(isolate);
70+
auto profiler = isolate->GetCpuProfiler();
71+
72+
profiler->StartProfiling(I.String(Title), bRecordSamples);
73+
}
74+
75+
UJavascriptProfile* UJavascriptProfile::Stop(const FString& Title)
76+
{
77+
auto isolate = Isolate::GetCurrent();
78+
79+
FIsolateHelper I(isolate);
80+
auto profiler = isolate->GetCpuProfiler();
81+
82+
auto Profile = profiler->StopProfiling(I.String(Title));
83+
84+
auto instance = NewObject<UJavascriptProfile>();
85+
instance->Profile = Profile;
86+
return instance;
87+
}
88+
89+
void UJavascriptProfile::SetSamplingInterval(int32 us)
90+
{
91+
auto isolate = Isolate::GetCurrent();
92+
93+
FIsolateHelper I(isolate);
94+
auto profiler = isolate->GetCpuProfiler();
95+
96+
profiler->SetSamplingInterval(us);
97+
}
98+
99+
void UJavascriptProfile::SetIdle(bool is_idle)
100+
{
101+
auto isolate = Isolate::GetCurrent();
102+
103+
FIsolateHelper I(isolate);
104+
auto profiler = isolate->GetCpuProfiler();
105+
106+
profiler->SetIdle(is_idle);
107+
}
108+
109+
FString UJavascriptLibrary::GetFunctionName(FJavascriptProfileNode Node)
110+
{
111+
return StringFromV8(reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetFunctionName());
112+
}
113+
int32 UJavascriptLibrary::GetScriptId(FJavascriptProfileNode Node)
114+
{
115+
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetScriptId();
116+
}
117+
FString UJavascriptLibrary::GetScriptResourceName(FJavascriptProfileNode Node)
118+
{
119+
return StringFromV8(reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetScriptResourceName());
120+
}
121+
int32 UJavascriptLibrary::GetLineNumber(FJavascriptProfileNode Node)
122+
{
123+
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetLineNumber();
124+
}
125+
int32 UJavascriptLibrary::GetColumnNumber(FJavascriptProfileNode Node)
126+
{
127+
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetColumnNumber();
128+
}
129+
int32 UJavascriptLibrary::GetHitLineCount(FJavascriptProfileNode Node)
130+
{
131+
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetHitLineCount();
132+
}
133+
FString UJavascriptLibrary::GetBailoutReason(FJavascriptProfileNode Node)
134+
{
135+
return ANSI_TO_TCHAR(reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetBailoutReason());
136+
}
137+
int32 UJavascriptLibrary::GetHitCount(FJavascriptProfileNode Node)
138+
{
139+
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetHitCount();
140+
}
141+
int32 UJavascriptLibrary::GetCallUid(FJavascriptProfileNode Node)
142+
{
143+
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetCallUid();
144+
}
145+
int32 UJavascriptLibrary::GetNodeId(FJavascriptProfileNode Node)
146+
{
147+
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetNodeId();
148+
}
149+
int32 UJavascriptLibrary::GetChildrenCount(FJavascriptProfileNode Node)
150+
{
151+
return reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetChildrenCount();
152+
}
153+
FJavascriptProfileNode UJavascriptLibrary::GetChild(FJavascriptProfileNode Node, int32 index)
154+
{
155+
FJavascriptProfileNode out;
156+
out.Node = reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetChild(index);
157+
return out;
158+
}
159+
int32 UJavascriptLibrary::GetDeoptInfosCount(FJavascriptProfileNode Node, int32 index)
160+
{
161+
const auto& infos = reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetDeoptInfos();
162+
return infos.size();
163+
}
164+
FString UJavascriptLibrary::GetDeoptInfo_Reason(FJavascriptProfileNode Node, int32 index)
165+
{
166+
const auto& infos = reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetDeoptInfos();
167+
return ANSI_TO_TCHAR(infos[index].deopt_reason);
168+
}
169+
FString UJavascriptLibrary::GetDeoptInfo_Stack(FJavascriptProfileNode Node, int32 index)
170+
{
171+
FString out;
172+
const auto& infos = reinterpret_cast<const CpuProfileNode*>(Node.Node)->GetDeoptInfos();
173+
for (const auto& frame : infos[index].stack)
174+
{
175+
out.Append(FString::Printf(TEXT("%d:%d"), frame.script_id, frame.position));
176+
}
177+
return out;
178+
}

0 commit comments

Comments
 (0)