Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: Node implementation of v8::Platform #14001

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion deps/v8/include/libplatform/libplatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,15 @@ enum class MessageLoopBehavior : bool {
* If |idle_task_support| is enabled then the platform will accept idle
* tasks (IdleTasksEnabled will return true) and will rely on the embedder
* calling v8::platform::RunIdleTasks to process the idle tasks.
* If |tracing_controller| is nullptr, the default platform will create a
* v8::platform::TracingController instance and use it.
*/
V8_PLATFORM_EXPORT v8::Platform* CreateDefaultPlatform(
int thread_pool_size = 0,
IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
InProcessStackDumping in_process_stack_dumping =
InProcessStackDumping::kEnabled);
InProcessStackDumping::kEnabled,
v8::TracingController* tracing_controller = nullptr);

/**
* Pumps the message loop for the given isolate.
Expand Down Expand Up @@ -67,6 +70,8 @@ V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform,
* Attempts to set the tracing controller for the given platform.
*
* The |platform| has to be created using |CreateDefaultPlatform|.
*
* DEPRECATED: Will be removed soon.
*/
V8_PLATFORM_EXPORT void SetTracingController(
v8::Platform* platform,
Expand Down
32 changes: 23 additions & 9 deletions deps/v8/include/libplatform/v8-tracing.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,15 @@ class V8_PLATFORM_EXPORT TraceConfig {
void operator=(const TraceConfig&) = delete;
};

class V8_PLATFORM_EXPORT TracingController {
#if defined(_MSC_VER)
#define V8_PLATFORM_NON_EXPORTED_BASE(code) \
__pragma(warning(suppress : 4275)) code
#else
#define V8_PLATFORM_NON_EXPORTED_BASE(code) code
#endif // defined(_MSC_VER)

class V8_PLATFORM_EXPORT TracingController
: public V8_PLATFORM_NON_EXPORTED_BASE(v8::TracingController) {
public:
enum Mode { DISABLED = 0, RECORDING_MODE };

Expand All @@ -227,25 +235,29 @@ class V8_PLATFORM_EXPORT TracingController {
};

TracingController();
~TracingController();
~TracingController() override;
void Initialize(TraceBuffer* trace_buffer);
const uint8_t* GetCategoryGroupEnabled(const char* category_group);
static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);

// v8::TracingController implementation.
const uint8_t* GetCategoryGroupEnabled(const char* category_group) override;
uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags);
unsigned int flags) override;
void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name, uint64_t handle);
const char* name, uint64_t handle) override;
void AddTraceStateObserver(
v8::TracingController::TraceStateObserver* observer) override;
void RemoveTraceStateObserver(
v8::TracingController::TraceStateObserver* observer) override;

void StartTracing(TraceConfig* trace_config);
void StopTracing();

void AddTraceStateObserver(Platform::TraceStateObserver* observer);
void RemoveTraceStateObserver(Platform::TraceStateObserver* observer);
static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);

private:
const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group);
Expand All @@ -255,14 +267,16 @@ class V8_PLATFORM_EXPORT TracingController {
std::unique_ptr<TraceBuffer> trace_buffer_;
std::unique_ptr<TraceConfig> trace_config_;
std::unique_ptr<base::Mutex> mutex_;
std::unordered_set<Platform::TraceStateObserver*> observers_;
std::unordered_set<v8::TracingController::TraceStateObserver*> observers_;
Mode mode_ = DISABLED;

// Disallow copy and assign
TracingController(const TracingController&) = delete;
void operator=(const TracingController&) = delete;
};

#undef V8_PLATFORM_NON_EXPORTED_BASE

} // namespace tracing
} // namespace platform
} // namespace v8
Expand Down
89 changes: 75 additions & 14 deletions deps/v8/include/v8-platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,66 @@ class ConvertableToTraceFormat {
virtual void AppendAsTraceFormat(std::string* out) const = 0;
};

/**
* V8 Tracing controller.
*
* Can be implemented by an embedder to record trace events from V8.
*/
class TracingController {
public:
virtual ~TracingController() = default;

/**
* Called by TRACE_EVENT* macros, don't call this directly.
* The name parameter is a category group for example:
* TRACE_EVENT0("v8,parse", "V8.Parse")
* The pointer returned points to a value with zero or more of the bits
* defined in CategoryGroupEnabledFlags.
**/
virtual const uint8_t* GetCategoryGroupEnabled(const char* name) {
static uint8_t no = 0;
return &no;
}

/**
* Adds a trace event to the platform tracing system. This function call is
* usually the result of a TRACE_* macro from trace_event_common.h when
* tracing and the category of the particular trace are enabled. It is not
* advisable to call this function on its own; it is really only meant to be
* used by the trace macros. The returned handle can be used by
* UpdateTraceEventDuration to update the duration of COMPLETE events.
*/
virtual uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<ConvertableToTraceFormat>* arg_convertables,
unsigned int flags) {
return 0;
}

