Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e7ad928
feat: optimize paint and add profile records.
andycall Jan 18, 2024
01019fb
feat: optimize trace, timeline and paint steps.
andycall Feb 14, 2024
f1a7f52
chore: linter.
andycall Feb 14, 2024
07e53f7
feat: record layout steps.
andycall Feb 15, 2024
0c94e2a
feat: full support layout tracks.
andycall Feb 15, 2024
87c3ad9
refactor: optimize profiler code.
andycall Feb 15, 2024
a32b841
refactor: same impls between layout and paint.
andycall Feb 16, 2024
6612d2b
feat: add ui command tracks
andycall Feb 16, 2024
1ce69f6
feat: add more tracks for element.
andycall Feb 19, 2024
b74e1bc
feat: good enough for element tracking.
andycall Feb 19, 2024
5b35672
feat: add tracking for CSS.
andycall Feb 19, 2024
26c4358
feat: add network tracks.
andycall Feb 20, 2024
41be912
feat: add basic native traces.
andycall Feb 21, 2024
1d8a007
feat: basic native api tracing.
andycall Feb 21, 2024
739e64e
feat: basic support tracking of binding methods.
andycall Feb 23, 2024
bb7c119
feat: add global switch and track events.
andycall Feb 26, 2024
adc54c6
feat: add tracks for setTimeout and requestAnimationFrame.
andycall Feb 27, 2024
0c45978
fix: rollback paint.
andycall Feb 27, 2024
7c3f755
fix: fix profiler stack.
andycall Feb 27, 2024
a664c31
fix: fix unit test.
andycall Feb 28, 2024
9c727ed
chore: fix linter.
andycall Feb 28, 2024
82b474a
fix: fix async exception didn't reported.
andycall Feb 28, 2024
0a1f3e6
feat: add profiler clear.
andycall Mar 5, 2024
e315f8f
fix: fix integration test.
andycall Mar 10, 2024
7656dc5
Committing clang-format changes
Mar 10, 2024
e795ca0
fix: fix unit test.
andycall Mar 10, 2024
a3ed587
fix: fix compile.
andycall Mar 10, 2024
88f2a3c
chore: optimize code
andycall Mar 26, 2024
da10d76
fix: fix tester.
andycall Mar 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bridge/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ list(APPEND BRIDGE_SOURCE
foundation/string_view.cc
foundation/native_value.cc
foundation/native_type.cc
foundation/stop_watch.cc
foundation/profiler.cc
foundation/ui_command_buffer.cc
foundation/ui_command_strategy.cc
polyfill/dist/polyfill.cc
Expand Down
4 changes: 4 additions & 0 deletions bridge/bindings/qjs/exception_state.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,8 @@ JSValue ExceptionState::ToQuickJS() {
return exception_;
}

JSValue ExceptionState::CurrentException(JSContext* ctx) {
return JS_GetException(ctx);
}

} // namespace webf
1 change: 1 addition & 0 deletions bridge/bindings/qjs/exception_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class ExceptionState {
ExceptionState& ReturnThis();

JSValue ToQuickJS();
static JSValue CurrentException(JSContext* ctx);

private:
JSValue exception_{JS_NULL};
Expand Down
6 changes: 5 additions & 1 deletion bridge/bindings/qjs/qjs_function.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,13 @@ ScriptValue QJSFunction::Invoke(JSContext* ctx, const ScriptValue& this_val, int
argv[0 + i] = arguments[i].QJSValue();
}

ExecutingContext* context = ExecutingContext::From(ctx);
context->dartIsolateContext()->profiler()->StartTrackSteps("JS_Call");

JSValue returnValue = JS_Call(ctx, function_, this_val.QJSValue(), argc, argv);

ExecutingContext* context = ExecutingContext::From(ctx);
context->dartIsolateContext()->profiler()->FinishTrackSteps();

context->DrainMicrotasks();

// Free the previous duplicated function.
Expand Down
2 changes: 2 additions & 0 deletions bridge/bindings/qjs/script_promise_resolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ ScriptPromise ScriptPromiseResolver::Promise() {
}

void ScriptPromiseResolver::ResolveOrRejectImmediately(JSValue value) {
context_->dartIsolateContext()->profiler()->StartTrackAsyncEvaluation();
{
if (state_ == kResolving) {
JSValue arguments[] = {value};
Expand All @@ -55,6 +56,7 @@ void ScriptPromiseResolver::ResolveOrRejectImmediately(JSValue value) {
}
}
context_->DrainMicrotasks();
context_->dartIsolateContext()->profiler()->FinishTrackAsyncEvaluation();
}

} // namespace webf
34 changes: 34 additions & 0 deletions bridge/core/api/api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,18 @@ void evaluateScriptsInternal(void* page_,
uint64_t* bytecode_len,
const char* bundleFilename,
int32_t startLine,
int64_t profile_id,
Dart_Handle persistent_handle,
EvaluateScriptsCallback result_callback) {
auto page = reinterpret_cast<webf::WebFPage*>(page_);
assert(std::this_thread::get_id() == page->currentThread());

page->dartIsolateContext()->profiler()->StartTrackEvaluation(profile_id);

bool is_success = page->evaluateScript(code, code_len, parsed_bytecodes, bytecode_len, bundleFilename, startLine);

page->dartIsolateContext()->profiler()->FinishTrackEvaluation(profile_id);

page->dartIsolateContext()->dispatcher()->PostToDart(page->isDedicated(), ReturnEvaluateScriptsInternal,
persistent_handle, result_callback, is_success);
}
Expand All @@ -45,11 +52,18 @@ static void ReturnEvaluateQuickjsByteCodeResultToDart(Dart_PersistentHandle pers
void evaluateQuickjsByteCodeInternal(void* page_,
uint8_t* bytes,
int32_t byteLen,
int64_t profile_id,
Dart_PersistentHandle persistent_handle,
EvaluateQuickjsByteCodeCallback result_callback) {
auto page = reinterpret_cast<webf::WebFPage*>(page_);
assert(std::this_thread::get_id() == page->currentThread());

page->dartIsolateContext()->profiler()->StartTrackEvaluation(profile_id);

bool is_success = page->evaluateByteCode(bytes, byteLen);

page->dartIsolateContext()->profiler()->FinishTrackEvaluation(profile_id);

page->dartIsolateContext()->dispatcher()->PostToDart(page->isDedicated(), ReturnEvaluateQuickjsByteCodeResultToDart,
persistent_handle, result_callback, is_success);
}
Expand All @@ -63,12 +77,19 @@ static void ReturnParseHTMLToDart(Dart_PersistentHandle persistent_handle, Parse
void parseHTMLInternal(void* page_,
char* code,
int32_t length,
int64_t profile_id,
Dart_PersistentHandle dart_handle,
ParseHTMLCallback result_callback) {
auto page = reinterpret_cast<webf::WebFPage*>(page_);
assert(std::this_thread::get_id() == page->currentThread());

page->dartIsolateContext()->profiler()->StartTrackEvaluation(profile_id);

page->parseHTML(code, length);
dart_free(code);

page->dartIsolateContext()->profiler()->FinishTrackEvaluation(profile_id);

page->dartIsolateContext()->dispatcher()->PostToDart(page->isDedicated(), ReturnParseHTMLToDart, dart_handle,
result_callback);
}
Expand All @@ -91,8 +112,14 @@ void invokeModuleEventInternal(void* page_,
auto page = reinterpret_cast<webf::WebFPage*>(page_);
auto dart_isolate_context = page->executingContext()->dartIsolateContext();
assert(std::this_thread::get_id() == page->currentThread());

page->dartIsolateContext()->profiler()->StartTrackAsyncEvaluation();

auto* result = page->invokeModuleEvent(reinterpret_cast<webf::SharedNativeString*>(module_name), eventType, event,
reinterpret_cast<webf::NativeValue*>(extra));

page->dartIsolateContext()->profiler()->FinishTrackAsyncEvaluation();

dart_isolate_context->dispatcher()->PostToDart(page->isDedicated(), ReturnInvokeEventResultToDart, persistent_handle,
result_callback, result);
}
Expand All @@ -104,6 +131,7 @@ static void ReturnDumpByteCodeResultToDart(Dart_Handle persistent_handle, DumpQu
}

void dumpQuickJsByteCodeInternal(void* page_,
int64_t profile_id,
const char* code,
int32_t code_len,
uint8_t** parsed_bytecodes,
Expand All @@ -113,9 +141,15 @@ void dumpQuickJsByteCodeInternal(void* page_,
DumpQuickjsByteCodeCallback result_callback) {
auto page = reinterpret_cast<webf::WebFPage*>(page_);
auto dart_isolate_context = page->executingContext()->dartIsolateContext();

dart_isolate_context->profiler()->StartTrackEvaluation(profile_id);

assert(std::this_thread::get_id() == page->currentThread());
uint8_t* bytes = page->dumpByteCode(code, code_len, url, bytecode_len);
*parsed_bytecodes = bytes;

dart_isolate_context->profiler()->FinishTrackEvaluation(profile_id);

dart_isolate_context->dispatcher()->PostToDart(page->isDedicated(), ReturnDumpByteCodeResultToDart, persistent_handle,
result_callback);
}
Expand Down
4 changes: 4 additions & 0 deletions bridge/core/api/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@ void evaluateScriptsInternal(void* page_,
uint64_t* bytecode_len,
const char* bundleFilename,
int32_t startLine,
int64_t profile_id,
Dart_Handle dart_handle,
EvaluateScriptsCallback result_callback);

void evaluateQuickjsByteCodeInternal(void* page_,
uint8_t* bytes,
int32_t byteLen,
int64_t profile_id,
Dart_PersistentHandle persistent_handle,
EvaluateQuickjsByteCodeCallback result_callback);
void parseHTMLInternal(void* page_,
char* code,
int32_t length,
int64_t profile_id,
Dart_PersistentHandle dart_handle,
ParseHTMLCallback result_callback);

Expand All @@ -40,6 +43,7 @@ void invokeModuleEventInternal(void* page_,
InvokeModuleEventCallback result_callback);

void dumpQuickJsByteCodeInternal(void* page_,
int64_t profile_id,
const char* code,
int32_t code_len,
uint8_t** parsed_bytecodes,
Expand Down
64 changes: 50 additions & 14 deletions bridge/core/binding_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ static void ReturnEventResultToDart(Dart_Handle persistent_handle,
}

static void HandleCallFromDartSideWrapper(NativeBindingObject* binding_object,
int64_t profile_id,
NativeValue* method,
int32_t argc,
NativeValue* argv,
Expand All @@ -39,7 +40,7 @@ static void HandleCallFromDartSideWrapper(NativeBindingObject* binding_object,
auto context_id = binding_object->binding_target_->contextId();

dart_isolate->dispatcher()->PostToJs(is_dedicated, context_id, NativeBindingObject::HandleCallFromDartSide,
dart_isolate, binding_object, method, argc, argv, persistent_handle,
dart_isolate, binding_object, profile_id, method, argc, argv, persistent_handle,
result_callback);
}

Expand All @@ -48,13 +49,17 @@ NativeBindingObject::NativeBindingObject(BindingObject* target)

void NativeBindingObject::HandleCallFromDartSide(DartIsolateContext* dart_isolate_context,
NativeBindingObject* binding_object,
int64_t profile_id,
NativeValue* native_method,
int32_t argc,
NativeValue* argv,
Dart_PersistentHandle dart_object,
DartInvokeResultCallback result_callback) {
if (binding_object->disposed_)
return;

dart_isolate_context->profiler()->StartTrackEvaluation(profile_id);

AtomicString method = AtomicString(
binding_object->binding_target_->ctx(),
std::unique_ptr<AutoFreeNativeString>(reinterpret_cast<AutoFreeNativeString*>(native_method->u.ptr)));
Expand All @@ -63,6 +68,8 @@ void NativeBindingObject::HandleCallFromDartSide(DartIsolateContext* dart_isolat
auto* return_value = new NativeValue();
std::memcpy(return_value, &result, sizeof(NativeValue));

dart_isolate_context->profiler()->FinishTrackEvaluation(profile_id);

dart_isolate_context->dispatcher()->PostToDart(binding_object->binding_target_->GetExecutingContext()->isDedicated(),
ReturnEventResultToDart, dart_object, return_value, result_callback);
}
Expand Down Expand Up @@ -109,11 +116,16 @@ NativeValue BindingObject::InvokeBindingMethod(const AtomicString& method,
const NativeValue* argv,
uint32_t reason,
ExceptionState& exception_state) const {
auto* context = GetExecutingContext();
auto* profiler = context->dartIsolateContext()->profiler();

profiler->StartTrackSteps("BindingObject::InvokeBindingMethod");

std::vector<NativeBindingObject*> invoke_elements_deps;
// Collect all DOM elements in arguments.
CollectElementDepsOnArgs(invoke_elements_deps, argc, argv);
// Make sure all these elements are ready in dart.
GetExecutingContext()->FlushUICommand(this, reason, invoke_elements_deps);
context->FlushUICommand(this, reason, invoke_elements_deps);

NativeValue return_value = Native_NewNull();
NativeValue native_method =
Expand All @@ -123,10 +135,12 @@ NativeValue BindingObject::InvokeBindingMethod(const AtomicString& method,
WEBF_LOG(INFO) << "[Dispatcher]: PostToDartSync method: InvokeBindingMethod; Call Begin";
#endif

profiler->StartTrackLinkSteps("Call To Dart");

GetDispatcher()->PostToDartSync(
GetExecutingContext()->isDedicated(), contextId(),
[&](bool cancel, double contextId, const NativeBindingObject* binding_object, NativeValue* return_value,
NativeValue* method, int32_t argc, const NativeValue* argv) {
[&](bool cancel, double contextId, int64_t profile_id, const NativeBindingObject* binding_object,
NativeValue* return_value, NativeValue* method, int32_t argc, const NativeValue* argv) {
if (cancel)
return;

Expand All @@ -138,17 +152,22 @@ NativeValue BindingObject::InvokeBindingMethod(const AtomicString& method,
WEBF_LOG(DEBUG) << "invoke_bindings_methods_from_native is nullptr" << std::endl;
return;
}
binding_object_->invoke_bindings_methods_from_native(contextId, binding_object, return_value, method, argc,
argv);
binding_object_->invoke_bindings_methods_from_native(contextId, profile_id, binding_object, return_value,
method, argc, argv);
#if ENABLE_LOG
WEBF_LOG(INFO) << "[Dispatcher]: PostToDartSync method: InvokeBindingMethod; Callback End";
#endif
},
GetExecutingContext()->contextId(), binding_object_, &return_value, &native_method, argc, argv);
GetExecutingContext()->contextId(), profiler->link_id(), binding_object_, &return_value, &native_method, argc,
argv);

#if ENABLE_LOG
WEBF_LOG(INFO) << "[Dispatcher]: PostToDartSync method: InvokeBindingMethod; Call End";
#endif

profiler->FinishTrackLinkSteps();
profiler->FinishTrackSteps();

return return_value;
}

Expand All @@ -157,23 +176,30 @@ NativeValue BindingObject::InvokeBindingMethod(BindingMethodCallOperations bindi
const NativeValue* argv,
uint32_t reason,
ExceptionState& exception_state) const {
auto* context = GetExecutingContext();
auto* profiler = context->dartIsolateContext()->profiler();

profiler->StartTrackSteps("BindingObject::InvokeBindingMethod");

std::vector<NativeBindingObject*> invoke_elements_deps;
// Collect all DOM elements in arguments.
CollectElementDepsOnArgs(invoke_elements_deps, argc, argv);
// Make sure all these elements are ready in dart.
GetExecutingContext()->FlushUICommand(this, reason, invoke_elements_deps);
context->FlushUICommand(this, reason, invoke_elements_deps);

NativeValue return_value = Native_NewNull();

#if ENABLE_LOG
WEBF_LOG(INFO) << "[Dispatcher]: PostToDartSync method: InvokeBindingMethod; Call Begin";
#endif

profiler->StartTrackLinkSteps("Call To Dart");

NativeValue native_method = NativeValueConverter<NativeTypeInt64>::ToNativeValue(binding_method_call_operation);
GetDispatcher()->PostToDartSync(
GetExecutingContext()->isDedicated(), contextId(),
[&](bool cancel, double contextId, const NativeBindingObject* binding_object, NativeValue* return_value,
NativeValue* method, int32_t argc, const NativeValue* argv) {
[&](bool cancel, double contextId, int64_t profile_id, const NativeBindingObject* binding_object,
NativeValue* return_value, NativeValue* method, int32_t argc, const NativeValue* argv) {
if (cancel)
return;

Expand All @@ -185,18 +211,21 @@ NativeValue BindingObject::InvokeBindingMethod(BindingMethodCallOperations bindi
WEBF_LOG(DEBUG) << "invoke_bindings_methods_from_native is nullptr" << std::endl;
return;
}
binding_object_->invoke_bindings_methods_from_native(contextId, binding_object, return_value, method, argc,
argv);
binding_object_->invoke_bindings_methods_from_native(contextId, profile_id, binding_object, return_value,
method, argc, argv);
#if ENABLE_LOG
WEBF_LOG(INFO) << "[Dispatcher]: PostToDartSync method: InvokeBindingMethod; Callback End";
#endif
},
GetExecutingContext()->contextId(), binding_object_, &return_value, &native_method, argc, argv);
context->contextId(), profiler->link_id(), binding_object_, &return_value, &native_method, argc, argv);

#if ENABLE_LOG
WEBF_LOG(INFO) << "[Dispatcher]: PostToDartSync method: InvokeBindingMethod; Call End";
#endif

profiler->FinishTrackLinkSteps();
profiler->FinishTrackSteps();

return return_value;
}

Expand All @@ -209,8 +238,15 @@ NativeValue BindingObject::GetBindingProperty(const AtomicString& prop,
"Can not get binding property on BindingObject, dart binding object had been disposed");
return Native_NewNull();
}

GetExecutingContext()->dartIsolateContext()->profiler()->StartTrackSteps("BindingObject::GetBindingProperty");

const NativeValue argv[] = {Native_NewString(prop.ToNativeString(GetExecutingContext()->ctx()).release())};
return InvokeBindingMethod(BindingMethodCallOperations::kGetProperty, 1, argv, reason, exception_state);
NativeValue result = InvokeBindingMethod(BindingMethodCallOperations::kGetProperty, 1, argv, reason, exception_state);

GetExecutingContext()->dartIsolateContext()->profiler()->FinishTrackSteps();

return result;
}

NativeValue BindingObject::SetBindingProperty(const AtomicString& prop,
Expand Down
3 changes: 3 additions & 0 deletions bridge/core/binding_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class ScriptPromiseResolver;
class DartIsolateContext;

using InvokeBindingsMethodsFromNative = void (*)(double contextId,
int64_t profile_id,
const NativeBindingObject* binding_object,
NativeValue* return_value,
NativeValue* method,
Expand All @@ -34,6 +35,7 @@ using InvokeBindingsMethodsFromNative = void (*)(double contextId,
using DartInvokeResultCallback = void (*)(Dart_Handle dart_object, NativeValue* result);

using InvokeBindingMethodsFromDart = void (*)(NativeBindingObject* binding_object,
int64_t profile_id,
NativeValue* method,
int32_t argc,
NativeValue* argv,
Expand All @@ -46,6 +48,7 @@ struct NativeBindingObject : public DartReadable {

static void HandleCallFromDartSide(DartIsolateContext* dart_isolate_context,
NativeBindingObject* binding_object,
int64_t profile_id,
NativeValue* method,
int32_t argc,
NativeValue* argv,
Expand Down
Loading