请问大家有什么方法集成JS性能分析到Unreal Insights吗 #1127
ChenRenault
started this conversation in
Ideas
Replies: 3 comments 6 replies
-
群里你问的时候,我还以为你是卡在上报数据给UE这块呢。 |
Beta Was this translation helpful? Give feedback.
1 reply
-
对v8小修改可以实现对所有函数的hook,之前给一个项目搞过。 |
Beta Was this translation helpful? Give feedback.
0 replies
-
这个是针对8.4.371.19版本v8的修改,修改后SetTraceEnterEventHandler和SetTraceExitEventHandler分别对函数的进入和退出hook。 diff --git a/include/v8.h b/include/v8.h
index 18d72f1630..186bc0326e 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -7798,6 +7798,10 @@ enum JitCodeEventOptions {
*/
typedef void (*JitCodeEventHandler)(const JitCodeEvent* event);
+typedef void (*TraceEnterEventHandler)(Isolate* isolate, Local<StackFrame> stack_frame);
+
+typedef void (*TraceExitEventHandler)(Isolate* isolate);
+
/**
* Callback function passed to SetUnhandledExceptionCallback.
*/
@@ -9229,6 +9233,10 @@ class V8_EXPORT Isolate {
void SetJitCodeEventHandler(JitCodeEventOptions options,
JitCodeEventHandler event_handler);
+ void SetTraceEnterEventHandler(TraceEnterEventHandler event_handler);
+
+ void SetTraceExitEventHandler(TraceExitEventHandler event_handler);
+
/**
* Modifies the stack limit for this Isolate.
*
diff --git a/src/api/api.cc b/src/api/api.cc
index 93780bceec..1a7197d01e 100644
--- a/src/api/api.cc
+++ b/src/api/api.cc
@@ -8795,6 +8795,16 @@ void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
isolate->logger()->SetCodeEventHandler(options, event_handler);
}
+void Isolate::SetTraceEnterEventHandler(TraceEnterEventHandler event_handler) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->trace_enter_event_handler_ = event_handler;
+}
+
+void Isolate::SetTraceExitEventHandler(TraceExitEventHandler event_handler) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->trace_exit_event_handler_ = event_handler;
+}
+
void Isolate::SetStackLimit(uintptr_t stack_limit) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
CHECK(stack_limit);
diff --git a/src/execution/isolate.h b/src/execution/isolate.h
index de00d862a3..583d8bf966 100644
--- a/src/execution/isolate.h
+++ b/src/execution/isolate.h
@@ -1867,6 +1867,12 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
friend class TestSerializer;
DISALLOW_COPY_AND_ASSIGN(Isolate);
+
+ public:
+ TraceEnterEventHandler trace_enter_event_handler_ = nullptr;
+
+ TraceExitEventHandler trace_exit_event_handler_ = nullptr;
+
};
#undef FIELD_ACCESSOR
diff --git a/src/runtime/runtime-test.cc b/src/runtime/runtime-test.cc
index db804490f4..80cb359168 100644
--- a/src/runtime/runtime-test.cc
+++ b/src/runtime/runtime-test.cc
@@ -26,6 +26,7 @@
#include "src/logging/counters.h"
#include "src/objects/heap-object-inl.h"
#include "src/objects/js-array-inl.h"
+#include "src/objects/frame-array-inl.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/smi.h"
#include "src/snapshot/snapshot.h"
@@ -944,12 +945,51 @@ void PrintIndentation(Isolate* isolate) {
} // namespace
RUNTIME_FUNCTION(Runtime_TraceEnter) {
- SealHandleScope shs(isolate);
- DCHECK_EQ(0, args.length());
- PrintIndentation(isolate);
- JavaScriptFrame::PrintTop(isolate, stdout, true, false);
- PrintF(" {\n");
- return ReadOnlyRoots(isolate).undefined_value();
+ if (isolate->trace_enter_event_handler_) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(0, args.length());
+ JavaScriptFrameIterator it(isolate);
+ while (!it.done()) {
+ if (it.frame()->is_java_script()) {
+ JavaScriptFrame* frame = it.frame();
+ Handle<FrameArray> frame_array =
+ isolate->factory()->NewFrameArray(1);
+ Code code = frame->LookupCode();
+ Handle<AbstractCode> abstract_code(AbstractCode::cast(code), isolate);
+ const int offset = static_cast<int>(frame->pc() - code.InstructionStart());
+ int flags = 0;
+ Handle<JSFunction> function(frame->function(), isolate);
+ Handle<Object> receiver(frame->receiver(), isolate);
+ Handle<FixedArray> parameters = isolate->factory()->empty_fixed_array();
+
+ if (frame->IsConstructor()) flags |= FrameArray::kIsConstructor;
+
+ frame_array = FrameArray::AppendJSFrame(
+ frame_array,
+ receiver->IsTheHole(isolate)
+ ? Handle<Object>::cast(isolate->factory()->undefined_value())
+ : receiver,
+ function,
+ abstract_code, offset, flags, parameters);
+
+ frame_array->ShrinkToFit(isolate);
+
+ Handle<StackTraceFrame> stack_trace_frame =
+ isolate->factory()->NewStackTraceFrame(frame_array, 0);
+
+ isolate->trace_enter_event_handler_(reinterpret_cast<v8::Isolate*>(isolate),
+ Utils::StackFrameToLocal(stack_trace_frame));
+
+ return ReadOnlyRoots(isolate).undefined_value();;
+ }
+ it.Advance();
+ }
+ isolate->trace_enter_event_handler_(reinterpret_cast<v8::Isolate*>(isolate), v8::Local<v8::StackFrame>());
+ return ReadOnlyRoots(isolate).undefined_value();
+ } else {
+ SealHandleScope shs(isolate);
+ return ReadOnlyRoots(isolate).undefined_value();
+ }
}
@@ -957,10 +997,9 @@ RUNTIME_FUNCTION(Runtime_TraceExit) {
SealHandleScope shs(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_CHECKED(Object, obj, 0);
- PrintIndentation(isolate);
- PrintF("} -> ");
- obj.ShortPrint();
- PrintF("\n");
+ if (isolate->trace_exit_event_handler_) {
+ isolate->trace_exit_event_handler_(reinterpret_cast<v8::Isolate*>(isolate));
+ }
return obj; // return TOS
}
|
Beta Was this translation helpful? Give feedback.
5 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
我之前的使用Cocos2d-x + tracy
通过lua_sethook 可以知道函数开始和结束,
然后分别调用 tracy的ZoneBegin 和ZoneEnd相关接口,即可埋点记录Lua函数的性能消耗。
现在UE中Unreal Insights我也可以实现 类似ZoneBegin 和ZoneEnd相关接口,问题是暂时不知道怎么设置JS函数开始和结束的钩子函数
目前是通过JavaScript能否能实现所有函数调用时的钩子函数? - theanarkh的回答 - 知乎
我修改Content/JavaScript/puerts/modular.js 中的genRequire的函数劫持了require函数,但是会出现加载报错(loadUEType相关的)
Beta Was this translation helpful? Give feedback.
All reactions