/**
* Sets the duration field of a COMPLETE trace event. It must be called with
* the handle returned from AddTraceEvent().
**/
virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name, uint64_t handle) {}

class TraceStateObserver {
public:
virtual ~TraceStateObserver() = default;
virtual void OnTraceEnabled() = 0;
virtual void OnTraceDisabled() = 0;
};

/** Adds tracing state change observer. */
virtual void AddTraceStateObserver(TraceStateObserver*) {}

/** Removes tracing state change observer. */
virtual void RemoveTraceStateObserver(TraceStateObserver*) {}
};

/**
* V8 Platform abstraction layer.
*
Expand Down Expand Up @@ -135,6 +195,20 @@ class Platform {
* the epoch.
**/
virtual double MonotonicallyIncreasingTime() = 0;
typedef void (*StackTracePrinter)();

/**
* Returns a function pointer that print a stack trace of the current stack
* on invocation. Disables printing of the stack trace if nullptr.
*/
virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }

/**
* Returns an instance of a v8::TracingController. This must be non-nullptr.
*/
virtual TracingController* GetTracingController() = 0;

// DEPRECATED methods, use TracingController interface instead.

/**
* Called by TRACE_EVENT* macros, don't call this directly.
Expand Down Expand Up @@ -200,26 +274,13 @@ class Platform {
virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name, uint64_t handle) {}

class TraceStateObserver {
public:
virtual ~TraceStateObserver() = default;
virtual void OnTraceEnabled() = 0;
virtual void OnTraceDisabled() = 0;
};
typedef v8::TracingController::TraceStateObserver TraceStateObserver;

/** Adds tracing state change observer. */
virtual void AddTraceStateObserver(TraceStateObserver*) {}

/** Removes tracing state change observer. */
virtual void RemoveTraceStateObserver(TraceStateObserver*) {}

typedef void (*StackTracePrinter)();

