update windows v8 files to 7.5

This commit is contained in:
minggo 2019-07-12 09:35:04 +08:00
parent ef6c9cf1df
commit fc7fa0be28
11 changed files with 3386 additions and 2362 deletions

View File

@ -8,6 +8,7 @@
#include "libplatform/libplatform-export.h" #include "libplatform/libplatform-export.h"
#include "libplatform/v8-tracing.h" #include "libplatform/v8-tracing.h"
#include "v8-platform.h" // NOLINT(build/include) #include "v8-platform.h" // NOLINT(build/include)
#include "v8config.h" // NOLINT(build/include)
namespace v8 { namespace v8 {
namespace platform { namespace platform {
@ -30,12 +31,15 @@ enum class MessageLoopBehavior : bool {
* If |idle_task_support| is enabled then the platform will accept idle * If |idle_task_support| is enabled then the platform will accept idle
* tasks (IdleTasksEnabled will return true) and will rely on the embedder * tasks (IdleTasksEnabled will return true) and will rely on the embedder
* calling v8::platform::RunIdleTasks to process the idle tasks. * 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( V8_PLATFORM_EXPORT std::unique_ptr<v8::Platform> NewDefaultPlatform(
int thread_pool_size = 0, int thread_pool_size = 0,
IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
InProcessStackDumping in_process_stack_dumping = InProcessStackDumping in_process_stack_dumping =
InProcessStackDumping::kEnabled); InProcessStackDumping::kDisabled,
std::unique_ptr<v8::TracingController> tracing_controller = {});
/** /**
* Pumps the message loop for the given isolate. * Pumps the message loop for the given isolate.
@ -43,21 +47,18 @@ V8_PLATFORM_EXPORT v8::Platform* CreateDefaultPlatform(
* The caller has to make sure that this is called from the right thread. * The caller has to make sure that this is called from the right thread.
* Returns true if a task was executed, and false otherwise. Unless requested * Returns true if a task was executed, and false otherwise. Unless requested
* through the |behavior| parameter, this call does not block if no task is * through the |behavior| parameter, this call does not block if no task is
* pending. The |platform| has to be created using |CreateDefaultPlatform|. * pending. The |platform| has to be created using |NewDefaultPlatform|.
*/ */
V8_PLATFORM_EXPORT bool PumpMessageLoop( V8_PLATFORM_EXPORT bool PumpMessageLoop(
v8::Platform* platform, v8::Isolate* isolate, v8::Platform* platform, v8::Isolate* isolate,
MessageLoopBehavior behavior = MessageLoopBehavior::kDoNotWait); MessageLoopBehavior behavior = MessageLoopBehavior::kDoNotWait);
V8_PLATFORM_EXPORT void EnsureEventLoopInitialized(v8::Platform* platform,
v8::Isolate* isolate);
/** /**
* Runs pending idle tasks for at most |idle_time_in_seconds| seconds. * Runs pending idle tasks for at most |idle_time_in_seconds| seconds.
* *
* The caller has to make sure that this is called from the right thread. * The caller has to make sure that this is called from the right thread.
* This call does not block if no task is pending. The |platform| has to be * This call does not block if no task is pending. The |platform| has to be
* created using |CreateDefaultPlatform|. * created using |NewDefaultPlatform|.
*/ */
V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform, V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform,
v8::Isolate* isolate, v8::Isolate* isolate,
@ -66,11 +67,14 @@ V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform,
/** /**
* Attempts to set the tracing controller for the given platform. * Attempts to set the tracing controller for the given platform.
* *
* The |platform| has to be created using |CreateDefaultPlatform|. * The |platform| has to be created using |NewDefaultPlatform|.
*
*/ */
V8_PLATFORM_EXPORT void SetTracingController( V8_PLATFORM_EXPORT V8_DEPRECATE_SOON(
"Access the DefaultPlatform directly",
void SetTracingController(
v8::Platform* platform, v8::Platform* platform,
v8::platform::tracing::TracingController* tracing_controller); v8::platform::tracing::TracingController* tracing_controller));
} // namespace platform } // namespace platform
} // namespace v8 } // namespace v8

View File

@ -5,6 +5,7 @@
#ifndef V8_LIBPLATFORM_V8_TRACING_H_ #ifndef V8_LIBPLATFORM_V8_TRACING_H_
#define V8_LIBPLATFORM_V8_TRACING_H_ #define V8_LIBPLATFORM_V8_TRACING_H_
#include <atomic>
#include <fstream> #include <fstream>
#include <memory> #include <memory>
#include <unordered_set> #include <unordered_set>
@ -35,7 +36,7 @@ class V8_PLATFORM_EXPORT TraceObject {
const char* as_string; const char* as_string;
}; };
TraceObject() {} TraceObject() = default;
~TraceObject(); ~TraceObject();
void Initialize( void Initialize(
char phase, const uint8_t* category_enabled_flag, const char* name, char phase, const uint8_t* category_enabled_flag, const char* name,
@ -43,8 +44,8 @@ class V8_PLATFORM_EXPORT TraceObject {
const char** arg_names, const uint8_t* arg_types, const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values, const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables, std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags); unsigned int flags, int64_t timestamp, int64_t cpu_timestamp);
void UpdateDuration(); void UpdateDuration(int64_t timestamp, int64_t cpu_timestamp);
void InitializeForTesting( void InitializeForTesting(
char phase, const uint8_t* category_enabled_flag, const char* name, char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int num_args, const char* scope, uint64_t id, uint64_t bind_id, int num_args,
@ -106,12 +107,14 @@ class V8_PLATFORM_EXPORT TraceObject {
class V8_PLATFORM_EXPORT TraceWriter { class V8_PLATFORM_EXPORT TraceWriter {
public: public:
TraceWriter() {} TraceWriter() = default;
virtual ~TraceWriter() {} virtual ~TraceWriter() = default;
virtual void AppendTraceEvent(TraceObject* trace_event) = 0; virtual void AppendTraceEvent(TraceObject* trace_event) = 0;
virtual void Flush() = 0; virtual void Flush() = 0;
static TraceWriter* CreateJSONTraceWriter(std::ostream& stream); static TraceWriter* CreateJSONTraceWriter(std::ostream& stream);
static TraceWriter* CreateJSONTraceWriter(std::ostream& stream,
const std::string& tag);
private: private:
// Disallow copy and assign // Disallow copy and assign
@ -145,8 +148,8 @@ class V8_PLATFORM_EXPORT TraceBufferChunk {
class V8_PLATFORM_EXPORT TraceBuffer { class V8_PLATFORM_EXPORT TraceBuffer {
public: public:
TraceBuffer() {} TraceBuffer() = default;
virtual ~TraceBuffer() {} virtual ~TraceBuffer() = default;
virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0; virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0;
virtual TraceObject* GetEventByHandle(uint64_t handle) = 0; virtual TraceObject* GetEventByHandle(uint64_t handle) = 0;
@ -209,14 +212,20 @@ class V8_PLATFORM_EXPORT TraceConfig {
void operator=(const TraceConfig&) = delete; void operator=(const TraceConfig&) = delete;
}; };
class V8_PLATFORM_EXPORT TracingController { #if defined(_MSC_VER)
public: #define V8_PLATFORM_NON_EXPORTED_BASE(code) \
enum Mode { DISABLED = 0, RECORDING_MODE }; __pragma(warning(suppress : 4275)) code
#else
#define V8_PLATFORM_NON_EXPORTED_BASE(code) code
#endif // defined(_MSC_VER)
// The pointer returned from GetCategoryGroupEnabledInternal() points to a class V8_PLATFORM_EXPORT TracingController
// value with zero or more of the following bits. Used in this class only. : public V8_PLATFORM_NON_EXPORTED_BASE(v8::TracingController) {
// The TRACE_EVENT macros should only use the value as a bool. public:
// These values must be in sync with macro values in TraceEvent.h in Blink. // The pointer returned from GetCategoryGroupEnabled() points to a value with
// zero or more of the following bits. Used in this class only. The
// TRACE_EVENT macros should only use the value as a bool. These values must
// be in sync with macro values in TraceEvent.h in Blink.
enum CategoryGroupEnabledFlags { enum CategoryGroupEnabledFlags {
// Category group enabled for the recording mode. // Category group enabled for the recording mode.
ENABLED_FOR_RECORDING = 1 << 0, ENABLED_FOR_RECORDING = 1 << 0,
@ -227,42 +236,58 @@ class V8_PLATFORM_EXPORT TracingController {
}; };
TracingController(); TracingController();
~TracingController(); ~TracingController() override;
void Initialize(TraceBuffer* trace_buffer); 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( uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name, 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* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types, const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values, const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables, std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags); unsigned int flags) override;
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<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags, int64_t timestamp) override;
void UpdateTraceEventDuration(const uint8_t* category_enabled_flag, 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 StartTracing(TraceConfig* trace_config);
void StopTracing(); void StopTracing();
void AddTraceStateObserver(Platform::TraceStateObserver* observer); static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
void RemoveTraceStateObserver(Platform::TraceStateObserver* observer);
protected:
virtual int64_t CurrentTimestampMicroseconds();
virtual int64_t CurrentCpuTimestampMicroseconds();
private: private:
const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group);
void UpdateCategoryGroupEnabledFlag(size_t category_index); void UpdateCategoryGroupEnabledFlag(size_t category_index);
void UpdateCategoryGroupEnabledFlags(); void UpdateCategoryGroupEnabledFlags();
std::unique_ptr<TraceBuffer> trace_buffer_; std::unique_ptr<TraceBuffer> trace_buffer_;
std::unique_ptr<TraceConfig> trace_config_; std::unique_ptr<TraceConfig> trace_config_;
std::unique_ptr<base::Mutex> mutex_; std::unique_ptr<base::Mutex> mutex_;
std::unordered_set<Platform::TraceStateObserver*> observers_; std::unordered_set<v8::TracingController::TraceStateObserver*> observers_;
Mode mode_ = DISABLED; std::atomic_bool recording_{false};
// Disallow copy and assign // Disallow copy and assign
TracingController(const TracingController&) = delete; TracingController(const TracingController&) = delete;
void operator=(const TracingController&) = delete; void operator=(const TracingController&) = delete;
}; };
#undef V8_PLATFORM_NON_EXPORTED_BASE
} // namespace tracing } // namespace tracing
} // namespace platform } // namespace platform
} // namespace v8 } // namespace v8

View File

@ -1,255 +0,0 @@
// Copyright 2008 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_V8_DEBUG_H_
#define V8_V8_DEBUG_H_
#include "v8.h" // NOLINT(build/include)
/**
* ATTENTION: The debugger API exposed by this file is deprecated and will be
* removed by the end of 2017. Please use the V8 inspector declared
* in include/v8-inspector.h instead.
*/
namespace v8 {
// Debug events which can occur in the V8 JavaScript engine.
enum DebugEvent {
Break = 1,
Exception = 2,
AfterCompile = 3,
CompileError = 4,
AsyncTaskEvent = 5,
};
class V8_EXPORT Debug {
public:
/**
* A client object passed to the v8 debugger whose ownership will be taken by
* it. v8 is always responsible for deleting the object.
*/
class ClientData {
public:
virtual ~ClientData() {}
};
/**
* A message object passed to the debug message handler.
*/
class Message {
public:
/**
* Check type of message.
*/
virtual bool IsEvent() const = 0;
virtual bool IsResponse() const = 0;
virtual DebugEvent GetEvent() const = 0;
/**
* Indicate whether this is a response to a continue command which will
* start the VM running after this is processed.
*/
virtual bool WillStartRunning() const = 0;
/**
* Access to execution state and event data. Don't store these cross
* callbacks as their content becomes invalid. These objects are from the
* debugger event that started the debug message loop.
*/
virtual Local<Object> GetExecutionState() const = 0;
virtual Local<Object> GetEventData() const = 0;
/**
* Get the debugger protocol JSON.
*/
virtual Local<String> GetJSON() const = 0;
/**
* Get the context active when the debug event happened. Note this is not
* the current active context as the JavaScript part of the debugger is
* running in its own context which is entered at this point.
*/
virtual Local<Context> GetEventContext() const = 0;
/**
* Client data passed with the corresponding request if any. This is the
* client_data data value passed into Debug::SendCommand along with the
* request that led to the message or NULL if the message is an event. The
* debugger takes ownership of the data and will delete it even if there is
* no message handler.
*/
virtual ClientData* GetClientData() const = 0;
virtual Isolate* GetIsolate() const = 0;
virtual ~Message() {}
};
/**
* An event details object passed to the debug event listener.
*/
class EventDetails {
public:
/**
* Event type.
*/
virtual DebugEvent GetEvent() const = 0;
/**
* Access to execution state and event data of the debug event. Don't store
* these cross callbacks as their content becomes invalid.
*/
virtual Local<Object> GetExecutionState() const = 0;
virtual Local<Object> GetEventData() const = 0;
/**
* Get the context active when the debug event happened. Note this is not
* the current active context as the JavaScript part of the debugger is
* running in its own context which is entered at this point.
*/
virtual Local<Context> GetEventContext() const = 0;
/**
* Client data passed with the corresponding callback when it was
* registered.
*/
virtual Local<Value> GetCallbackData() const = 0;
/**
* This is now a dummy that returns nullptr.
*/
virtual ClientData* GetClientData() const = 0;
virtual Isolate* GetIsolate() const = 0;
virtual ~EventDetails() {}
};
/**
* Debug event callback function.
*
* \param event_details object providing information about the debug event
*
* A EventCallback does not take possession of the event data,
* and must not rely on the data persisting after the handler returns.
*/
typedef void (*EventCallback)(const EventDetails& event_details);
/**
* This is now a no-op.
*/
typedef void (*MessageHandler)(const Message& message);
V8_DEPRECATED("No longer supported", static bool SetDebugEventListener(
Isolate* isolate, EventCallback that,
Local<Value> data = Local<Value>()));
// Schedule a debugger break to happen when JavaScript code is run
// in the given isolate.
V8_DEPRECATED("No longer supported",
static void DebugBreak(Isolate* isolate));
// Remove scheduled debugger break in given isolate if it has not
// happened yet.
V8_DEPRECATED("No longer supported",
static void CancelDebugBreak(Isolate* isolate));
// Check if a debugger break is scheduled in the given isolate.
V8_DEPRECATED("No longer supported",
static bool CheckDebugBreak(Isolate* isolate));
// This is now a no-op.
V8_DEPRECATED("No longer supported",
static void SetMessageHandler(Isolate* isolate,
MessageHandler handler));
// This is now a no-op.
V8_DEPRECATED("No longer supported",
static void SendCommand(Isolate* isolate,
const uint16_t* command, int length,
ClientData* client_data = NULL));
/**
* Run a JavaScript function in the debugger.
* \param fun the function to call
* \param data passed as second argument to the function
* With this call the debugger is entered and the function specified is called
* with the execution state as the first argument. This makes it possible to
* get access to information otherwise not available during normal JavaScript
* execution e.g. details on stack frames. Receiver of the function call will
* be the debugger context global object, however this is a subject to change.
* The following example shows a JavaScript function which when passed to
* v8::Debug::Call will return the current line of JavaScript execution.
*
* \code
* function frame_source_line(exec_state) {
* return exec_state.frame(0).sourceLine();
* }
* \endcode
*/
V8_DEPRECATED("No longer supported",
static MaybeLocal<Value> Call(
Local<Context> context, v8::Local<v8::Function> fun,
Local<Value> data = Local<Value>()));
// This is now a no-op.
V8_DEPRECATED("No longer supported",
static void ProcessDebugMessages(Isolate* isolate));
/**
* Debugger is running in its own context which is entered while debugger
* messages are being dispatched. This is an explicit getter for this
* debugger context. Note that the content of the debugger context is subject
* to change. The Context exists only when the debugger is active, i.e. at
* least one DebugEventListener or MessageHandler is set.
*/
V8_DEPRECATED("Use v8-inspector",
static Local<Context> GetDebugContext(Isolate* isolate));
/**
* While in the debug context, this method returns the top-most non-debug
* context, if it exists.
*/
V8_DEPRECATED(
"No longer supported",
static MaybeLocal<Context> GetDebuggedContext(Isolate* isolate));
/**
* Enable/disable LiveEdit functionality for the given Isolate
* (default Isolate if not provided). V8 will abort if LiveEdit is
* unexpectedly used. LiveEdit is enabled by default.
*/
V8_DEPRECATED("No longer supported",
static void SetLiveEditEnabled(Isolate* isolate, bool enable));
/**
* Returns array of internal properties specific to the value type. Result has
* the following format: [<name>, <value>,...,<name>, <value>]. Result array
* will be allocated in the current context.
*/
V8_DEPRECATED("No longer supported",
static MaybeLocal<Array> GetInternalProperties(
Isolate* isolate, Local<Value> value));
/**
* Defines if the ES2015 tail call elimination feature is enabled or not.
* The change of this flag triggers deoptimization of all functions that
* contain calls at tail position.
*/
V8_DEPRECATED("No longer supported",
static bool IsTailCallEliminationEnabled(Isolate* isolate));
V8_DEPRECATED("No longer supported",
static void SetTailCallEliminationEnabled(Isolate* isolate,
bool enabled));
};
} // namespace v8
#undef EXPORT
#endif // V8_V8_DEBUG_H_

View File

@ -62,7 +62,7 @@ class V8_EXPORT StringView {
class V8_EXPORT StringBuffer { class V8_EXPORT StringBuffer {
public: public:
virtual ~StringBuffer() {} virtual ~StringBuffer() = default;
virtual const StringView& string() = 0; virtual const StringView& string() = 0;
// This method copies contents. // This method copies contents.
static std::unique_ptr<StringBuffer> create(const StringView&); static std::unique_ptr<StringBuffer> create(const StringView&);
@ -99,6 +99,7 @@ class V8_EXPORT V8ContextInfo {
class V8_EXPORT V8StackTrace { class V8_EXPORT V8StackTrace {
public: public:
virtual StringView firstNonEmptySourceURL() const = 0;
virtual bool isEmpty() const = 0; virtual bool isEmpty() const = 0;
virtual StringView topSourceURL() const = 0; virtual StringView topSourceURL() const = 0;
virtual int topLineNumber() const = 0; virtual int topLineNumber() const = 0;
@ -106,7 +107,7 @@ class V8_EXPORT V8StackTrace {
virtual StringView topScriptId() const = 0; virtual StringView topScriptId() const = 0;
virtual StringView topFunctionName() const = 0; virtual StringView topFunctionName() const = 0;
virtual ~V8StackTrace() {} virtual ~V8StackTrace() = default;
virtual std::unique_ptr<protocol::Runtime::API::StackTrace> virtual std::unique_ptr<protocol::Runtime::API::StackTrace>
buildInspectorObject() const = 0; buildInspectorObject() const = 0;
virtual std::unique_ptr<StringBuffer> toString() const = 0; virtual std::unique_ptr<StringBuffer> toString() const = 0;
@ -117,13 +118,13 @@ class V8_EXPORT V8StackTrace {
class V8_EXPORT V8InspectorSession { class V8_EXPORT V8InspectorSession {
public: public:
virtual ~V8InspectorSession() {} virtual ~V8InspectorSession() = default;
// Cross-context inspectable values (DOM nodes in different worlds, etc.). // Cross-context inspectable values (DOM nodes in different worlds, etc.).
class V8_EXPORT Inspectable { class V8_EXPORT Inspectable {
public: public:
virtual v8::Local<v8::Value> get(v8::Local<v8::Context>) = 0; virtual v8::Local<v8::Value> get(v8::Local<v8::Context>) = 0;
virtual ~Inspectable() {} virtual ~Inspectable() = default;
}; };
virtual void addInspectedObject(std::unique_ptr<Inspectable>) = 0; virtual void addInspectedObject(std::unique_ptr<Inspectable>) = 0;
@ -149,8 +150,9 @@ class V8_EXPORT V8InspectorSession {
// Remote objects. // Remote objects.
virtual std::unique_ptr<protocol::Runtime::API::RemoteObject> wrapObject( virtual std::unique_ptr<protocol::Runtime::API::RemoteObject> wrapObject(
v8::Local<v8::Context>, v8::Local<v8::Value>, v8::Local<v8::Context>, v8::Local<v8::Value>, const StringView& groupName,
const StringView& groupName) = 0; bool generatePreview) = 0;
virtual bool unwrapObject(std::unique_ptr<StringBuffer>* error, virtual bool unwrapObject(std::unique_ptr<StringBuffer>* error,
const StringView& objectId, v8::Local<v8::Value>*, const StringView& objectId, v8::Local<v8::Value>*,
v8::Local<v8::Context>*, v8::Local<v8::Context>*,
@ -160,7 +162,7 @@ class V8_EXPORT V8InspectorSession {
class V8_EXPORT V8InspectorClient { class V8_EXPORT V8InspectorClient {
public: public:
virtual ~V8InspectorClient() {} virtual ~V8InspectorClient() = default;
virtual void runMessageLoopOnPause(int contextGroupId) {} virtual void runMessageLoopOnPause(int contextGroupId) {}
virtual void quitMessageLoopOnPause() {} virtual void quitMessageLoopOnPause() {}
@ -211,17 +213,39 @@ class V8_EXPORT V8InspectorClient {
// TODO(dgozman): this was added to support service worker shadow page. We // TODO(dgozman): this was added to support service worker shadow page. We
// should not connect at all. // should not connect at all.
virtual bool canExecuteScripts(int contextGroupId) { return true; } virtual bool canExecuteScripts(int contextGroupId) { return true; }
virtual void maxAsyncCallStackDepthChanged(int depth) {}
virtual std::unique_ptr<StringBuffer> resourceNameToUrl(
const StringView& resourceName) {
return nullptr;
}
};
// These stack trace ids are intended to be passed between debuggers and be
// resolved later. This allows to track cross-debugger calls and step between
// them if a single client connects to multiple debuggers.
struct V8_EXPORT V8StackTraceId {
uintptr_t id;
std::pair<int64_t, int64_t> debugger_id;
V8StackTraceId();
V8StackTraceId(uintptr_t id, const std::pair<int64_t, int64_t> debugger_id);
~V8StackTraceId() = default;
bool IsInvalid() const;
}; };
class V8_EXPORT V8Inspector { class V8_EXPORT V8Inspector {
public: public:
static std::unique_ptr<V8Inspector> create(v8::Isolate*, V8InspectorClient*); static std::unique_ptr<V8Inspector> create(v8::Isolate*, V8InspectorClient*);
virtual ~V8Inspector() {} virtual ~V8Inspector() = default;
// Contexts instrumentation. // Contexts instrumentation.
virtual void contextCreated(const V8ContextInfo&) = 0; virtual void contextCreated(const V8ContextInfo&) = 0;
virtual void contextDestroyed(v8::Local<v8::Context>) = 0; virtual void contextDestroyed(v8::Local<v8::Context>) = 0;
virtual void resetContextGroup(int contextGroupId) = 0; virtual void resetContextGroup(int contextGroupId) = 0;
virtual v8::MaybeLocal<v8::Context> contextById(int contextId) = 0;
// Various instrumentation. // Various instrumentation.
virtual void idleStarted() = 0; virtual void idleStarted() = 0;
@ -235,6 +259,11 @@ class V8_EXPORT V8Inspector {
virtual void asyncTaskFinished(void* task) = 0; virtual void asyncTaskFinished(void* task) = 0;
virtual void allAsyncTasksCanceled() = 0; virtual void allAsyncTasksCanceled() = 0;
virtual V8StackTraceId storeCurrentStackTrace(
const StringView& description) = 0;
virtual void externalAsyncTaskStarted(const V8StackTraceId& parent) = 0;
virtual void externalAsyncTaskFinished(const V8StackTraceId& parent) = 0;
// Exceptions instrumentation. // Exceptions instrumentation.
virtual unsigned exceptionThrown( virtual unsigned exceptionThrown(
v8::Local<v8::Context>, const StringView& message, v8::Local<v8::Context>, const StringView& message,
@ -247,7 +276,7 @@ class V8_EXPORT V8Inspector {
// Connection. // Connection.
class V8_EXPORT Channel { class V8_EXPORT Channel {
public: public:
virtual ~Channel() {} virtual ~Channel() = default;
virtual void sendResponse(int callId, virtual void sendResponse(int callId,
std::unique_ptr<StringBuffer> message) = 0; std::unique_ptr<StringBuffer> message) = 0;
virtual void sendNotification(std::unique_ptr<StringBuffer> message) = 0; virtual void sendNotification(std::unique_ptr<StringBuffer> message) = 0;

View File

@ -7,9 +7,12 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> // For abort.
#include <memory> #include <memory>
#include <string> #include <string>
#include "v8config.h" // NOLINT(build/include)
namespace v8 { namespace v8 {
class Isolate; class Isolate;
@ -36,6 +39,81 @@ class IdleTask {
virtual void Run(double deadline_in_seconds) = 0; virtual void Run(double deadline_in_seconds) = 0;
}; };
/**
* A TaskRunner allows scheduling of tasks. The TaskRunner may still be used to
* post tasks after the isolate gets destructed, but these tasks may not get
* executed anymore. All tasks posted to a given TaskRunner will be invoked in
* sequence. Tasks can be posted from any thread.
*/
class TaskRunner {
public:
/**
* Schedules a task to be invoked by this TaskRunner. The TaskRunner
* implementation takes ownership of |task|.
*/
virtual void PostTask(std::unique_ptr<Task> task) = 0;
/**
* Schedules a task to be invoked by this TaskRunner. The TaskRunner
* implementation takes ownership of |task|. The |task| cannot be nested
* within other task executions.
*
* Requires that |TaskRunner::NonNestableTasksEnabled()| is true.
*/
virtual void PostNonNestableTask(std::unique_ptr<Task> task) {}
/**
* Schedules a task to be invoked by this TaskRunner. The task is scheduled
* after the given number of seconds |delay_in_seconds|. The TaskRunner
* implementation takes ownership of |task|.
*/
virtual void PostDelayedTask(std::unique_ptr<Task> task,
double delay_in_seconds) = 0;
/**
* Schedules a task to be invoked by this TaskRunner. The task is scheduled
* after the given number of seconds |delay_in_seconds|. The TaskRunner
* implementation takes ownership of |task|. The |task| cannot be nested
* within other task executions.
*
* Requires that |TaskRunner::NonNestableDelayedTasksEnabled()| is true.
*/
virtual void PostNonNestableDelayedTask(std::unique_ptr<Task> task,
double delay_in_seconds) {}
/**
* Schedules an idle task to be invoked by this TaskRunner. The task is
* scheduled when the embedder is idle. Requires that
* |TaskRunner::IdleTasksEnabled()| is true. Idle tasks may be reordered
* relative to other task types and may be starved for an arbitrarily long
* time if no idle time is available. The TaskRunner implementation takes
* ownership of |task|.
*/
virtual void PostIdleTask(std::unique_ptr<IdleTask> task) = 0;
/**
* Returns true if idle tasks are enabled for this TaskRunner.
*/
virtual bool IdleTasksEnabled() = 0;
/**
* Returns true if non-nestable tasks are enabled for this TaskRunner.
*/
virtual bool NonNestableTasksEnabled() const { return false; }
/**
* Returns true if non-nestable delayed tasks are enabled for this TaskRunner.
*/
virtual bool NonNestableDelayedTasksEnabled() const { return false; }
TaskRunner() = default;
virtual ~TaskRunner() = default;
private:
TaskRunner(const TaskRunner&) = delete;
TaskRunner& operator=(const TaskRunner&) = delete;
};
/** /**
* The interface represents complex arguments to trace events. * The interface represents complex arguments to trace events.
*/ */
@ -53,88 +131,13 @@ class ConvertableToTraceFormat {
}; };
/** /**
* V8 Platform abstraction layer. * V8 Tracing controller.
* *
* The embedder has to provide an implementation of this interface before * Can be implemented by an embedder to record trace events from V8.
* initializing the rest of V8.
*/ */
class Platform { class TracingController {
public: public:
/** virtual ~TracingController() = default;
* This enum is used to indicate whether a task is potentially long running,
* or causes a long wait. The embedder might want to use this hint to decide
* whether to execute the task on a dedicated thread.
*/
enum ExpectedRuntime {
kShortRunningTask,
kLongRunningTask
};
virtual ~Platform() = default;
/**
* Gets the number of threads that are used to execute background tasks. Is
* used to estimate the number of tasks a work package should be split into.
* A return value of 0 means that there are no background threads available.
* Note that a value of 0 won't prohibit V8 from posting tasks using
* |CallOnBackgroundThread|.
*/
virtual size_t NumberOfAvailableBackgroundThreads() { return 0; }
/**
* Schedules a task to be invoked on a background thread. |expected_runtime|
* indicates that the task will run a long time. The Platform implementation
* takes ownership of |task|. There is no guarantee about order of execution
* of tasks wrt order of scheduling, nor is there a guarantee about the
* thread the task will be run on.
*/
virtual void CallOnBackgroundThread(Task* task,
ExpectedRuntime expected_runtime) = 0;
/**
* Schedules a task to be invoked on a foreground thread wrt a specific
* |isolate|. Tasks posted for the same isolate should be execute in order of
* scheduling. The definition of "foreground" is opaque to V8.
*/
virtual void CallOnForegroundThread(Isolate* isolate, Task* task) = 0;
/**
* Schedules a task to be invoked on a foreground thread wrt a specific
* |isolate| after the given number of seconds |delay_in_seconds|.
* Tasks posted for the same isolate should be execute in order of
* scheduling. The definition of "foreground" is opaque to V8.
*/
virtual void CallDelayedOnForegroundThread(Isolate* isolate, Task* task,
double delay_in_seconds) = 0;
/**
* Schedules a task to be invoked on a foreground thread wrt a specific
* |isolate| when the embedder is idle.
* Requires that SupportsIdleTasks(isolate) is true.
* Idle tasks may be reordered relative to other task types and may be
* starved for an arbitrarily long time if no idle time is available.
* The definition of "foreground" is opaque to V8.
*/
virtual void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) {
// TODO(ulan): Make this function abstract after V8 roll in Chromium.
}
/**
* Returns true if idle tasks are enabled for the given |isolate|.
*/
virtual bool IdleTasksEnabled(Isolate* isolate) {
// TODO(ulan): Make this function abstract after V8 roll in Chromium.
return false;
}
/**
* Monotonically increasing time in seconds from an arbitrary fixed point in
* the past. This function is expected to return at least
* millisecond-precision values. For this reason,
* it is recommended that the fixed point be no further in the past than
* the epoch.
**/
virtual double MonotonicallyIncreasingTime() = 0;
/** /**
* Called by TRACE_EVENT* macros, don't call this directly. * Called by TRACE_EVENT* macros, don't call this directly.
@ -149,37 +152,11 @@ class Platform {
} }
/** /**
* Gets the category group name of the given category_enabled_flag pointer. * Adds a trace event to the platform tracing system. These function calls are
* Usually used while serliazing TRACE_EVENTs.
**/
virtual const char* GetCategoryGroupName(
const uint8_t* category_enabled_flag) {
static const char dummy[] = "dummy";
return dummy;
}
/**
* 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 * 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 * 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 * advisable to call these functions on their own; they are really only meant
* used by the trace macros. The returned handle can be used by * 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, unsigned int flags) {
return 0;
}
/**
* 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. * UpdateTraceEventDuration to update the duration of COMPLETE events.
*/ */
virtual uint64_t AddTraceEvent( virtual uint64_t AddTraceEvent(
@ -189,8 +166,16 @@ class Platform {
const uint64_t* arg_values, const uint64_t* arg_values,
std::unique_ptr<ConvertableToTraceFormat>* arg_convertables, std::unique_ptr<ConvertableToTraceFormat>* arg_convertables,
unsigned int flags) { unsigned int flags) {
return AddTraceEvent(phase, category_enabled_flag, name, scope, id, bind_id, return 0;
num_args, arg_names, arg_types, arg_values, flags); }
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) {
return 0;
} }
/** /**
@ -212,6 +197,229 @@ class Platform {
/** Removes tracing state change observer. */ /** Removes tracing state change observer. */
virtual void RemoveTraceStateObserver(TraceStateObserver*) {} virtual void RemoveTraceStateObserver(TraceStateObserver*) {}
};
/**
* A V8 memory page allocator.
*
* Can be implemented by an embedder to manage large host OS allocations.
*/
class PageAllocator {
public:
virtual ~PageAllocator() = default;
/**
* Gets the page granularity for AllocatePages and FreePages. Addresses and
* lengths for those calls should be multiples of AllocatePageSize().
*/
virtual size_t AllocatePageSize() = 0;
/**
* Gets the page granularity for SetPermissions and ReleasePages. Addresses
* and lengths for those calls should be multiples of CommitPageSize().
*/
virtual size_t CommitPageSize() = 0;
/**
* Sets the random seed so that GetRandomMmapAddr() will generate repeatable
* sequences of random mmap addresses.
*/
virtual void SetRandomMmapSeed(int64_t seed) = 0;
/**
* Returns a randomized address, suitable for memory allocation under ASLR.
* The address will be aligned to AllocatePageSize.
*/
virtual void* GetRandomMmapAddr() = 0;
/**
* Memory permissions.
*/
enum Permission {
kNoAccess,
kRead,
kReadWrite,
// TODO(hpayer): Remove this flag. Memory should never be rwx.
kReadWriteExecute,
kReadExecute
};
/**
* Allocates memory in range with the given alignment and permission.
*/
virtual void* AllocatePages(void* address, size_t length, size_t alignment,
Permission permissions) = 0;
/**
* Frees memory in a range that was allocated by a call to AllocatePages.
*/
virtual bool FreePages(void* address, size_t length) = 0;
/**
* Releases memory in a range that was allocated by a call to AllocatePages.
*/
virtual bool ReleasePages(void* address, size_t length,
size_t new_length) = 0;
/**
* Sets permissions on pages in an allocated range.
*/
virtual bool SetPermissions(void* address, size_t length,
Permission permissions) = 0;
/**
* Frees memory in the given [address, address + size) range. address and size
* should be operating system page-aligned. The next write to this
* memory area brings the memory transparently back.
*/
virtual bool DiscardSystemPages(void* address, size_t size) { return true; }
};
/**
* V8 Platform abstraction layer.
*
* The embedder has to provide an implementation of this interface before
* initializing the rest of V8.
*/
class Platform {
public:
virtual ~Platform() = default;
/**
* Allows the embedder to manage memory page allocations.
*/
virtual PageAllocator* GetPageAllocator() {
// TODO(bbudge) Make this abstract after all embedders implement this.
return nullptr;
}
/**
* Enables the embedder to respond in cases where V8 can't allocate large
* blocks of memory. V8 retries the failed allocation once after calling this
* method. On success, execution continues; otherwise V8 exits with a fatal
* error.
* Embedder overrides of this function must NOT call back into V8.
*/
virtual void OnCriticalMemoryPressure() {
// TODO(bbudge) Remove this when embedders override the following method.
// See crbug.com/634547.
}
/**
* Enables the embedder to respond in cases where V8 can't allocate large
* memory regions. The |length| parameter is the amount of memory needed.
* Returns true if memory is now available. Returns false if no memory could
* be made available. V8 will retry allocations until this method returns
* false.
*
* Embedder overrides of this function must NOT call back into V8.
*/
virtual bool OnCriticalMemoryPressure(size_t length) { return false; }
/**
* Gets the number of worker threads used by
* Call(BlockingTask)OnWorkerThread(). This can be used to estimate the number
* of tasks a work package should be split into. A return value of 0 means
* that there are no worker threads available. Note that a value of 0 won't
* prohibit V8 from posting tasks using |CallOnWorkerThread|.
*/
virtual int NumberOfWorkerThreads() = 0;
/**
* Returns a TaskRunner which can be used to post a task on the foreground.
* This function should only be called from a foreground thread.
*/
virtual std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
Isolate* isolate) = 0;
/**
* Schedules a task to be invoked on a worker thread.
*/
virtual void CallOnWorkerThread(std::unique_ptr<Task> task) = 0;
/**
* Schedules a task that blocks the main thread to be invoked with
* high-priority on a worker thread.
*/
virtual void CallBlockingTaskOnWorkerThread(std::unique_ptr<Task> task) {
// Embedders may optionally override this to process these tasks in a high
// priority pool.
CallOnWorkerThread(std::move(task));
}
/**
* Schedules a task to be invoked with low-priority on a worker thread.
*/
virtual void CallLowPriorityTaskOnWorkerThread(std::unique_ptr<Task> task) {
// Embedders may optionally override this to process these tasks in a low
// priority pool.
CallOnWorkerThread(std::move(task));
}
/**
* Schedules a task to be invoked on a worker thread after |delay_in_seconds|
* expires.
*/
virtual void CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
double delay_in_seconds) = 0;
/**
* Schedules a task to be invoked on a foreground thread wrt a specific
* |isolate|. Tasks posted for the same isolate should be execute in order of
* scheduling. The definition of "foreground" is opaque to V8.
*/
V8_DEPRECATE_SOON(
"Use a taskrunner acquired by GetForegroundTaskRunner instead.",
virtual void CallOnForegroundThread(Isolate* isolate, Task* task)) = 0;
/**
* Schedules a task to be invoked on a foreground thread wrt a specific
* |isolate| after the given number of seconds |delay_in_seconds|.
* Tasks posted for the same isolate should be execute in order of
* scheduling. The definition of "foreground" is opaque to V8.
*/
V8_DEPRECATE_SOON(
"Use a taskrunner acquired by GetForegroundTaskRunner instead.",
virtual void CallDelayedOnForegroundThread(Isolate* isolate, Task* task,
double delay_in_seconds)) = 0;
/**
* Schedules a task to be invoked on a foreground thread wrt a specific
* |isolate| when the embedder is idle.
* Requires that SupportsIdleTasks(isolate) is true.
* Idle tasks may be reordered relative to other task types and may be
* starved for an arbitrarily long time if no idle time is available.
* The definition of "foreground" is opaque to V8.
*/
V8_DEPRECATE_SOON(
"Use a taskrunner acquired by GetForegroundTaskRunner instead.",
virtual void CallIdleOnForegroundThread(Isolate* isolate,
IdleTask* task)) {
// This must be overriden if |IdleTasksEnabled()|.
abort();
}
/**
* Returns true if idle tasks are enabled for the given |isolate|.
*/
virtual bool IdleTasksEnabled(Isolate* isolate) {
return false;
}
/**
* Monotonically increasing time in seconds from an arbitrary fixed point in
* the past. This function is expected to return at least
* millisecond-precision values. For this reason,
* it is recommended that the fixed point be no further in the past than
* the epoch.
**/
virtual double MonotonicallyIncreasingTime() = 0;
/**
* Current wall-clock time in milliseconds since epoch.
* This function is expected to return at least millisecond-precision values.
*/
virtual double CurrentClockTimeMillis() = 0;
typedef void (*StackTracePrinter)(); typedef void (*StackTracePrinter)();
@ -220,6 +428,25 @@ class Platform {
* on invocation. Disables printing of the stack trace if nullptr. * on invocation. Disables printing of the stack trace if nullptr.
*/ */
virtual StackTracePrinter GetStackTracePrinter() { return nullptr; } virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }
/**
* Returns an instance of a v8::TracingController. This must be non-nullptr.
*/
virtual TracingController* GetTracingController() = 0;
/**
* Tells the embedder to generate and upload a crashdump during an unexpected
* but non-critical scenario.
*/
virtual void DumpWithoutCrashing() {}
protected:
/**
* Default implementation of current wall-clock time in milliseconds
* since epoch. Useful for implementing |CurrentClockTimeMillis| if
* nothing special needed.
*/
V8_EXPORT static double SystemClockTimeMillis();
}; };
} // namespace v8 } // namespace v8

View File

@ -47,22 +47,8 @@ template class V8_EXPORT std::vector<v8::CpuProfileDeoptInfo>;
namespace v8 { namespace v8 {
/**
* TracingCpuProfiler monitors tracing being enabled/disabled
* and emits CpuProfile trace events once v8.cpu_profiler tracing category
* is enabled. It has no overhead unless the category is enabled.
*/
class V8_EXPORT TracingCpuProfiler {
public:
static std::unique_ptr<TracingCpuProfiler> Create(Isolate*);
virtual ~TracingCpuProfiler() = default;
protected:
TracingCpuProfiler() = default;
};
// TickSample captures the information collected for each sample. // TickSample captures the information collected for each sample.
struct TickSample { struct V8_EXPORT TickSample {
// Internal profiling (with --prof + tools/$OS-tick-processor) wants to // Internal profiling (with --prof + tools/$OS-tick-processor) wants to
// include the runtime function we're calling. Externally exposed tick // include the runtime function we're calling. Externally exposed tick
// samples don't care. // samples don't care.
@ -143,6 +129,20 @@ class V8_EXPORT CpuProfileNode {
unsigned int hit_count; unsigned int hit_count;
}; };
// An annotation hinting at the source of a CpuProfileNode.
enum SourceType {
// User-supplied script with associated resource information.
kScript = 0,
// Native scripts and provided builtins.
kBuiltin = 1,
// Callbacks into native code.
kCallback = 2,
// VM-internal functions or state.
kInternal = 3,
// A node that failed to symbolize.
kUnresolved = 4,
};
/** Returns function name (empty string for anonymous functions.) */ /** Returns function name (empty string for anonymous functions.) */
Local<String> GetFunctionName() const; Local<String> GetFunctionName() const;
@ -166,6 +166,12 @@ class V8_EXPORT CpuProfileNode {
*/ */
const char* GetScriptResourceNameStr() const; const char* GetScriptResourceNameStr() const;
/**
* Return true if the script from where the function originates is flagged as
* being shared cross-origin.
*/
bool IsScriptSharedCrossOrigin() const;
/** /**
* Returns the number, 1-based, of the line where the function originates. * Returns the number, 1-based, of the line where the function originates.
* kNoLineNumberInfo if no line number information is available. * kNoLineNumberInfo if no line number information is available.
@ -208,12 +214,20 @@ class V8_EXPORT CpuProfileNode {
/** Returns id of the node. The id is unique within the tree */ /** Returns id of the node. The id is unique within the tree */
unsigned GetNodeId() const; unsigned GetNodeId() const;
/**
* Gets the type of the source which the node was captured from.
*/
SourceType GetSourceType() const;
/** Returns child nodes count of the node. */ /** Returns child nodes count of the node. */
int GetChildrenCount() const; int GetChildrenCount() const;
/** Retrieves a child node by index. */ /** Retrieves a child node by index. */
const CpuProfileNode* GetChild(int index) const; const CpuProfileNode* GetChild(int index) const;
/** Retrieves the ancestor node, or null if the root. */
const CpuProfileNode* GetParent() const;
/** Retrieves deopt infos for the node. */ /** Retrieves deopt infos for the node. */
const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const; const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const;
@ -273,6 +287,16 @@ class V8_EXPORT CpuProfile {
void Delete(); void Delete();
}; };
enum CpuProfilingMode {
// In the resulting CpuProfile tree, intermediate nodes in a stack trace
// (from the root to a leaf) will have line numbers that point to the start
// line of the function, rather than the line of the callsite of the child.
kLeafNodeLineNumbers,
// In the resulting CpuProfile tree, nodes are separated based on the line
// number of their callsite in their parent.
kCallerLineNumbers,
};
/** /**
* Interface for controlling CPU profiling. Instance of the * Interface for controlling CPU profiling. Instance of the
* profiler can be created using v8::CpuProfiler::New method. * profiler can be created using v8::CpuProfiler::New method.
@ -286,6 +310,13 @@ class V8_EXPORT CpuProfiler {
*/ */
static CpuProfiler* New(Isolate* isolate); static CpuProfiler* New(Isolate* isolate);
/**
* Synchronously collect current stack sample in all profilers attached to
* the |isolate|. The call does not affect number of ticks recorded for
* the current top node.
*/
static void CollectSample(Isolate* isolate);
/** /**
* Disposes the CPU profiler object. * Disposes the CPU profiler object.
*/ */
@ -298,6 +329,15 @@ class V8_EXPORT CpuProfiler {
*/ */
void SetSamplingInterval(int us); void SetSamplingInterval(int us);
/**
* Sets whether or not the profiler should prioritize consistency of sample
* periodicity on Windows. Disabling this can greatly reduce CPU usage, but
* may result in greater variance in sample timings from the platform's
* scheduler. Defaults to enabled. This method must be called when there are
* no profiles being recorded.
*/
void SetUsePreciseSampling(bool);
/** /**
* Starts collecting CPU profile. Title may be an empty string. It * Starts collecting CPU profile. Title may be an empty string. It
* is allowed to have several profiles being collected at * is allowed to have several profiles being collected at
@ -309,6 +349,13 @@ class V8_EXPORT CpuProfiler {
* |record_samples| parameter controls whether individual samples should * |record_samples| parameter controls whether individual samples should
* be recorded in addition to the aggregated tree. * be recorded in addition to the aggregated tree.
*/ */
void StartProfiling(Local<String> title, CpuProfilingMode mode,
bool record_samples = false);
/**
* The same as StartProfiling above, but the CpuProfilingMode defaults to
* kLeafNodeLineNumbers mode, which was the previous default behavior of the
* profiler.
*/
void StartProfiling(Local<String> title, bool record_samples = false); void StartProfiling(Local<String> title, bool record_samples = false);
/** /**
@ -322,12 +369,20 @@ class V8_EXPORT CpuProfiler {
* Recording the forced sample does not contribute to the aggregated * Recording the forced sample does not contribute to the aggregated
* profile statistics. * profile statistics.
*/ */
void CollectSample(); V8_DEPRECATED("Use static CollectSample(Isolate*) instead.",
void CollectSample());
/** /**
* Tells the profiler whether the embedder is idle. * Tells the profiler whether the embedder is idle.
*/ */
void SetIdle(bool is_idle); V8_DEPRECATED("Use Isolate::SetIdle(bool) instead.",
void SetIdle(bool is_idle));
/**
* Generate more detailed source positions to code objects. This results in
* better results when mapping profiling samples to script source.
*/
static void UseDetailedSourcePositionsForProfiling(Isolate* isolate);
private: private:
CpuProfiler(); CpuProfiler();
@ -389,11 +444,12 @@ class V8_EXPORT HeapGraphNode {
kRegExp = 6, // RegExp. kRegExp = 6, // RegExp.
kHeapNumber = 7, // Number stored in the heap. kHeapNumber = 7, // Number stored in the heap.
kNative = 8, // Native object (not from V8 heap). kNative = 8, // Native object (not from V8 heap).
kSynthetic = 9, // Synthetic object, usualy used for grouping kSynthetic = 9, // Synthetic object, usually used for grouping
// snapshot items together. // snapshot items together.
kConsString = 10, // Concatenated string. A pair of pointers to strings. kConsString = 10, // Concatenated string. A pair of pointers to strings.
kSlicedString = 11, // Sliced string. A fragment of another string. kSlicedString = 11, // Sliced string. A fragment of another string.
kSymbol = 12 // A Symbol (ES6). kSymbol = 12, // A Symbol (ES6).
kBigInt = 13 // BigInt.
}; };
/** Returns node type (see HeapGraphNode::Type). */ /** Returns node type (see HeapGraphNode::Type). */
@ -432,7 +488,7 @@ class V8_EXPORT OutputStream { // NOLINT
kContinue = 0, kContinue = 0,
kAbort = 1 kAbort = 1
}; };
virtual ~OutputStream() {} virtual ~OutputStream() = default;
/** Notify about the end of stream. */ /** Notify about the end of stream. */
virtual void EndOfStream() = 0; virtual void EndOfStream() = 0;
/** Get preferred output chunk size. Called only once. */ /** Get preferred output chunk size. Called only once. */
@ -526,7 +582,7 @@ class V8_EXPORT ActivityControl { // NOLINT
kContinue = 0, kContinue = 0,
kAbort = 1 kAbort = 1
}; };
virtual ~ActivityControl() {} virtual ~ActivityControl() = default;
/** /**
* Notify about current progress. The activity can be stopped by * Notify about current progress. The activity can be stopped by
* returning kAbort as the callback result. * returning kAbort as the callback result.
@ -592,6 +648,11 @@ class V8_EXPORT AllocationProfile {
*/ */
int column_number; int column_number;
/**
* Unique id of the node.
*/
uint32_t node_id;
/** /**
* List of callees called from this node for which we have sampled * List of callees called from this node for which we have sampled
* allocations. The lifetime of the children is scoped to the containing * allocations. The lifetime of the children is scoped to the containing
@ -605,19 +666,111 @@ class V8_EXPORT AllocationProfile {
std::vector<Allocation> allocations; std::vector<Allocation> allocations;
}; };
/**
* Represent a single sample recorded for an allocation.
*/
struct Sample {
/**
* id of the node in the profile tree.
*/
uint32_t node_id;
/**
* Size of the sampled allocation object.
*/
size_t size;
/**
* The number of objects of such size that were sampled.
*/
unsigned int count;
/**
* Unique time-ordered id of the allocation sample. Can be used to track
* what samples were added or removed between two snapshots.
*/
uint64_t sample_id;
};
/** /**
* Returns the root node of the call-graph. The root node corresponds to an * Returns the root node of the call-graph. The root node corresponds to an
* empty JS call-stack. The lifetime of the returned Node* is scoped to the * empty JS call-stack. The lifetime of the returned Node* is scoped to the
* containing AllocationProfile. * containing AllocationProfile.
*/ */
virtual Node* GetRootNode() = 0; virtual Node* GetRootNode() = 0;
virtual const std::vector<Sample>& GetSamples() = 0;
virtual ~AllocationProfile() {} virtual ~AllocationProfile() = default;
static const int kNoLineNumberInfo = Message::kNoLineNumberInfo; static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
static const int kNoColumnNumberInfo = Message::kNoColumnInfo; static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
}; };
/**
* An object graph consisting of embedder objects and V8 objects.
* Edges of the graph are strong references between the objects.
* The embedder can build this graph during heap snapshot generation
* to include the embedder objects in the heap snapshot.
* Usage:
* 1) Define derived class of EmbedderGraph::Node for embedder objects.
* 2) Set the build embedder graph callback on the heap profiler using
* HeapProfiler::AddBuildEmbedderGraphCallback.
* 3) In the callback use graph->AddEdge(node1, node2) to add an edge from
* node1 to node2.
* 4) To represent references from/to V8 object, construct V8 nodes using
* graph->V8Node(value).
*/
class V8_EXPORT EmbedderGraph {
public:
class Node {
public:
Node() = default;
virtual ~Node() = default;
virtual const char* Name() = 0;
virtual size_t SizeInBytes() = 0;
/**
* The corresponding V8 wrapper node if not null.
* During heap snapshot generation the embedder node and the V8 wrapper
* node will be merged into one node to simplify retaining paths.
*/
virtual Node* WrapperNode() { return nullptr; }
virtual bool IsRootNode() { return false; }
/** Must return true for non-V8 nodes. */
virtual bool IsEmbedderNode() { return true; }
/**
* Optional name prefix. It is used in Chrome for tagging detached nodes.
*/
virtual const char* NamePrefix() { return nullptr; }
private:
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
};
/**
* Returns a node corresponding to the given V8 value. Ownership is not
* transferred. The result pointer is valid while the graph is alive.
*/
virtual Node* V8Node(const v8::Local<v8::Value>& value) = 0;
/**
* Adds the given node to the graph and takes ownership of the node.
* Returns a raw pointer to the node that is valid while the graph is alive.
*/
virtual Node* AddNode(std::unique_ptr<Node> node) = 0;
/**
* Adds an edge that represents a strong reference from the given
* node |from| to the given node |to|. The nodes must be added to the graph
* before calling this function.
*
* If name is nullptr, the edge will have auto-increment indexes, otherwise
* it will be named accordingly.
*/
virtual void AddEdge(Node* from, Node* to, const char* name = nullptr) = 0;
virtual ~EmbedderGraph() = default;
};
/** /**
* Interface for controlling heap profiling. Instance of the * Interface for controlling heap profiling. Instance of the
@ -630,32 +783,15 @@ class V8_EXPORT HeapProfiler {
kSamplingForceGC = 1 << 0, kSamplingForceGC = 1 << 0,
}; };
typedef std::unordered_set<const v8::PersistentBase<v8::Value>*>
RetainerChildren;
typedef std::vector<std::pair<v8::RetainedObjectInfo*, RetainerChildren>>
RetainerGroups;
typedef std::vector<std::pair<const v8::PersistentBase<v8::Value>*,
const v8::PersistentBase<v8::Value>*>>
RetainerEdges;
struct RetainerInfos {
RetainerGroups groups;
RetainerEdges edges;
};
/** /**
* Callback function invoked to retrieve all RetainerInfos from the embedder. * Callback function invoked during heap snapshot generation to retrieve
* the embedder object graph. The callback should use graph->AddEdge(..) to
* add references between the objects.
* The callback must not trigger garbage collection in V8.
*/ */
typedef RetainerInfos (*GetRetainerInfosCallback)(v8::Isolate* isolate); typedef void (*BuildEmbedderGraphCallback)(v8::Isolate* isolate,
v8::EmbedderGraph* graph,
/** void* data);
* Callback function invoked for obtaining RetainedObjectInfo for
* the given JavaScript wrapper object. It is prohibited to enter V8
* while the callback is running: only getters on the handle and
* GetPointerFromInternalField on the objects are allowed.
*/
typedef RetainedObjectInfo* (*WrapperInfoCallback)(uint16_t class_id,
Local<Value> wrapper);
/** Returns the number of snapshots taken. */ /** Returns the number of snapshots taken. */
int GetSnapshotCount(); int GetSnapshotCount();
@ -701,15 +837,15 @@ class V8_EXPORT HeapProfiler {
virtual const char* GetName(Local<Object> object) = 0; virtual const char* GetName(Local<Object> object) = 0;
protected: protected:
virtual ~ObjectNameResolver() {} virtual ~ObjectNameResolver() = default;
}; };
/** /**
* Takes a heap snapshot and returns it. * Takes a heap snapshot and returns it.
*/ */
const HeapSnapshot* TakeHeapSnapshot( const HeapSnapshot* TakeHeapSnapshot(
ActivityControl* control = NULL, ActivityControl* control = nullptr,
ObjectNameResolver* global_object_name_resolver = NULL); ObjectNameResolver* global_object_name_resolver = nullptr);
/** /**
* Starts tracking of heap objects population statistics. After calling * Starts tracking of heap objects population statistics. After calling
@ -736,7 +872,7 @@ class V8_EXPORT HeapProfiler {
* method. * method.
*/ */
SnapshotObjectId GetHeapStats(OutputStream* stream, SnapshotObjectId GetHeapStats(OutputStream* stream,
int64_t* timestamp_us = NULL); int64_t* timestamp_us = nullptr);
/** /**
* Stops tracking of heap objects population statistics, cleans up all * Stops tracking of heap objects population statistics, cleans up all
@ -784,7 +920,7 @@ class V8_EXPORT HeapProfiler {
/** /**
* Returns the sampled profile of allocations allocated (and still live) since * Returns the sampled profile of allocations allocated (and still live) since
* StartSamplingHeapProfiler was called. The ownership of the pointer is * StartSamplingHeapProfiler was called. The ownership of the pointer is
* transfered to the caller. Returns nullptr if sampling heap profiler is not * transferred to the caller. Returns nullptr if sampling heap profiler is not
* active. * active.
*/ */
AllocationProfile* GetAllocationProfile(); AllocationProfile* GetAllocationProfile();
@ -795,12 +931,10 @@ class V8_EXPORT HeapProfiler {
*/ */
void DeleteAllHeapSnapshots(); void DeleteAllHeapSnapshots();
/** Binds a callback to embedder's class ID. */ void AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,
void SetWrapperClassInfoProvider( void* data);
uint16_t class_id, void RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,
WrapperInfoCallback callback); void* data);
void SetGetRetainerInfosCallback(GetRetainerInfosCallback callback);
/** /**
* Default value of persistent handle class ID. Must not be used to * Default value of persistent handle class ID. Must not be used to
@ -809,9 +943,6 @@ class V8_EXPORT HeapProfiler {
*/ */
static const uint16_t kPersistentHandleNoClassId = 0; static const uint16_t kPersistentHandleNoClassId = 0;
/** Returns memory used for profiler internal data and snapshots. */
size_t GetProfilerMemorySize();
private: private:
HeapProfiler(); HeapProfiler();
~HeapProfiler(); ~HeapProfiler();
@ -819,80 +950,6 @@ class V8_EXPORT HeapProfiler {
HeapProfiler& operator=(const HeapProfiler&); HeapProfiler& operator=(const HeapProfiler&);
}; };
/**
* Interface for providing information about embedder's objects
* held by global handles. This information is reported in two ways:
*
* 1. When calling AddObjectGroup, an embedder may pass
* RetainedObjectInfo instance describing the group. To collect
* this information while taking a heap snapshot, V8 calls GC
* prologue and epilogue callbacks.
*
* 2. When a heap snapshot is collected, V8 additionally
* requests RetainedObjectInfos for persistent handles that
* were not previously reported via AddObjectGroup.
*
* Thus, if an embedder wants to provide information about native
* objects for heap snapshots, it can do it in a GC prologue
* handler, and / or by assigning wrapper class ids in the following way:
*
* 1. Bind a callback to class id by calling SetWrapperClassInfoProvider.
* 2. Call SetWrapperClassId on certain persistent handles.
*
* V8 takes ownership of RetainedObjectInfo instances passed to it and
* keeps them alive only during snapshot collection. Afterwards, they
* are freed by calling the Dispose class function.
*/
class V8_EXPORT RetainedObjectInfo { // NOLINT
public:
/** Called by V8 when it no longer needs an instance. */
virtual void Dispose() = 0;
/** Returns whether two instances are equivalent. */
virtual bool IsEquivalent(RetainedObjectInfo* other) = 0;
/**
* Returns hash value for the instance. Equivalent instances
* must have the same hash value.
*/
virtual intptr_t GetHash() = 0;
/**
* Returns human-readable label. It must be a null-terminated UTF-8
* encoded string. V8 copies its contents during a call to GetLabel.
*/
virtual const char* GetLabel() = 0;
/**
* Returns human-readable group label. It must be a null-terminated UTF-8
* encoded string. V8 copies its contents during a call to GetGroupLabel.
* Heap snapshot generator will collect all the group names, create
* top level entries with these names and attach the objects to the
* corresponding top level group objects. There is a default
* implementation which is required because embedders don't have their
* own implementation yet.
*/
virtual const char* GetGroupLabel() { return GetLabel(); }
/**
* Returns element count in case if a global handle retains
* a subgraph by holding one of its nodes.
*/
virtual intptr_t GetElementCount() { return -1; }
/** Returns embedder's object size in bytes. */
virtual intptr_t GetSizeInBytes() { return -1; }
protected:
RetainedObjectInfo() {}
virtual ~RetainedObjectInfo() {}
private:
RetainedObjectInfo(const RetainedObjectInfo&);
RetainedObjectInfo& operator=(const RetainedObjectInfo&);
};
/** /**
* A struct for exporting HeapStats data from V8, using "push" model. * A struct for exporting HeapStats data from V8, using "push" model.
* See HeapProfiler::GetHeapStats. * See HeapProfiler::GetHeapStats.
@ -905,6 +962,76 @@ struct HeapStatsUpdate {
uint32_t size; // New value of size field for the interval with this index. uint32_t size; // New value of size field for the interval with this index.
}; };
#define CODE_EVENTS_LIST(V) \
V(Builtin) \
V(Callback) \
V(Eval) \
V(Function) \
V(InterpretedFunction) \
V(Handler) \
V(BytecodeHandler) \
V(LazyCompile) \
V(RegExp) \
V(Script) \
V(Stub)
/**
* Note that this enum may be extended in the future. Please include a default
* case if this enum is used in a switch statement.
*/
enum CodeEventType {
kUnknownType = 0
#define V(Name) , k##Name##Type
CODE_EVENTS_LIST(V)
#undef V
};
/**
* Representation of a code creation event
*/
class V8_EXPORT CodeEvent {
public:
uintptr_t GetCodeStartAddress();
size_t GetCodeSize();
Local<String> GetFunctionName();
Local<String> GetScriptName();
int GetScriptLine();
int GetScriptColumn();
/**
* NOTE (mmarchini): We can't allocate objects in the heap when we collect
* existing code, and both the code type and the comment are not stored in the
* heap, so we return those as const char*.
*/
CodeEventType GetCodeType();
const char* GetComment();
static const char* GetCodeEventTypeName(CodeEventType code_event_type);
};
/**
* Interface to listen to code creation events.
*/
class V8_EXPORT CodeEventHandler {
public:
/**
* Creates a new listener for the |isolate|. The isolate must be initialized.
* The listener object must be disposed after use by calling |Dispose| method.
* Multiple listeners can be created for the same isolate.
*/
explicit CodeEventHandler(Isolate* isolate);
virtual ~CodeEventHandler();
virtual void Handle(CodeEvent* code_event) = 0;
void Enable();
void Disable();
private:
CodeEventHandler();
CodeEventHandler(const CodeEventHandler&);
CodeEventHandler& operator=(const CodeEventHandler&);
void* internal_listener_;
};
} // namespace v8 } // namespace v8

View File

@ -25,13 +25,11 @@ enum PersistentContainerCallbackType {
kNotWeak, kNotWeak,
// These correspond to v8::WeakCallbackType // These correspond to v8::WeakCallbackType
kWeakWithParameter, kWeakWithParameter,
kWeakWithInternalFields, kWeakWithInternalFields
kWeak = kWeakWithParameter // For backwards compatibility. Deprecate.
}; };
/** /**
* A default trait implemenation for PersistentValueMap which uses std::map * A default trait implementation for PersistentValueMap which uses std::map
* as a backing map. * as a backing map.
* *
* Users will have to implement their own weak callbacks & dispose traits. * Users will have to implement their own weak callbacks & dispose traits.
@ -94,11 +92,11 @@ class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
static WeakCallbackDataType* WeakCallbackParameter( static WeakCallbackDataType* WeakCallbackParameter(
MapType* map, const K& key, Local<V> value) { MapType* map, const K& key, Local<V> value) {
return NULL; return nullptr;
} }
static MapType* MapFromWeakCallbackInfo( static MapType* MapFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) { const WeakCallbackInfo<WeakCallbackDataType>& data) {
return NULL; return nullptr;
} }
static K KeyFromWeakCallbackInfo( static K KeyFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) { const WeakCallbackInfo<WeakCallbackDataType>& data) {
@ -196,26 +194,13 @@ class PersistentValueMapBase {
return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key)); return SetReturnValueFromVal(&returnValue, Traits::Get(&impl_, key));
} }
/**
* Call Isolate::SetReference with the given parent and the map value.
*/
void SetReference(const K& key,
const Persistent<Object>& parent) {
GetIsolate()->SetReference(
reinterpret_cast<internal::Object**>(parent.val_),
reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))));
}
/** /**
* Call V8::RegisterExternallyReferencedObject with the map value for given * Call V8::RegisterExternallyReferencedObject with the map value for given
* key. * key.
*/ */
void RegisterExternallyReferencedObject(K& key) { V8_DEPRECATED(
assert(Contains(key)); "Used TracedGlobal and EmbedderHeapTracer::RegisterEmbedderReference",
V8::RegisterExternallyReferencedObject( inline void RegisterExternallyReferencedObject(K& key));
reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))),
reinterpret_cast<internal::Isolate*>(GetIsolate()));
}
/** /**
* Return value for key and remove it from the map. * Return value for key and remove it from the map.
@ -299,7 +284,10 @@ class PersistentValueMapBase {
} }
protected: protected:
explicit PersistentValueMapBase(Isolate* isolate) : isolate_(isolate) {} explicit PersistentValueMapBase(Isolate* isolate)
: isolate_(isolate), label_(nullptr) {}
PersistentValueMapBase(Isolate* isolate, const char* label)
: isolate_(isolate), label_(label) {}
~PersistentValueMapBase() { Clear(); } ~PersistentValueMapBase() { Clear(); }
@ -312,7 +300,7 @@ class PersistentValueMapBase {
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) { static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
V* v = persistent->val_; V* v = persistent->val_;
persistent->val_ = 0; persistent->val_ = nullptr;
return reinterpret_cast<PersistentContainerValue>(v); return reinterpret_cast<PersistentContainerValue>(v);
} }
@ -341,6 +329,10 @@ class PersistentValueMapBase {
p.Reset(); p.Reset();
} }
void AnnotateStrongRetainer(Global<V>* persistent) {
persistent->AnnotateStrongRetainer(label_);
}
private: private:
PersistentValueMapBase(PersistentValueMapBase&); PersistentValueMapBase(PersistentValueMapBase&);
void operator=(PersistentValueMapBase&); void operator=(PersistentValueMapBase&);
@ -350,21 +342,33 @@ class PersistentValueMapBase {
bool hasValue = value != kPersistentContainerNotFound; bool hasValue = value != kPersistentContainerNotFound;
if (hasValue) { if (hasValue) {
returnValue->SetInternal( returnValue->SetInternal(
*reinterpret_cast<internal::Object**>(FromVal(value))); *reinterpret_cast<internal::Address*>(FromVal(value)));
} }
return hasValue; return hasValue;
} }
Isolate* isolate_; Isolate* isolate_;
typename Traits::Impl impl_; typename Traits::Impl impl_;
const char* label_;
}; };
template <typename K, typename V, typename Traits>
inline void
PersistentValueMapBase<K, V, Traits>::RegisterExternallyReferencedObject(
K& key) {
assert(Contains(key));
V8::RegisterExternallyReferencedObject(
reinterpret_cast<internal::Address*>(FromVal(Traits::Get(&impl_, key))),
reinterpret_cast<internal::Isolate*>(GetIsolate()));
}
template <typename K, typename V, typename Traits> template <typename K, typename V, typename Traits>
class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> { class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
public: public:
explicit PersistentValueMap(Isolate* isolate) explicit PersistentValueMap(Isolate* isolate)
: PersistentValueMapBase<K, V, Traits>(isolate) {} : PersistentValueMapBase<K, V, Traits>(isolate) {}
PersistentValueMap(Isolate* isolate, const char* label)
: PersistentValueMapBase<K, V, Traits>(isolate, label) {}
typedef typedef
typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
@ -392,10 +396,17 @@ class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
* by the Traits class. * by the Traits class.
*/ */
Global<V> SetUnique(const K& key, Global<V>* persistent) { Global<V> SetUnique(const K& key, Global<V>* persistent) {
if (Traits::kCallbackType != kNotWeak) { if (Traits::kCallbackType == kNotWeak) {
this->AnnotateStrongRetainer(persistent);
} else {
WeakCallbackType callback_type =
Traits::kCallbackType == kWeakWithInternalFields
? WeakCallbackType::kInternalFields
: WeakCallbackType::kParameter;
Local<V> value(Local<V>::New(this->isolate(), *persistent)); Local<V> value(Local<V>::New(this->isolate(), *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>( persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
Traits::WeakCallbackParameter(this, key, value), WeakCallback); Traits::WeakCallbackParameter(this, key, value), WeakCallback,
callback_type);
} }
PersistentContainerValue old_value = PersistentContainerValue old_value =
Traits::Set(this->impl(), key, this->ClearAndLeak(persistent)); Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
@ -432,6 +443,8 @@ class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
public: public:
explicit GlobalValueMap(Isolate* isolate) explicit GlobalValueMap(Isolate* isolate)
: PersistentValueMapBase<K, V, Traits>(isolate) {} : PersistentValueMapBase<K, V, Traits>(isolate) {}
GlobalValueMap(Isolate* isolate, const char* label)
: PersistentValueMapBase<K, V, Traits>(isolate, label) {}
typedef typedef
typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
@ -459,7 +472,9 @@ class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
* by the Traits class. * by the Traits class.
*/ */
Global<V> SetUnique(const K& key, Global<V>* persistent) { Global<V> SetUnique(const K& key, Global<V>* persistent) {
if (Traits::kCallbackType != kNotWeak) { if (Traits::kCallbackType == kNotWeak) {
this->AnnotateStrongRetainer(persistent);
} else {
WeakCallbackType callback_type = WeakCallbackType callback_type =
Traits::kCallbackType == kWeakWithInternalFields Traits::kCallbackType == kWeakWithInternalFields
? WeakCallbackType::kInternalFields ? WeakCallbackType::kInternalFields
@ -638,7 +653,7 @@ class PersistentValueVector {
private: private:
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) { static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
V* v = persistent->val_; V* v = persistent->val_;
persistent->val_ = 0; persistent->val_ = nullptr;
return reinterpret_cast<PersistentContainerValue>(v); return reinterpret_cast<PersistentContainerValue>(v);
} }

View File

@ -16,6 +16,10 @@
#define V8_CANDIDATE_STRING "" #define V8_CANDIDATE_STRING ""
#endif #endif
#ifndef V8_EMBEDDER_STRING
#define V8_EMBEDDER_STRING ""
#endif
#define V8_SX(x) #x #define V8_SX(x) #x
#define V8_S(x) V8_SX(x) #define V8_S(x) V8_SX(x)
@ -23,11 +27,12 @@
#define V8_VERSION_STRING \ #define V8_VERSION_STRING \
V8_S(V8_MAJOR_VERSION) \ V8_S(V8_MAJOR_VERSION) \
"." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) "." V8_S( \ "." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) "." V8_S( \
V8_PATCH_LEVEL) V8_CANDIDATE_STRING V8_PATCH_LEVEL) V8_EMBEDDER_STRING V8_CANDIDATE_STRING
#else #else
#define V8_VERSION_STRING \ #define V8_VERSION_STRING \
V8_S(V8_MAJOR_VERSION) \ V8_S(V8_MAJOR_VERSION) \
"." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) V8_CANDIDATE_STRING "." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) \
V8_EMBEDDER_STRING V8_CANDIDATE_STRING
#endif #endif
#endif // V8_VERSION_STRING_H_ #endif // V8_VERSION_STRING_H_

View File

@ -8,10 +8,10 @@
// These macros define the version number for the current version. // These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build // NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts. // system so their names cannot be changed without changing the scripts.
#define V8_MAJOR_VERSION 6 #define V8_MAJOR_VERSION 7
#define V8_MINOR_VERSION 0 #define V8_MINOR_VERSION 5
#define V8_BUILD_NUMBER 286 #define V8_BUILD_NUMBER 288
#define V8_PATCH_LEVEL 52 #define V8_PATCH_LEVEL 22
// Use 1 for candidates and 0 otherwise. // Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.) // (Boolean macro values are not supported by all preprocessors.)

File diff suppressed because it is too large Load Diff

View File

@ -61,8 +61,10 @@
// V8_OS_CYGWIN - Cygwin // V8_OS_CYGWIN - Cygwin
// V8_OS_DRAGONFLYBSD - DragonFlyBSD // V8_OS_DRAGONFLYBSD - DragonFlyBSD
// V8_OS_FREEBSD - FreeBSD // V8_OS_FREEBSD - FreeBSD
// V8_OS_FUCHSIA - Fuchsia
// V8_OS_LINUX - Linux // V8_OS_LINUX - Linux
// V8_OS_MACOSX - Mac OS X // V8_OS_MACOSX - Mac OS X
// V8_OS_IOS - iOS
// V8_OS_NETBSD - NetBSD // V8_OS_NETBSD - NetBSD
// V8_OS_OPENBSD - OpenBSD // V8_OS_OPENBSD - OpenBSD
// V8_OS_POSIX - POSIX compatible (mostly everything except Windows) // V8_OS_POSIX - POSIX compatible (mostly everything except Windows)
@ -79,6 +81,9 @@
# define V8_OS_BSD 1 # define V8_OS_BSD 1
# define V8_OS_MACOSX 1 # define V8_OS_MACOSX 1
# define V8_OS_POSIX 1 # define V8_OS_POSIX 1
# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
# define V8_OS_IOS 1
# endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
# define V8_OS_CYGWIN 1 # define V8_OS_CYGWIN 1
# define V8_OS_POSIX 1 # define V8_OS_POSIX 1
@ -95,6 +100,9 @@
# define V8_OS_BSD 1 # define V8_OS_BSD 1
# define V8_OS_FREEBSD 1 # define V8_OS_FREEBSD 1
# define V8_OS_POSIX 1 # define V8_OS_POSIX 1
#elif defined(__Fuchsia__)
# define V8_OS_FUCHSIA 1
# define V8_OS_POSIX 1
#elif defined(__DragonFly__) #elif defined(__DragonFly__)
# define V8_OS_BSD 1 # define V8_OS_BSD 1
# define V8_OS_DRAGONFLYBSD 1 # define V8_OS_DRAGONFLYBSD 1
@ -157,23 +165,19 @@
// //
// C++11 feature detection // C++11 feature detection
// //
// V8_HAS_CXX11_ALIGNAS - alignas specifier supported
// V8_HAS_CXX11_ALIGNOF - alignof(type) operator supported
//
// Compiler-specific feature detection // Compiler-specific feature detection
// //
// V8_HAS___ALIGNOF - __alignof(type) operator supported
// V8_HAS___ALIGNOF__ - __alignof__(type) operator supported
// V8_HAS_ATTRIBUTE_ALIGNED - __attribute__((aligned(n))) supported
// V8_HAS_ATTRIBUTE_ALWAYS_INLINE - __attribute__((always_inline)) // V8_HAS_ATTRIBUTE_ALWAYS_INLINE - __attribute__((always_inline))
// supported // supported
// V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) supported // V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) supported
// V8_HAS_ATTRIBUTE_NOINLINE - __attribute__((noinline)) supported // V8_HAS_ATTRIBUTE_NOINLINE - __attribute__((noinline)) supported
// V8_HAS_ATTRIBUTE_NORETURN - __attribute__((noreturn)) supported
// V8_HAS_ATTRIBUTE_UNUSED - __attribute__((unused)) supported // V8_HAS_ATTRIBUTE_UNUSED - __attribute__((unused)) supported
// V8_HAS_ATTRIBUTE_VISIBILITY - __attribute__((visibility)) supported // V8_HAS_ATTRIBUTE_VISIBILITY - __attribute__((visibility)) supported
// V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result)) // V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result))
// supported // supported
// V8_HAS_BUILTIN_BSWAP16 - __builtin_bswap16() supported
// V8_HAS_BUILTIN_BSWAP32 - __builtin_bswap32() supported
// V8_HAS_BUILTIN_BSWAP64 - __builtin_bswap64() supported
// V8_HAS_BUILTIN_CLZ - __builtin_clz() supported // V8_HAS_BUILTIN_CLZ - __builtin_clz() supported
// V8_HAS_BUILTIN_CTZ - __builtin_ctz() supported // V8_HAS_BUILTIN_CTZ - __builtin_ctz() supported
// V8_HAS_BUILTIN_EXPECT - __builtin_expect() supported // V8_HAS_BUILTIN_EXPECT - __builtin_expect() supported
@ -182,7 +186,6 @@
// V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported // V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported
// V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_overflow() supported // V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_overflow() supported
// V8_HAS_BUILTIN_UADD_OVERFLOW - __builtin_uadd_overflow() supported // V8_HAS_BUILTIN_UADD_OVERFLOW - __builtin_uadd_overflow() supported
// V8_HAS_DECLSPEC_ALIGN - __declspec(align(n)) supported
// V8_HAS_DECLSPEC_DEPRECATED - __declspec(deprecated) supported // V8_HAS_DECLSPEC_DEPRECATED - __declspec(deprecated) supported
// V8_HAS_DECLSPEC_NOINLINE - __declspec(noinline) supported // V8_HAS_DECLSPEC_NOINLINE - __declspec(noinline) supported
// V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported // V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported
@ -201,20 +204,19 @@
# define V8_CC_GNU 1 # define V8_CC_GNU 1
#endif #endif
// Clang defines __alignof__ as alias for __alignof
# define V8_HAS___ALIGNOF 1
# define V8_HAS___ALIGNOF__ V8_HAS___ALIGNOF
# define V8_HAS_ATTRIBUTE_ALIGNED (__has_attribute(aligned))
# define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline)) # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
# define V8_HAS_ATTRIBUTE_DEPRECATED (__has_attribute(deprecated)) # define V8_HAS_ATTRIBUTE_DEPRECATED (__has_attribute(deprecated))
# define V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE \
(__has_extension(attribute_deprecated_with_message))
# define V8_HAS_ATTRIBUTE_NOINLINE (__has_attribute(noinline)) # define V8_HAS_ATTRIBUTE_NOINLINE (__has_attribute(noinline))
# define V8_HAS_ATTRIBUTE_NORETURN (__has_attribute(noreturn))
# define V8_HAS_ATTRIBUTE_UNUSED (__has_attribute(unused)) # define V8_HAS_ATTRIBUTE_UNUSED (__has_attribute(unused))
# define V8_HAS_ATTRIBUTE_VISIBILITY (__has_attribute(visibility)) # define V8_HAS_ATTRIBUTE_VISIBILITY (__has_attribute(visibility))
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \ # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
(__has_attribute(warn_unused_result)) (__has_attribute(warn_unused_result))
# define V8_HAS_BUILTIN_BSWAP16 (__has_builtin(__builtin_bswap16))
# define V8_HAS_BUILTIN_BSWAP32 (__has_builtin(__builtin_bswap32))
# define V8_HAS_BUILTIN_BSWAP64 (__has_builtin(__builtin_bswap64))
# define V8_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz)) # define V8_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz))
# define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz)) # define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz))
# define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect)) # define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect))
@ -224,7 +226,9 @@
# define V8_HAS_BUILTIN_SSUB_OVERFLOW (__has_builtin(__builtin_ssub_overflow)) # define V8_HAS_BUILTIN_SSUB_OVERFLOW (__has_builtin(__builtin_ssub_overflow))
# define V8_HAS_BUILTIN_UADD_OVERFLOW (__has_builtin(__builtin_uadd_overflow)) # define V8_HAS_BUILTIN_UADD_OVERFLOW (__has_builtin(__builtin_uadd_overflow))
# define V8_HAS_CXX11_ALIGNAS (__has_feature(cxx_alignas)) # if __cplusplus >= 201402L
# define V8_CAN_HAVE_DCHECK_IN_CONSTEXPR 1
# endif
#elif defined(__GNUC__) #elif defined(__GNUC__)
@ -240,9 +244,6 @@
# endif # endif
# define V8_CC_MINGW (V8_CC_MINGW32 || V8_CC_MINGW64) # define V8_CC_MINGW (V8_CC_MINGW32 || V8_CC_MINGW64)
# define V8_HAS___ALIGNOF__ (V8_GNUC_PREREQ(4, 3, 0))
# define V8_HAS_ATTRIBUTE_ALIGNED (V8_GNUC_PREREQ(2, 95, 0))
// always_inline is available in gcc 4.0 but not very reliable until 4.4. // always_inline is available in gcc 4.0 but not very reliable until 4.4.
// Works around "sorry, unimplemented: inlining failed" build errors with // Works around "sorry, unimplemented: inlining failed" build errors with
// older compilers. // older compilers.
@ -250,7 +251,6 @@
# define V8_HAS_ATTRIBUTE_DEPRECATED (V8_GNUC_PREREQ(3, 4, 0)) # define V8_HAS_ATTRIBUTE_DEPRECATED (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE (V8_GNUC_PREREQ(4, 5, 0)) # define V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE (V8_GNUC_PREREQ(4, 5, 0))
# define V8_HAS_ATTRIBUTE_NOINLINE (V8_GNUC_PREREQ(3, 4, 0)) # define V8_HAS_ATTRIBUTE_NOINLINE (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_ATTRIBUTE_NORETURN (V8_GNUC_PREREQ(2, 5, 0))
# define V8_HAS_ATTRIBUTE_UNUSED (V8_GNUC_PREREQ(2, 95, 0)) # define V8_HAS_ATTRIBUTE_UNUSED (V8_GNUC_PREREQ(2, 95, 0))
# define V8_HAS_ATTRIBUTE_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0)) # define V8_HAS_ATTRIBUTE_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0))
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \ # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
@ -262,17 +262,11 @@
# define V8_HAS_BUILTIN_FRAME_ADDRESS (V8_GNUC_PREREQ(2, 96, 0)) # define V8_HAS_BUILTIN_FRAME_ADDRESS (V8_GNUC_PREREQ(2, 96, 0))
# define V8_HAS_BUILTIN_POPCOUNT (V8_GNUC_PREREQ(3, 4, 0)) # define V8_HAS_BUILTIN_POPCOUNT (V8_GNUC_PREREQ(3, 4, 0))
# if __cplusplus >= 201103L
# define V8_HAS_CXX11_ALIGNAS (V8_GNUC_PREREQ(4, 8, 0))
# define V8_HAS_CXX11_ALIGNOF (V8_GNUC_PREREQ(4, 8, 0))
# endif
#endif #endif
#if defined(_MSC_VER) #if defined(_MSC_VER)
# define V8_CC_MSVC 1 # define V8_CC_MSVC 1
# define V8_HAS___ALIGNOF 1
# define V8_HAS_DECLSPEC_ALIGN 1
# define V8_HAS_DECLSPEC_DEPRECATED 1 # define V8_HAS_DECLSPEC_DEPRECATED 1
# define V8_HAS_DECLSPEC_NOINLINE 1 # define V8_HAS_DECLSPEC_NOINLINE 1
# define V8_HAS_DECLSPEC_SELECTANY 1 # define V8_HAS_DECLSPEC_SELECTANY 1
@ -311,18 +305,6 @@
#endif #endif
// A macro used to tell the compiler that a particular function never returns.
// Use like:
// V8_NORETURN void MyAbort() { abort(); }
#if V8_HAS_ATTRIBUTE_NORETURN
# define V8_NORETURN __attribute__((noreturn))
#elif V8_HAS_DECLSPEC_NORETURN
# define V8_NORETURN __declspec(noreturn)
#else
# define V8_NORETURN /* NOT SUPPORTED */
#endif
// A macro (V8_DEPRECATED) to mark classes or functions as deprecated. // A macro (V8_DEPRECATED) to mark classes or functions as deprecated.
#if defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE #if defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE
#define V8_DEPRECATED(message, declarator) \ #define V8_DEPRECATED(message, declarator) \
@ -362,67 +344,45 @@
#endif #endif
// This macro allows to specify memory alignment for structs, classes, etc.
// Use like:
// class V8_ALIGNED(16) MyClass { ... };
// V8_ALIGNED(32) int array[42];
#if V8_HAS_CXX11_ALIGNAS
# define V8_ALIGNED(n) alignas(n)
#elif V8_HAS_ATTRIBUTE_ALIGNED
# define V8_ALIGNED(n) __attribute__((aligned(n)))
#elif V8_HAS_DECLSPEC_ALIGN
# define V8_ALIGNED(n) __declspec(align(n))
#else
# define V8_ALIGNED(n) /* NOT SUPPORTED */
#endif
// This macro is similar to V8_ALIGNED(), but takes a type instead of size
// in bytes. If the compiler does not supports using the alignment of the
// |type|, it will align according to the |alignment| instead. For example,
// Visual Studio C++ cannot combine __declspec(align) and __alignof. The
// |alignment| must be a literal that is used as a kind of worst-case fallback
// alignment.
// Use like:
// struct V8_ALIGNAS(AnotherClass, 16) NewClass { ... };
// V8_ALIGNAS(double, 8) int array[100];
#if V8_HAS_CXX11_ALIGNAS
# define V8_ALIGNAS(type, alignment) alignas(type)
#elif V8_HAS___ALIGNOF__ && V8_HAS_ATTRIBUTE_ALIGNED
# define V8_ALIGNAS(type, alignment) __attribute__((aligned(__alignof__(type))))
#else
# define V8_ALIGNAS(type, alignment) V8_ALIGNED(alignment)
#endif
// This macro returns alignment in bytes (an integer power of two) required for
// any instance of the given type, which is either complete type, an array type,
// or a reference type.
// Use like:
// size_t alignment = V8_ALIGNOF(double);
#if V8_HAS_CXX11_ALIGNOF
# define V8_ALIGNOF(type) alignof(type)
#elif V8_HAS___ALIGNOF
# define V8_ALIGNOF(type) __alignof(type)
#elif V8_HAS___ALIGNOF__
# define V8_ALIGNOF(type) __alignof__(type)
#else
// Note that alignment of a type within a struct can be less than the
// alignment of the type stand-alone (because of ancient ABIs), so this
// should only be used as a last resort.
namespace v8 { template <typename T> class AlignOfHelper { char c; T t; }; }
# define V8_ALIGNOF(type) (sizeof(::v8::AlignOfHelper<type>) - sizeof(type))
#endif
// Annotate a function indicating the caller must examine the return value. // Annotate a function indicating the caller must examine the return value.
// Use like: // Use like:
// int foo() WARN_UNUSED_RESULT; // int foo() V8_WARN_UNUSED_RESULT;
#if V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT #if V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) #define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else #else
#define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */ #define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */
#endif #endif
#ifdef V8_OS_WIN
// Setup for Windows DLL export/import. When building the V8 DLL the
// BUILDING_V8_SHARED needs to be defined. When building a program which uses
// the V8 DLL USING_V8_SHARED needs to be defined. When either building the V8
// static library or building a program which uses the V8 static library neither
// BUILDING_V8_SHARED nor USING_V8_SHARED should be defined.
#ifdef BUILDING_V8_SHARED
# define V8_EXPORT __declspec(dllexport)
#elif USING_V8_SHARED
# define V8_EXPORT __declspec(dllimport)
#else
# define V8_EXPORT
#endif // BUILDING_V8_SHARED
#else // V8_OS_WIN
// Setup for Linux shared library export.
#if V8_HAS_ATTRIBUTE_VISIBILITY
# ifdef BUILDING_V8_SHARED
# define V8_EXPORT __attribute__ ((visibility("default")))
# else
# define V8_EXPORT
# endif
#else
# define V8_EXPORT
#endif
#endif // V8_OS_WIN
// clang-format on // clang-format on
#endif // V8CONFIG_H_ #endif // V8CONFIG_H_