Skip to content

Commit 88da02c

Browse files
committed
demonstrate node_platform and node_v8platform
1 parent 6b1819c commit 88da02c

File tree

5 files changed

+521
-9
lines changed

5 files changed

+521
-9
lines changed

node.gyp

+3
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@
182182
'src/node_url.cc',
183183
'src/node_util.cc',
184184
'src/node_v8.cc',
185+
'src/node_v8platform.cc',
185186
'src/node_stat_watcher.cc',
186187
'src/node_watchdog.cc',
187188
'src/node_zlib.cc',
@@ -222,7 +223,9 @@
222223
'src/node_internals.h',
223224
'src/node_javascript.h',
224225
'src/node_mutex.h',
226+
'src/node_platform.h',
225227
'src/node_root_certs.h',
228+
'src/node_v8platform.h',
226229
'src/node_version.h',
227230
'src/node_watchdog.h',
228231
'src/node_wrap.h',

src/node.cc

+16-9
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "node_internals.h"
2828
#include "node_revert.h"
2929
#include "node_debug_options.h"
30+
#include "node_v8platform.h"
3031

3132
#if defined HAVE_PERFCTR
3233
#include "node_counters.h"
@@ -241,14 +242,19 @@ static node::DebugOptions debug_options;
241242

242243
static struct {
243244
#if NODE_USE_V8_PLATFORM
244-
void Initialize(int thread_pool_size) {
245-
platform_ = v8::platform::CreateDefaultPlatform(thread_pool_size);
245+
void Initialize(int thread_pool_size, uv_loop_t* loop) {
246+
platform_ = new node::platform::NodePlatform(thread_pool_size, loop);
247+
// TODO: the following methods expect v8::Platform, how do we deal with that?
246248
V8::InitializePlatform(platform_);
247249
tracing::TraceEventHelper::SetCurrentPlatform(platform_);
248250
}
249251

250-
void PumpMessageLoop(Isolate* isolate) {
251-
v8::platform::PumpMessageLoop(platform_, isolate);
252+
void PumpMessageLoop() {
253+
platform_->PumpMessageLoop();
254+
}
255+
256+
void RunIdle(double budgetSeconds) {
257+
platform_->RunIdle(budgetSeconds);
252258
}
253259

254260
void Dispose() {
@@ -266,17 +272,18 @@ static struct {
266272
void StartTracingAgent() {
267273
CHECK(tracing_agent_ == nullptr);
268274
tracing_agent_ = new tracing::Agent();
275+
// TODO: this method expects v8::Platform, how do we deal with that?
269276
tracing_agent_->Start(platform_, trace_enabled_categories);
270277
}
271278

272279
void StopTracingAgent() {
273280
tracing_agent_->Stop();
274281
}
275282

276-
v8::Platform* platform_;
277283
tracing::Agent* tracing_agent_;
284+
node::platform::NodePlatform* platform_;
278285
#else // !NODE_USE_V8_PLATFORM
279-
void Initialize(int thread_pool_size) {}
286+
void Initialize(int thread_pool_size, uv_loop_t* loop) {}
280287
void PumpMessageLoop(Isolate* isolate) {}
281288
void Dispose() {}
282289
bool StartInspector(Environment *env, const char* script_path,
@@ -4481,11 +4488,11 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
44814488
SealHandleScope seal(isolate);
44824489
bool more;
44834490
do {
4484-
v8_platform.PumpMessageLoop(isolate);
4491+
v8_platform.PumpMessageLoop();
44854492
more = uv_run(env.event_loop(), UV_RUN_ONCE);
44864493

44874494
if (more == false) {
4488-
v8_platform.PumpMessageLoop(isolate);
4495+
v8_platform.PumpMessageLoop();
44894496
EmitBeforeExit(&env);
44904497

44914498
// Emit `beforeExit` if the loop became alive either after emitting
@@ -4591,7 +4598,7 @@ int Start(int argc, char** argv) {
45914598
V8::SetEntropySource(crypto::EntropySource);
45924599
#endif // HAVE_OPENSSL
45934600

4594-
v8_platform.Initialize(v8_thread_pool_size);
4601+
v8_platform.Initialize(v8_thread_pool_size, uv_default_loop());
45954602
// Enable tracing when argv has --trace-events-enabled.
45964603
if (trace_enabled) {
45974604
fprintf(stderr, "Warning: Trace event is an experimental feature "

src/node_platform.h

+234
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
// Original source: https://github.com/v8/v8/blob/a9e56f4f36d70d16a956367133dda258c4f52bf4/include/v8-platform.h
2+
// Original headers:
3+
// Copyright 2013 the V8 project authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style license that can be
5+
// found in the LICENSE file.
6+
7+
#ifndef SRC_NODE_PLATFORM_H_
8+
#define SRC_NODE_PLATFORM_H_
9+
10+
#include "v8.h"
11+
12+
#include <stddef.h>
13+
#include <stdint.h>
14+
#include <memory>
15+
#include <string>
16+
17+
18+
namespace node {
19+
namespace platform {
20+
21+
class v8::Isolate;
22+
23+
/**
24+
* A Task represents a unit of work.
25+
*/
26+
class Task {
27+
public:
28+
virtual ~Task() = default;
29+
30+
virtual void Run() = 0;
31+
};
32+
33+
/**
34+
* An IdleTask represents a unit of work to be performed in idle time.
35+
* The Run method is invoked with an argument that specifies the deadline in
36+
* seconds returned by MonotonicallyIncreasingTime().
37+
* The idle task is expected to complete by this deadline.
38+
*/
39+
class IdleTask {
40+
public:
41+
virtual ~IdleTask() = default;
42+
virtual void Run(double deadline_in_seconds) = 0;
43+
};
44+
45+
/**
46+
* The interface represents complex arguments to trace events.
47+
*/
48+
class ConvertableToTraceFormat {
49+
public:
50+
virtual ~ConvertableToTraceFormat() = default;
51+
52+
/**
53+
* Append the class info to the provided |out| string. The appended
54+
* data must be a valid JSON object. Strings must be properly quoted, and
55+
* escaped. There is no processing applied to the content after it is
56+
* appended.
57+
*/
58+
virtual void AppendAsTraceFormat(std::string* out) const = 0;
59+
};
60+
61+
/**
62+
* V8 Platform abstraction layer.
63+
*
64+
* The embedder has to provide an implementation of this interface before
65+
* initializing the rest of V8.
66+
*/
67+
class Platform {
68+
public:
69+
/**
70+
* This enum is used to indicate whether a task is potentially long running,
71+
* or causes a long wait. The embedder might want to use this hint to decide
72+
* whether to execute the task on a dedicated thread.
73+
*/
74+
enum ExpectedRuntime {
75+
kShortRunningTask,
76+
kLongRunningTask
77+
};
78+
79+
virtual ~Platform() = default;
80+
81+
/**
82+
* Gets the number of threads that are used to execute background tasks. Is
83+
* used to estimate the number of tasks a work package should be split into.
84+
* A return value of 0 means that there are no background threads available.
85+
* Note that a value of 0 won't prohibit V8 from posting tasks using
86+
* |CallOnBackgroundThread|.
87+
*/
88+
virtual size_t NumberOfAvailableBackgroundThreads() { return 0; }
89+
90+
/**
91+
* Schedules a task to be invoked on a background thread. |expected_runtime|
92+
* indicates that the task will run a long time. The Platform implementation
93+
* takes ownership of |task|. There is no guarantee about order of execution
94+
* of tasks wrt order of scheduling, nor is there a guarantee about the
95+
* thread the task will be run on.
96+
*/
97+
virtual void CallOnBackgroundThread(Task* task,
98+
ExpectedRuntime expected_runtime) = 0;
99+
100+
/**
101+
* Schedules a task to be invoked on a foreground thread wrt a specific
102+
* |isolate|. Tasks posted for the same isolate should be execute in order of
103+
* scheduling. The definition of "foreground" is opaque to V8.
104+
*/
105+
virtual void CallOnForegroundThread(Isolate* isolate, Task* task) = 0;
106+
107+
/**
108+
* Schedules a task to be invoked on a foreground thread wrt a specific
109+
* |isolate| after the given number of seconds |delay_in_seconds|.
110+
* Tasks posted for the same isolate should be execute in order of
111+
* scheduling. The definition of "foreground" is opaque to V8.
112+
*/
113+
virtual void CallDelayedOnForegroundThread(Isolate* isolate, Task* task,
114+
double delay_in_seconds) = 0;
115+
116+
/**
117+
* Schedules a task to be invoked on a foreground thread wrt a specific
118+
* |isolate| when the embedder is idle.
119+
* Requires that SupportsIdleTasks(isolate) is true.
120+
* Idle tasks may be reordered relative to other task types and may be
121+
* starved for an arbitrarily long time if no idle time is available.
122+
* The definition of "foreground" is opaque to V8.
123+
*/
124+
virtual void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) {
125+
// TODO(ulan): Make this function abstract after V8 roll in Chromium.
126+
}
127+
128+
/**
129+
* Returns true if idle tasks are enabled for the given |isolate|.
130+
*/
131+
virtual bool IdleTasksEnabled(Isolate* isolate) {
132+
// TODO(ulan): Make this function abstract after V8 roll in Chromium.
133+
return false;
134+
}
135+
136+
/**
137+
* Monotonically increasing time in seconds from an arbitrary fixed point in
138+
* the past. This function is expected to return at least
139+
* millisecond-precision values. For this reason,
140+
* it is recommended that the fixed point be no further in the past than
141+
* the epoch.
142+
**/
143+
virtual double MonotonicallyIncreasingTime() = 0;
144+
145+
/**
146+
* Called by TRACE_EVENT* macros, don't call this directly.
147+
* The name parameter is a category group for example:
148+
* TRACE_EVENT0("v8,parse", "V8.Parse")
149+
* The pointer returned points to a value with zero or more of the bits
150+
* defined in CategoryGroupEnabledFlags.
151+
**/
152+
virtual const uint8_t* GetCategoryGroupEnabled(const char* name) {
153+
static uint8_t no = 0;
154+
return &no;
155+
}
156+
157+
/**
158+
* Gets the category group name of the given category_enabled_flag pointer.
159+
* Usually used while serliazing TRACE_EVENTs.
160+
**/
161+
virtual const char* GetCategoryGroupName(
162+
const uint8_t* category_enabled_flag) {
163+
static const char dummy[] = "dummy";
164+
return dummy;
165+
}
166+
167+
/**
168+
* Adds a trace event to the platform tracing system. This function call is
169+
* usually the result of a TRACE_* macro from trace_event_common.h when
170+
* tracing and the category of the particular trace are enabled. It is not
171+
* advisable to call this function on its own; it is really only meant to be
172+
* used by the trace macros. The returned handle can be used by
173+
* UpdateTraceEventDuration to update the duration of COMPLETE events.
174+
*/
175+
virtual uint64_t AddTraceEvent(
176+
char phase, const uint8_t* category_enabled_flag, const char* name,
177+
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
178+
const char** arg_names, const uint8_t* arg_types,
179+
const uint64_t* arg_values, unsigned int flags) {
180+
return 0;
181+
}
182+
183+
/**
184+
* Adds a trace event to the platform tracing system. This function call is
185+
* usually the result of a TRACE_* macro from trace_event_common.h when
186+
* tracing and the category of the particular trace are enabled. It is not
187+
* advisable to call this function on its own; it is really only meant to be
188+
* used by the trace macros. The returned handle can be used by
189+
* UpdateTraceEventDuration to update the duration of COMPLETE events.
190+
*/
191+
virtual uint64_t AddTraceEvent(
192+
char phase, const uint8_t* category_enabled_flag, const char* name,
193+
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
194+
const char** arg_names, const uint8_t* arg_types,
195+
const uint64_t* arg_values,
196+
std::unique_ptr<ConvertableToTraceFormat>* arg_convertables,
197+
unsigned int flags) {
198+
return AddTraceEvent(phase, category_enabled_flag, name, scope, id, bind_id,
199+
num_args, arg_names, arg_types, arg_values, flags);
200+
}
201+
202+
/**
203+
* Sets the duration field of a COMPLETE trace event. It must be called with
204+
* the handle returned from AddTraceEvent().
205+
**/
206+
virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
207+
const char* name, uint64_t handle) {}
208+
209+
class TraceStateObserver {
210+
public:
211+
virtual ~TraceStateObserver() = default;
212+
virtual void OnTraceEnabled() = 0;
213+
virtual void OnTraceDisabled() = 0;
214+
};
215+
216+
/** Adds tracing state change observer. */
217+
virtual void AddTraceStateObserver(TraceStateObserver*) {}
218+
219+
/** Removes tracing state change observer. */
220+
virtual void RemoveTraceStateObserver(TraceStateObserver*) {}
221+
222+
typedef void (*StackTracePrinter)();
223+
224+
/**
225+
* Returns a function pointer that print a stack trace of the current stack
226+
* on invocation. Disables printing of the stack trace if nullptr.
227+
*/
228+
virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }
229+
};
230+
231+
} // namespace platform
232+
} // namespace v8
233+
234+
#endif // V8_V8_PLATFORM_H_

0 commit comments

Comments
 (0)