/**
* Returns a function pointer that print a stack trace of the current stack
* on invocation. Disables printing of the stack trace if nullptr.
*/
virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }
};

} // namespace v8
Expand Down
13 changes: 6 additions & 7 deletions deps/v8/src/cancelable-task.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,17 @@ Cancelable::~Cancelable() {
CancelableTaskManager::CancelableTaskManager()
: task_id_counter_(0), canceled_(false) {}

uint32_t CancelableTaskManager::Register(Cancelable* task) {
CancelableTaskManager::Id CancelableTaskManager::Register(Cancelable* task) {
base::LockGuard<base::Mutex> guard(&mutex_);
uint32_t id = ++task_id_counter_;
// The loop below is just used when task_id_counter_ overflows.
while (cancelable_tasks_.count(id) > 0) ++id;
CancelableTaskManager::Id id = ++task_id_counter_;
// Id overflows are not supported.
CHECK_NE(0, id);
CHECK(!canceled_);
cancelable_tasks_[id] = task;
return id;
}


void CancelableTaskManager::RemoveFinishedTask(uint32_t id) {
void CancelableTaskManager::RemoveFinishedTask(CancelableTaskManager::Id id) {
base::LockGuard<base::Mutex> guard(&mutex_);
size_t removed = cancelable_tasks_.erase(id);
USE(removed);
Expand All @@ -49,7 +48,7 @@ void CancelableTaskManager::RemoveFinishedTask(uint32_t id) {
}

CancelableTaskManager::TryAbortResult CancelableTaskManager::TryAbort(
uint32_t id) {
CancelableTaskManager::Id id) {
base::LockGuard<base::Mutex> guard(&mutex_);
auto entry = cancelable_tasks_.find(id);
if (entry != cancelable_tasks_.end()) {
Expand Down
18 changes: 10 additions & 8 deletions deps/v8/src/cancelable-task.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#ifndef V8_CANCELABLE_TASK_H_
#define V8_CANCELABLE_TASK_H_

#include <map>
#include <unordered_map>

#include "include/v8-platform.h"
#include "src/base/atomic-utils.h"
Expand All @@ -24,12 +24,14 @@ class Isolate;
// from any fore- and background task/thread.
class V8_EXPORT_PRIVATE CancelableTaskManager {
public:
using Id = uint64_t;

CancelableTaskManager();

// Registers a new cancelable {task}. Returns the unique {id} of the task that
// can be used to try to abort a task by calling {Abort}.
// Must not be called after CancelAndWait.
uint32_t Register(Cancelable* task);
Id Register(Cancelable* task);

// Try to abort running a task identified by {id}. The possible outcomes are:
// (1) The task is already finished running or was canceled before and
Expand All @@ -39,7 +41,7 @@ class V8_EXPORT_PRIVATE CancelableTaskManager {
// removed.
//
enum TryAbortResult { kTaskRemoved, kTaskRunning, kTaskAborted };
TryAbortResult TryAbort(uint32_t id);
TryAbortResult TryAbort(Id id);

// Cancels all remaining registered tasks and waits for tasks that are
// already running. This disallows subsequent Register calls.
Expand All @@ -59,13 +61,13 @@ class V8_EXPORT_PRIVATE CancelableTaskManager {
private:
// Only called by {Cancelable} destructor. The task is done with executing,
// but needs to be removed.
void RemoveFinishedTask(uint32_t id);
void RemoveFinishedTask(Id id);

// To mitigate the ABA problem, the api refers to tasks through an id.
uint32_t task_id_counter_;
Id task_id_counter_;

// A set of cancelable tasks that are currently registered.
std::map<uint32_t, Cancelable*> cancelable_tasks_;
std::unordered_map<Id, Cancelable*> cancelable_tasks_;

// Mutex and condition variable enabling concurrent register and removing, as
// well as waiting for background tasks on {CancelAndWait}.
Expand All @@ -89,7 +91,7 @@ class V8_EXPORT_PRIVATE Cancelable {
// a platform. This step transfers ownership to the platform, which destroys
// the task after running it. Since the exact time is not known, we cannot
// access the object after handing it to a platform.
uint32_t id() { return id_; }
CancelableTaskManager::Id id() { return id_; }

protected:
bool TryRun() { return status_.TrySetValue(kWaiting, kRunning); }
Expand Down Expand Up @@ -120,7 +122,7 @@ class V8_EXPORT_PRIVATE Cancelable {

CancelableTaskManager* parent_;
base::AtomicValue<Status> status_;
uint32_t id_;
CancelableTaskManager::Id id_;

// The counter is incremented for failing tries to cancel a task. This can be
// used by the task itself as an indication how often external entities tried
Expand Down
32 changes: 17 additions & 15 deletions deps/v8/src/d8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ class PredictablePlatform : public Platform {
return synthetic_time_in_sec_ += 0.00001;
}

v8::TracingController* GetTracingController() override {
return platform_->GetTracingController();
}

using Platform::AddTraceEvent;
uint64_t AddTraceEvent(char phase, const uint8_t* categoryEnabledFlag,
const char* name, const char* scope, uint64_t id,
Expand Down Expand Up @@ -3063,18 +3067,7 @@ int Shell::Main(int argc, char* argv[]) {
if (!SetOptions(argc, argv)) return 1;
v8::V8::InitializeICUDefaultLocation(argv[0], options.icu_data_file);

v8::platform::InProcessStackDumping in_process_stack_dumping =
options.disable_in_process_stack_traces
? v8::platform::InProcessStackDumping::kDisabled
: v8::platform::InProcessStackDumping::kEnabled;

g_platform = i::FLAG_verify_predictable
? new PredictablePlatform()
: v8::platform::CreateDefaultPlatform(
0, v8::platform::IdleTaskSupport::kEnabled,
in_process_stack_dumping);

platform::tracing::TracingController* tracing_controller;
platform::tracing::TracingController* tracing_controller = nullptr;
if (options.trace_enabled) {
trace_file.open("v8_trace.json");
tracing_controller = new platform::tracing::TracingController();
Expand All @@ -3083,11 +3076,20 @@ int Shell::Main(int argc, char* argv[]) {
platform::tracing::TraceBuffer::kRingBufferChunks,
platform::tracing::TraceWriter::CreateJSONTraceWriter(trace_file));
tracing_controller->Initialize(trace_buffer);
if (!i::FLAG_verify_predictable) {
platform::SetTracingController(g_platform, tracing_controller);
}
}

v8::platform::InProcessStackDumping in_process_stack_dumping =
options.disable_in_process_stack_traces
? v8::platform::InProcessStackDumping::kDisabled
: v8::platform::InProcessStackDumping::kEnabled;

g_platform = i::FLAG_verify_predictable
? new PredictablePlatform()
: v8::platform::CreateDefaultPlatform(
0, v8::platform::IdleTaskSupport::kEnabled,
in_process_stack_dumping,
tracing_controller);

v8::V8::InitializePlatform(g_platform);
v8::V8::Initialize();
if (options.natives_blob || options.snapshot_blob) {
Expand Down
2 changes: 2 additions & 0 deletions deps/v8/src/heap/heap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ Heap::Heap()
heap_iterator_depth_(0),
local_embedder_heap_tracer_(nullptr),
fast_promotion_mode_(false),
use_tasks_(true),
force_oom_(false),
delay_sweeper_tasks_for_testing_(false),
pending_layout_change_object_(nullptr) {
Expand Down Expand Up @@ -5823,6 +5824,7 @@ void Heap::RegisterExternallyReferencedObject(Object** object) {
}

void Heap::TearDown() {
use_tasks_ = false;
#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
Verify();
Expand Down
Loading