v8  6.7.288(node10.6.0)
V8 is Google's open source JavaScript engine
v8-platform.h
Go to the documentation of this file.
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_V8_PLATFORM_H_
6 #define V8_V8_PLATFORM_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <memory>
11 #include <string>
12 
13 #include "v8config.h" // NOLINT(build/include)
14 
15 namespace v8 {
16 
17 class Isolate;
18 
19 /**
20  * A Task represents a unit of work.
21  */
22 class Task {
23  public:
24  virtual ~Task() = default;
25 
26  virtual void Run() = 0;
27 };
28 
29 /**
30  * An IdleTask represents a unit of work to be performed in idle time.
31  * The Run method is invoked with an argument that specifies the deadline in
32  * seconds returned by MonotonicallyIncreasingTime().
33  * The idle task is expected to complete by this deadline.
34  */
35 class IdleTask {
36  public:
37  virtual ~IdleTask() = default;
38  virtual void Run(double deadline_in_seconds) = 0;
39 };
40 
41 /**
42  * A TaskRunner allows scheduling of tasks. The TaskRunner may still be used to
43  * post tasks after the isolate gets destructed, but these tasks may not get
44  * executed anymore. All tasks posted to a given TaskRunner will be invoked in
45  * sequence. Tasks can be posted from any thread.
46  */
47 class TaskRunner {
48  public:
49  /**
50  * Schedules a task to be invoked by this TaskRunner. The TaskRunner
51  * implementation takes ownership of |task|.
52  */
53  virtual void PostTask(std::unique_ptr<Task> task) = 0;
54 
55  /**
56  * Schedules a task to be invoked by this TaskRunner. The task is scheduled
57  * after the given number of seconds |delay_in_seconds|. The TaskRunner
58  * implementation takes ownership of |task|.
59  */
60  virtual void PostDelayedTask(std::unique_ptr<Task> task,
61  double delay_in_seconds) = 0;
62 
63  /**
64  * Schedules an idle task to be invoked by this TaskRunner. The task is
65  * scheduled when the embedder is idle. Requires that
66  * TaskRunner::SupportsIdleTasks(isolate) is true. Idle tasks may be reordered
67  * relative to other task types and may be starved for an arbitrarily long
68  * time if no idle time is available. The TaskRunner implementation takes
69  * ownership of |task|.
70  */
71  virtual void PostIdleTask(std::unique_ptr<IdleTask> task) = 0;
72 
73  /**
74  * Returns true if idle tasks are enabled for this TaskRunner.
75  */
76  virtual bool IdleTasksEnabled() = 0;
77 
78  TaskRunner() = default;
79  virtual ~TaskRunner() = default;
80 
81  private:
82  TaskRunner(const TaskRunner&) = delete;
83  TaskRunner& operator=(const TaskRunner&) = delete;
84 };
85 
86 /**
87  * The interface represents complex arguments to trace events.
88  */
90  public:
91  virtual ~ConvertableToTraceFormat() = default;
92 
93  /**
94  * Append the class info to the provided |out| string. The appended
95  * data must be a valid JSON object. Strings must be properly quoted, and
96  * escaped. There is no processing applied to the content after it is
97  * appended.
98  */
99  virtual void AppendAsTraceFormat(std::string* out) const = 0;
100 };
101 
102 /**
103  * V8 Tracing controller.
104  *
105  * Can be implemented by an embedder to record trace events from V8.
106  */
108  public:
109  virtual ~TracingController() = default;
110 
111  /**
112  * Called by TRACE_EVENT* macros, don't call this directly.
113  * The name parameter is a category group for example:
114  * TRACE_EVENT0("v8,parse", "V8.Parse")
115  * The pointer returned points to a value with zero or more of the bits
116  * defined in CategoryGroupEnabledFlags.
117  **/
118  virtual const uint8_t* GetCategoryGroupEnabled(const char* name) {
119  static uint8_t no = 0;
120  return &no;
121  }
122 
123  /**
124  * Adds a trace event to the platform tracing system. These function calls are
125  * usually the result of a TRACE_* macro from trace_event_common.h when
126  * tracing and the category of the particular trace are enabled. It is not
127  * advisable to call these functions on their own; they are really only meant
128  * to be used by the trace macros. The returned handle can be used by
129  * UpdateTraceEventDuration to update the duration of COMPLETE events.
130  */
131  virtual uint64_t AddTraceEvent(
132  char phase, const uint8_t* category_enabled_flag, const char* name,
133  const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
134  const char** arg_names, const uint8_t* arg_types,
135  const uint64_t* arg_values,
137  unsigned int flags) {
138  return 0;
139  }
140  virtual uint64_t AddTraceEventWithTimestamp(
141  char phase, const uint8_t* category_enabled_flag, const char* name,
142  const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
143  const char** arg_names, const uint8_t* arg_types,
144  const uint64_t* arg_values,
146  unsigned int flags, int64_t timestamp) {
147  return 0;
148  }
149 
150  /**
151  * Sets the duration field of a COMPLETE trace event. It must be called with
152  * the handle returned from AddTraceEvent().
153  **/
154  virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
155  const char* name, uint64_t handle) {}
156 
158  public:
159  virtual ~TraceStateObserver() = default;
160  virtual void OnTraceEnabled() = 0;
161  virtual void OnTraceDisabled() = 0;
162  };
163 
164  /** Adds tracing state change observer. */
166 
167  /** Removes tracing state change observer. */
169 };
170 
171 /**
172  * A V8 memory page allocator.
173  *
174  * Can be implemented by an embedder to manage large host OS allocations.
175  */
177  public:
178  virtual ~PageAllocator() = default;
179 
180  /**
181  * Gets the page granularity for AllocatePages and FreePages. Addresses and
182  * lengths for those calls should be multiples of AllocatePageSize().
183  */
184  virtual size_t AllocatePageSize() = 0;
185 
186  /**
187  * Gets the page granularity for SetPermissions and ReleasePages. Addresses
188  * and lengths for those calls should be multiples of CommitPageSize().
189  */
190  virtual size_t CommitPageSize() = 0;
191 
192  /**
193  * Sets the random seed so that GetRandomMmapAddr() will generate repeatable
194  * sequences of random mmap addresses.
195  */
196  virtual void SetRandomMmapSeed(int64_t seed) = 0;
197 
198  /**
199  * Returns a randomized address, suitable for memory allocation under ASLR.
200  * The address will be aligned to AllocatePageSize.
201  */
202  virtual void* GetRandomMmapAddr() = 0;
203 
204  /**
205  * Memory permissions.
206  */
207  enum Permission {
210  // TODO(hpayer): Remove this flag. Memory should never be rwx.
213  };
214 
215  /**
216  * Allocates memory in range with the given alignment and permission.
217  */
218  virtual void* AllocatePages(void* address, size_t length, size_t alignment,
219  Permission permissions) = 0;
220 
221  /**
222  * Frees memory in a range that was allocated by a call to AllocatePages.
223  */
224  virtual bool FreePages(void* address, size_t length) = 0;
225 
226  /**
227  * Releases memory in a range that was allocated by a call to AllocatePages.
228  */
229  virtual bool ReleasePages(void* address, size_t length,
230  size_t new_length) = 0;
231 
232  /**
233  * Sets permissions on pages in an allocated range.
234  */
235  virtual bool SetPermissions(void* address, size_t length,
236  Permission permissions) = 0;
237 };
238 
239 /**
240  * V8 Platform abstraction layer.
241  *
242  * The embedder has to provide an implementation of this interface before
243  * initializing the rest of V8.
244  */
245 class Platform {
246  public:
247  /**
248  * This enum is used to indicate whether a task is potentially long running,
249  * or causes a long wait. The embedder might want to use this hint to decide
250  * whether to execute the task on a dedicated thread.
251  */
255  };
256 
257  virtual ~Platform() = default;
258 
259  /**
260  * Allows the embedder to manage memory page allocations.
261  */
263  // TODO(bbudge) Make this abstract after all embedders implement this.
264  return nullptr;
265  }
266 
267  /**
268  * Enables the embedder to respond in cases where V8 can't allocate large
269  * blocks of memory. V8 retries the failed allocation once after calling this
270  * method. On success, execution continues; otherwise V8 exits with a fatal
271  * error.
272  * Embedder overrides of this function must NOT call back into V8.
273  */
274  virtual void OnCriticalMemoryPressure() {
275  // TODO(bbudge) Remove this when embedders override the following method.
276  // See crbug.com/634547.
277  }
278 
279  /**
280  * Enables the embedder to respond in cases where V8 can't allocate large
281  * memory regions. The |length| parameter is the amount of memory needed.
282  * Returns true if memory is now available. Returns false if no memory could
283  * be made available. V8 will retry allocations until this method returns
284  * false.
285  *
286  * Embedder overrides of this function must NOT call back into V8.
287  */
288  virtual bool OnCriticalMemoryPressure(size_t length) { return false; }
289 
290  /**
291  * Gets the number of worker threads used by GetWorkerThreadsTaskRunner() and
292  * CallOnWorkerThread(). This can be used to estimate the number of tasks a
293  * work package should be split into. A return value of 0 means that there are
294  * no worker threads available. Note that a value of 0 won't prohibit V8 from
295  * posting tasks using |CallOnWorkerThread|.
296  */
297  virtual int NumberOfWorkerThreads() {
298  return static_cast<int>(NumberOfAvailableBackgroundThreads());
299  }
300 
301  /**
302  * Deprecated. Use NumberOfWorkerThreads() instead.
303  * TODO(gab): Remove this when all embedders override
304  * NumberOfWorkerThreads() instead.
305  */
307  "NumberOfAvailableBackgroundThreads() is deprecated, use "
308  "NumberOfAvailableBackgroundThreads() instead.",
309  virtual size_t NumberOfAvailableBackgroundThreads()) {
310  return 0;
311  }
312 
313  /**
314  * Returns a TaskRunner which can be used to post a task on the foreground.
315  * This function should only be called from a foreground thread.
316  */
318  Isolate* isolate) {
319  // TODO(ahaas): Make this function abstract after it got implemented on all
320  // platforms.
321  return {};
322  }
323 
324  /**
325  * Returns a TaskRunner which can be used to post a task on a background.
326  * This function should only be called from a foreground thread.
327  */
329  "GetBackgroundTaskRunner() is deprecated, use "
330  "GetWorkerThreadsTaskRunner() "
331  "instead.",
333  Isolate* isolate)) {
334  // TODO(gab): Remove this method when all embedders have moved to
335  // GetWorkerThreadsTaskRunner().
336 
337  // An implementation needs to be provided here because this is called by the
338  // default GetWorkerThreadsTaskRunner() implementation below. In practice
339  // however, all code either:
340  // - Overrides GetWorkerThreadsTaskRunner() (thus not making this call) --
341  // i.e. all v8 code.
342  // - Overrides this method (thus not making this call) -- i.e. all
343  // unadapted embedders.
344  abort();
345  }
346 
347  /**
348  * Returns a TaskRunner which can be used to post async tasks on a worker.
349  * This function should only be called from a foreground thread.
350  */
352  Isolate* isolate) {
353  // TODO(gab): Make this function abstract after it got implemented on all
354  // platforms.
356  }
357 
358  /**
359  * Schedules a task to be invoked on a background thread. |expected_runtime|
360  * indicates that the task will run a long time. The Platform implementation
361  * takes ownership of |task|. There is no guarantee about order of execution
362  * of tasks wrt order of scheduling, nor is there a guarantee about the
363  * thread the task will be run on.
364  */
366  "ExpectedRuntime is deprecated, use CallOnWorkerThread() instead.",
367  virtual void CallOnBackgroundThread(Task* task,
369  // An implementation needs to be provided here because this is called by the
370  // default implementation below. In practice however, all code either:
371  // - Overrides the new method (thus not making this call) -- i.e. all v8
372  // code.
373  // - Overrides this method (thus not making this call) -- i.e. all
374  // unadapted embedders.
375  abort();
376  }
377 
378  /**
379  * Schedules a task to be invoked on a worker thread.
380  * TODO(gab): Make pure virtual when all embedders override this instead of
381  * CallOnBackgroundThread().
382  */
385  }
386 
387  /**
388  * Schedules a task that blocks the main thread to be invoked with
389  * high-priority on a worker thread.
390  */
392  // Embedders may optionally override this to process these tasks in a high
393  // priority pool.
395  }
396 
397  /**
398  * Schedules a task to be invoked on a foreground thread wrt a specific
399  * |isolate|. Tasks posted for the same isolate should be execute in order of
400  * scheduling. The definition of "foreground" is opaque to V8.
401  */
402  virtual void CallOnForegroundThread(Isolate* isolate, Task* task) = 0;
403 
404  /**
405  * Schedules a task to be invoked on a foreground thread wrt a specific
406  * |isolate| after the given number of seconds |delay_in_seconds|.
407  * Tasks posted for the same isolate should be execute in order of
408  * scheduling. The definition of "foreground" is opaque to V8.
409  */
410  virtual void CallDelayedOnForegroundThread(Isolate* isolate, Task* task,
411  double delay_in_seconds) = 0;
412 
413  /**
414  * Schedules a task to be invoked on a foreground thread wrt a specific
415  * |isolate| when the embedder is idle.
416  * Requires that SupportsIdleTasks(isolate) is true.
417  * Idle tasks may be reordered relative to other task types and may be
418  * starved for an arbitrarily long time if no idle time is available.
419  * The definition of "foreground" is opaque to V8.
420  */
421  virtual void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) {
422  // TODO(ulan): Make this function abstract after V8 roll in Chromium.
423  }
424 
425  /**
426  * Returns true if idle tasks are enabled for the given |isolate|.
427  */
428  virtual bool IdleTasksEnabled(Isolate* isolate) {
429  // TODO(ulan): Make this function abstract after V8 roll in Chromium.
430  return false;
431  }
432 
433  /**
434  * Monotonically increasing time in seconds from an arbitrary fixed point in
435  * the past. This function is expected to return at least
436  * millisecond-precision values. For this reason,
437  * it is recommended that the fixed point be no further in the past than
438  * the epoch.
439  **/
440  virtual double MonotonicallyIncreasingTime() = 0;
441 
442  /**
443  * Current wall-clock time in milliseconds since epoch.
444  * This function is expected to return at least millisecond-precision values.
445  */
446  virtual double CurrentClockTimeMillis() = 0;
447 
448  typedef void (*StackTracePrinter)();
449 
450  /**
451  * Returns a function pointer that print a stack trace of the current stack
452  * on invocation. Disables printing of the stack trace if nullptr.
453  */
454  virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }
455 
456  /**
457  * Returns an instance of a v8::TracingController. This must be non-nullptr.
458  */
460 
461  protected:
462  /**
463  * Default implementation of current wall-clock time in milliseconds
464  * since epoch. Useful for implementing |CurrentClockTimeMillis| if
465  * nothing special needed.
466  */
467  static double SystemClockTimeMillis();
468 };
469 
470 } // namespace v8
471 
472 #endif // V8_V8_PLATFORM_H_
virtual void RemoveTraceStateObserver(TraceStateObserver *)
Definition: v8-platform.h:168
virtual size_t AllocatePageSize()=0
virtual ~Platform()=default
virtual StackTracePrinter GetStackTracePrinter()
Definition: v8-platform.h:454
virtual void Run()=0
virtual void PostIdleTask(std::unique_ptr< IdleTask > task)=0
size_t(* GetExternallyAllocatedMemoryInBytesCallback)()
Definition: v8.h:7437
virtual ~TaskRunner()=default
virtual bool IdleTasksEnabled()=0
virtual void * AllocatePages(void *address, size_t length, size_t alignment, Permission permissions)=0
virtual double CurrentClockTimeMillis()=0
virtual size_t CommitPageSize()=0
virtual const uint8_t * GetCategoryGroupEnabled(const char *name)
Definition: v8-platform.h:118
#define V8_DEPRECATE_SOON(message, declarator)
Definition: v8config.h:340
virtual int NumberOfWorkerThreads()
Definition: v8-platform.h:297
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)
Definition: v8-platform.h:131
virtual void AddTraceStateObserver(TraceStateObserver *)
Definition: v8-platform.h:165
virtual void AppendAsTraceFormat(std::string *out) const =0
void(* StackTracePrinter)()
Definition: v8-platform.h:448
virtual ~TracingController()=default
virtual ~Task()=default
virtual ~ConvertableToTraceFormat()=default
virtual PageAllocator * GetPageAllocator()
Definition: v8-platform.h:262
virtual void PostTask(std::unique_ptr< Task > task)=0
virtual bool IdleTasksEnabled(Isolate *isolate)
Definition: v8-platform.h:428
virtual bool SetPermissions(void *address, size_t length, Permission permissions)=0
virtual bool FreePages(void *address, size_t length)=0
virtual double MonotonicallyIncreasingTime()=0
static double SystemClockTimeMillis()
virtual void * GetRandomMmapAddr()=0
constexpr uint32_t CurrentValueSerializerFormatVersion()
virtual ~IdleTask()=default
virtual void OnCriticalMemoryPressure()
Definition: v8-platform.h:274
virtual void UpdateTraceEventDuration(const uint8_t *category_enabled_flag, const char *name, uint64_t handle)
Definition: v8-platform.h:154
TaskRunner()=default
virtual void SetRandomMmapSeed(int64_t seed)=0
virtual void CallIdleOnForegroundThread(Isolate *isolate, IdleTask *task)
Definition: v8-platform.h:421
virtual void Run(double deadline_in_seconds)=0
virtual TracingController * GetTracingController()=0
virtual bool OnCriticalMemoryPressure(size_t length)
Definition: v8-platform.h:288
virtual void CallOnForegroundThread(Isolate *isolate, Task *task)=0
virtual ~PageAllocator()=default
virtual void PostDelayedTask(std::unique_ptr< Task > task, double delay_in_seconds)=0
virtual void CallDelayedOnForegroundThread(Isolate *isolate, Task *task, double delay_in_seconds)=0
virtual bool ReleasePages(void *address, size_t length, size_t new_length)=0
virtual uint64_t AddTraceEventWithTimestamp(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, int64_t timestamp)
Definition: v8-platform.h:140