Turn audio into a shareable video. forked from nypublicradio/audiogram

v8-platform.h 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  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. #ifndef V8_V8_PLATFORM_H_
  5. #define V8_V8_PLATFORM_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <stdlib.h> // For abort.
  9. #include <memory>
  10. #include <string>
  11. #include "v8config.h" // NOLINT(build/include)
  12. namespace v8 {
  13. class Isolate;
  14. /**
  15. * A Task represents a unit of work.
  16. */
  17. class Task {
  18. public:
  19. virtual ~Task() = default;
  20. virtual void Run() = 0;
  21. };
  22. /**
  23. * An IdleTask represents a unit of work to be performed in idle time.
  24. * The Run method is invoked with an argument that specifies the deadline in
  25. * seconds returned by MonotonicallyIncreasingTime().
  26. * The idle task is expected to complete by this deadline.
  27. */
  28. class IdleTask {
  29. public:
  30. virtual ~IdleTask() = default;
  31. virtual void Run(double deadline_in_seconds) = 0;
  32. };
  33. /**
  34. * A TaskRunner allows scheduling of tasks. The TaskRunner may still be used to
  35. * post tasks after the isolate gets destructed, but these tasks may not get
  36. * executed anymore. All tasks posted to a given TaskRunner will be invoked in
  37. * sequence. Tasks can be posted from any thread.
  38. */
  39. class TaskRunner {
  40. public:
  41. /**
  42. * Schedules a task to be invoked by this TaskRunner. The TaskRunner
  43. * implementation takes ownership of |task|.
  44. */
  45. virtual void PostTask(std::unique_ptr<Task> task) = 0;
  46. /**
  47. * Schedules a task to be invoked by this TaskRunner. The TaskRunner
  48. * implementation takes ownership of |task|. The |task| cannot be nested
  49. * within other task executions.
  50. *
  51. * Requires that |TaskRunner::NonNestableTasksEnabled()| is true.
  52. */
  53. virtual void PostNonNestableTask(std::unique_ptr<Task> task) {}
  54. /**
  55. * Schedules a task to be invoked by this TaskRunner. The task is scheduled
  56. * after the given number of seconds |delay_in_seconds|. The TaskRunner
  57. * implementation takes ownership of |task|.
  58. */
  59. virtual void PostDelayedTask(std::unique_ptr<Task> task,
  60. double delay_in_seconds) = 0;
  61. /**
  62. * Schedules a task to be invoked by this TaskRunner. The task is scheduled
  63. * after the given number of seconds |delay_in_seconds|. The TaskRunner
  64. * implementation takes ownership of |task|. The |task| cannot be nested
  65. * within other task executions.
  66. *
  67. * Requires that |TaskRunner::NonNestableDelayedTasksEnabled()| is true.
  68. */
  69. virtual void PostNonNestableDelayedTask(std::unique_ptr<Task> task,
  70. double delay_in_seconds) {}
  71. /**
  72. * Schedules an idle task to be invoked by this TaskRunner. The task is
  73. * scheduled when the embedder is idle. Requires that
  74. * |TaskRunner::IdleTasksEnabled()| is true. Idle tasks may be reordered
  75. * relative to other task types and may be starved for an arbitrarily long
  76. * time if no idle time is available. The TaskRunner implementation takes
  77. * ownership of |task|.
  78. */
  79. virtual void PostIdleTask(std::unique_ptr<IdleTask> task) = 0;
  80. /**
  81. * Returns true if idle tasks are enabled for this TaskRunner.
  82. */
  83. virtual bool IdleTasksEnabled() = 0;
  84. /**
  85. * Returns true if non-nestable tasks are enabled for this TaskRunner.
  86. */
  87. virtual bool NonNestableTasksEnabled() const { return false; }
  88. /**
  89. * Returns true if non-nestable delayed tasks are enabled for this TaskRunner.
  90. */
  91. virtual bool NonNestableDelayedTasksEnabled() const { return false; }
  92. TaskRunner() = default;
  93. virtual ~TaskRunner() = default;
  94. TaskRunner(const TaskRunner&) = delete;
  95. TaskRunner& operator=(const TaskRunner&) = delete;
  96. };
  97. /**
  98. * The interface represents complex arguments to trace events.
  99. */
  100. class ConvertableToTraceFormat {
  101. public:
  102. virtual ~ConvertableToTraceFormat() = default;
  103. /**
  104. * Append the class info to the provided |out| string. The appended
  105. * data must be a valid JSON object. Strings must be properly quoted, and
  106. * escaped. There is no processing applied to the content after it is
  107. * appended.
  108. */
  109. virtual void AppendAsTraceFormat(std::string* out) const = 0;
  110. };
  111. /**
  112. * V8 Tracing controller.
  113. *
  114. * Can be implemented by an embedder to record trace events from V8.
  115. */
  116. class TracingController {
  117. public:
  118. virtual ~TracingController() = default;
  119. /**
  120. * Called by TRACE_EVENT* macros, don't call this directly.
  121. * The name parameter is a category group for example:
  122. * TRACE_EVENT0("v8,parse", "V8.Parse")
  123. * The pointer returned points to a value with zero or more of the bits
  124. * defined in CategoryGroupEnabledFlags.
  125. **/
  126. virtual const uint8_t* GetCategoryGroupEnabled(const char* name) {
  127. static uint8_t no = 0;
  128. return &no;
  129. }
  130. /**
  131. * Adds a trace event to the platform tracing system. These function calls are
  132. * usually the result of a TRACE_* macro from trace_event_common.h when
  133. * tracing and the category of the particular trace are enabled. It is not
  134. * advisable to call these functions on their own; they are really only meant
  135. * to be used by the trace macros. The returned handle can be used by
  136. * UpdateTraceEventDuration to update the duration of COMPLETE events.
  137. */
  138. virtual uint64_t AddTraceEvent(
  139. char phase, const uint8_t* category_enabled_flag, const char* name,
  140. const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
  141. const char** arg_names, const uint8_t* arg_types,
  142. const uint64_t* arg_values,
  143. std::unique_ptr<ConvertableToTraceFormat>* arg_convertables,
  144. unsigned int flags) {
  145. return 0;
  146. }
  147. virtual uint64_t AddTraceEventWithTimestamp(
  148. char phase, const uint8_t* category_enabled_flag, const char* name,
  149. const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
  150. const char** arg_names, const uint8_t* arg_types,
  151. const uint64_t* arg_values,
  152. std::unique_ptr<ConvertableToTraceFormat>* arg_convertables,
  153. unsigned int flags, int64_t timestamp) {
  154. return 0;
  155. }
  156. /**
  157. * Sets the duration field of a COMPLETE trace event. It must be called with
  158. * the handle returned from AddTraceEvent().
  159. **/
  160. virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
  161. const char* name, uint64_t handle) {}
  162. class TraceStateObserver {
  163. public:
  164. virtual ~TraceStateObserver() = default;
  165. virtual void OnTraceEnabled() = 0;
  166. virtual void OnTraceDisabled() = 0;
  167. };
  168. /** Adds tracing state change observer. */
  169. virtual void AddTraceStateObserver(TraceStateObserver*) {}
  170. /** Removes tracing state change observer. */
  171. virtual void RemoveTraceStateObserver(TraceStateObserver*) {}
  172. };
  173. /**
  174. * A V8 memory page allocator.
  175. *
  176. * Can be implemented by an embedder to manage large host OS allocations.
  177. */
  178. class PageAllocator {
  179. public:
  180. virtual ~PageAllocator() = default;
  181. /**
  182. * Gets the page granularity for AllocatePages and FreePages. Addresses and
  183. * lengths for those calls should be multiples of AllocatePageSize().
  184. */
  185. virtual size_t AllocatePageSize() = 0;
  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. * Sets the random seed so that GetRandomMmapAddr() will generate repeatable
  193. * sequences of random mmap addresses.
  194. */
  195. virtual void SetRandomMmapSeed(int64_t seed) = 0;
  196. /**
  197. * Returns a randomized address, suitable for memory allocation under ASLR.
  198. * The address will be aligned to AllocatePageSize.
  199. */
  200. virtual void* GetRandomMmapAddr() = 0;
  201. /**
  202. * Memory permissions.
  203. */
  204. enum Permission {
  205. kNoAccess,
  206. kRead,
  207. kReadWrite,
  208. // TODO(hpayer): Remove this flag. Memory should never be rwx.
  209. kReadWriteExecute,
  210. kReadExecute
  211. };
  212. /**
  213. * Allocates memory in range with the given alignment and permission.
  214. */
  215. virtual void* AllocatePages(void* address, size_t length, size_t alignment,
  216. Permission permissions) = 0;
  217. /**
  218. * Frees memory in a range that was allocated by a call to AllocatePages.
  219. */
  220. virtual bool FreePages(void* address, size_t length) = 0;
  221. /**
  222. * Releases memory in a range that was allocated by a call to AllocatePages.
  223. */
  224. virtual bool ReleasePages(void* address, size_t length,
  225. size_t new_length) = 0;
  226. /**
  227. * Sets permissions on pages in an allocated range.
  228. */
  229. virtual bool SetPermissions(void* address, size_t length,
  230. Permission permissions) = 0;
  231. /**
  232. * Frees memory in the given [address, address + size) range. address and size
  233. * should be operating system page-aligned. The next write to this
  234. * memory area brings the memory transparently back.
  235. */
  236. virtual bool DiscardSystemPages(void* address, size_t size) { return true; }
  237. };
  238. /**
  239. * V8 Platform abstraction layer.
  240. *
  241. * The embedder has to provide an implementation of this interface before
  242. * initializing the rest of V8.
  243. */
  244. class Platform {
  245. public:
  246. virtual ~Platform() = default;
  247. /**
  248. * Allows the embedder to manage memory page allocations.
  249. */
  250. virtual PageAllocator* GetPageAllocator() {
  251. // TODO(bbudge) Make this abstract after all embedders implement this.
  252. return nullptr;
  253. }
  254. /**
  255. * Enables the embedder to respond in cases where V8 can't allocate large
  256. * blocks of memory. V8 retries the failed allocation once after calling this
  257. * method. On success, execution continues; otherwise V8 exits with a fatal
  258. * error.
  259. * Embedder overrides of this function must NOT call back into V8.
  260. */
  261. virtual void OnCriticalMemoryPressure() {
  262. // TODO(bbudge) Remove this when embedders override the following method.
  263. // See crbug.com/634547.
  264. }
  265. /**
  266. * Enables the embedder to respond in cases where V8 can't allocate large
  267. * memory regions. The |length| parameter is the amount of memory needed.
  268. * Returns true if memory is now available. Returns false if no memory could
  269. * be made available. V8 will retry allocations until this method returns
  270. * false.
  271. *
  272. * Embedder overrides of this function must NOT call back into V8.
  273. */
  274. virtual bool OnCriticalMemoryPressure(size_t length) { return false; }
  275. /**
  276. * Gets the number of worker threads used by
  277. * Call(BlockingTask)OnWorkerThread(). This can be used to estimate the number
  278. * of tasks a work package should be split into. A return value of 0 means
  279. * that there are no worker threads available. Note that a value of 0 won't
  280. * prohibit V8 from posting tasks using |CallOnWorkerThread|.
  281. */
  282. virtual int NumberOfWorkerThreads() = 0;
  283. /**
  284. * Returns a TaskRunner which can be used to post a task on the foreground.
  285. * This function should only be called from a foreground thread.
  286. */
  287. virtual std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
  288. Isolate* isolate) = 0;
  289. /**
  290. * Schedules a task to be invoked on a worker thread.
  291. */
  292. virtual void CallOnWorkerThread(std::unique_ptr<Task> task) = 0;
  293. /**
  294. * Schedules a task that blocks the main thread to be invoked with
  295. * high-priority on a worker thread.
  296. */
  297. virtual void CallBlockingTaskOnWorkerThread(std::unique_ptr<Task> task) {
  298. // Embedders may optionally override this to process these tasks in a high
  299. // priority pool.
  300. CallOnWorkerThread(std::move(task));
  301. }
  302. /**
  303. * Schedules a task to be invoked with low-priority on a worker thread.
  304. */
  305. virtual void CallLowPriorityTaskOnWorkerThread(std::unique_ptr<Task> task) {
  306. // Embedders may optionally override this to process these tasks in a low
  307. // priority pool.
  308. CallOnWorkerThread(std::move(task));
  309. }
  310. /**
  311. * Schedules a task to be invoked on a worker thread after |delay_in_seconds|
  312. * expires.
  313. */
  314. virtual void CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
  315. double delay_in_seconds) = 0;
  316. /**
  317. * Schedules a task to be invoked on a foreground thread wrt a specific
  318. * |isolate|. Tasks posted for the same isolate should be execute in order of
  319. * scheduling. The definition of "foreground" is opaque to V8.
  320. */
  321. V8_DEPRECATE_SOON(
  322. "Use a taskrunner acquired by GetForegroundTaskRunner instead.",
  323. virtual void CallOnForegroundThread(Isolate* isolate, Task* task)) = 0;
  324. /**
  325. * Schedules a task to be invoked on a foreground thread wrt a specific
  326. * |isolate| after the given number of seconds |delay_in_seconds|.
  327. * Tasks posted for the same isolate should be execute in order of
  328. * scheduling. The definition of "foreground" is opaque to V8.
  329. */
  330. V8_DEPRECATE_SOON(
  331. "Use a taskrunner acquired by GetForegroundTaskRunner instead.",
  332. virtual void CallDelayedOnForegroundThread(Isolate* isolate, Task* task,
  333. double delay_in_seconds)) = 0;
  334. /**
  335. * Schedules a task to be invoked on a foreground thread wrt a specific
  336. * |isolate| when the embedder is idle.
  337. * Requires that SupportsIdleTasks(isolate) is true.
  338. * Idle tasks may be reordered relative to other task types and may be
  339. * starved for an arbitrarily long time if no idle time is available.
  340. * The definition of "foreground" is opaque to V8.
  341. */
  342. V8_DEPRECATE_SOON(
  343. "Use a taskrunner acquired by GetForegroundTaskRunner instead.",
  344. virtual void CallIdleOnForegroundThread(Isolate* isolate,
  345. IdleTask* task)) {
  346. // This must be overriden if |IdleTasksEnabled()|.
  347. abort();
  348. }
  349. /**
  350. * Returns true if idle tasks are enabled for the given |isolate|.
  351. */
  352. virtual bool IdleTasksEnabled(Isolate* isolate) {
  353. return false;
  354. }
  355. /**
  356. * Monotonically increasing time in seconds from an arbitrary fixed point in
  357. * the past. This function is expected to return at least
  358. * millisecond-precision values. For this reason,
  359. * it is recommended that the fixed point be no further in the past than
  360. * the epoch.
  361. **/
  362. virtual double MonotonicallyIncreasingTime() = 0;
  363. /**
  364. * Current wall-clock time in milliseconds since epoch.
  365. * This function is expected to return at least millisecond-precision values.
  366. */
  367. virtual double CurrentClockTimeMillis() = 0;
  368. typedef void (*StackTracePrinter)();
  369. /**
  370. * Returns a function pointer that print a stack trace of the current stack
  371. * on invocation. Disables printing of the stack trace if nullptr.
  372. */
  373. virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }
  374. /**
  375. * Returns an instance of a v8::TracingController. This must be non-nullptr.
  376. */
  377. virtual TracingController* GetTracingController() = 0;
  378. /**
  379. * Tells the embedder to generate and upload a crashdump during an unexpected
  380. * but non-critical scenario.
  381. */
  382. virtual void DumpWithoutCrashing() {}
  383. /**
  384. * Lets the embedder to add crash keys.
  385. */
  386. virtual void AddCrashKey(int id, const char* name, uintptr_t value) {
  387. // "noop" is a valid implementation if the embedder doesn't care to log
  388. // additional data for crashes.
  389. }
  390. protected:
  391. /**
  392. * Default implementation of current wall-clock time in milliseconds
  393. * since epoch. Useful for implementing |CurrentClockTimeMillis| if
  394. * nothing special needed.
  395. */
  396. V8_EXPORT static double SystemClockTimeMillis();
  397. };
  398. } // namespace v8
  399. #endif // V8_V8_PLATFORM_H_