Skip to content

src: expose node.http trace flag by array#48142

Closed
H4ad wants to merge 2 commits intonodejs:mainfrom
h4ad-forks:perf/is-trace-http
Closed

src: expose node.http trace flag by array#48142
H4ad wants to merge 2 commits intonodejs:mainfrom
h4ad-forks:perf/is-trace-http

Conversation

@H4ad
Copy link
Member

@H4ad H4ad commented May 23, 2023

This PR aims to fix the issue raised on NodeJS Performance: nodejs/performance#81

The function isTraceHTTPEnable is a little bit expensive, in general, that function should not even appear in the stack trace since is just to check if the trace is enabled.

The solution was inspired by nodejs/performance#81 (comment) and it basically exposes the C++ pointer of the flag that tells if the HTTP trace is enabled or not by using an array.

To Reviewers

Some interesting files that could be looked to review this code:

  • Built-in Trace Function:
    BUILTIN(IsTraceCategoryEnabled) {
    HandleScope scope(isolate);
    Handle<Object> category = args.atOrUndefined(isolate, 1);
    if (!category->IsString()) {
    THROW_NEW_ERROR_RETURN_FAILURE(
    isolate, NewTypeError(MessageTemplate::kTraceEventCategoryError));
    }
    bool enabled;
    #if defined(V8_USE_PERFETTO)
    MaybeUtf8 category_str(isolate, Handle<String>::cast(category));
    perfetto::DynamicCategory dynamic_category{*category_str};
    enabled = TRACE_EVENT_CATEGORY_ENABLED(dynamic_category);
    #else
    enabled = *GetCategoryGroupEnabled(isolate, Handle<String>::cast(category));
    #endif
    return isolate->heap()->ToBoolean(enabled);
    }
  • The implementation of GetCategoryGroupEnabled:
    const uint8_t* TracingController::GetCategoryGroupEnabled(
    const char* category_group) {
    // Check that category group does not contain double quote
    DCHECK(!strchr(category_group, '"'));
    // The g_category_groups is append only, avoid using a lock for the fast path.
    size_t category_index = base::Acquire_Load(&g_category_index);
    // Search for pre-existing category group.
    for (size_t i = 0; i < category_index; ++i) {
    if (strcmp(g_category_groups[i], category_group) == 0) {
    return &g_category_group_enabled[i];
    }
    }
    // Slow path. Grab the lock.
    base::MutexGuard lock(mutex_.get());
    // Check the list again with lock in hand.
    unsigned char* category_group_enabled = nullptr;
    category_index = base::Acquire_Load(&g_category_index);
    for (size_t i = 0; i < category_index; ++i) {
    if (strcmp(g_category_groups[i], category_group) == 0) {
    return &g_category_group_enabled[i];
    }
    }
    // Create a new category group.
    // Check that there is a slot for the new category_group.
    DCHECK(category_index < kMaxCategoryGroups);
    if (category_index < kMaxCategoryGroups) {
    // Don't hold on to the category_group pointer, so that we can create
    // category groups with strings not known at compile time (this is
    // required by SetWatchEvent).
    const char* new_group = base::Strdup(category_group);
    g_category_groups[category_index] = new_group;
    DCHECK(!g_category_group_enabled[category_index]);
    // Note that if both included and excluded patterns in the
    // TraceConfig are empty, we exclude nothing,
    // thereby enabling this category group.
    UpdateCategoryGroupEnabledFlag(category_index);
    category_group_enabled = &g_category_group_enabled[category_index];
    // Update the max index now.
    base::Release_Store(&g_category_index, category_index + 1);
    } else {
    category_group_enabled =
    &g_category_group_enabled[g_category_categories_exhausted];
    }
    return category_group_enabled;
    }
  • The defined function used to get the current category pointer:
    // Get a pointer to the enabled state of the given trace category. Only
    // long-lived literal strings should be given as the category group. The
    // returned pointer can be held permanently in a local static for example. If
    // the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
    // TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
    // between the load of the tracing state and the call to
    // TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
    // for best performance when tracing is disabled.
    // const uint8_t*
    // TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group)
    #define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
    node::tracing::TraceEventHelper::GetCategoryGroupEnabled

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants